Skip to content

Commit 6b20883

Browse files
committed
httpclient: handle chunked responses
Detect responses that are sent with Transfer-Encoding: chunked, and record that information so that we can consume the entire message body.
1 parent 6a09567 commit 6b20883

File tree

2 files changed

+15
-7
lines changed

2 files changed

+15
-7
lines changed

src/transports/httpclient.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ static int on_header_complete(http_parser *parser)
163163
}
164164

165165
response->content_length = (size_t)len;
166+
} else if (!strcasecmp("Transfer-Encoding", name->ptr) &&
167+
!strcasecmp("chunked", value->ptr)) {
168+
ctx->response->chunked = 1;
166169
} else if (!strcasecmp("Proxy-Authenticate", git_buf_cstr(name))) {
167170
char *dup = git__strndup(value->ptr, value->size);
168171
GIT_ERROR_CHECK_ALLOC(dup);
@@ -351,7 +354,11 @@ static int on_headers_complete(http_parser *parser)
351354
/* Stop parsing. */
352355
http_parser_pause(parser, 1);
353356

354-
ctx->client->state = READING_BODY;
357+
if (ctx->response->content_type || ctx->response->chunked)
358+
ctx->client->state = READING_BODY;
359+
else
360+
ctx->client->state = DONE;
361+
355362
return 0;
356363
}
357364

@@ -1003,11 +1010,11 @@ GIT_INLINE(int) client_read_and_parse(git_http_client *client)
10031010
/*
10041011
* See if we've consumed the entire response body. If the client was
10051012
* reading the body but did not consume it entirely, it's possible that
1006-
* they knew that the stream had finished (in a git response, seeing a final
1007-
* flush) and stopped reading. But if the response was chunked, we may have
1008-
* not consumed the final chunk marker. Consume it to ensure that we don't
1009-
* have it waiting in our socket. If there's more than just a chunk marker,
1010-
* close the connection.
1013+
* they knew that the stream had finished (in a git response, seeing a
1014+
* final flush) and stopped reading. But if the response was chunked,
1015+
* we may have not consumed the final chunk marker. Consume it to
1016+
* ensure that we don't have it waiting in our socket. If there's
1017+
* more than just a chunk marker, close the connection.
10111018
*/
10121019
static void complete_response_body(git_http_client *client)
10131020
{

src/transports/httpclient.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ typedef struct {
5353
unsigned proxy_auth_schemetypes; /**< Schemes requested by proxy */
5454
unsigned proxy_auth_credtypes; /**< Supported cred types for proxy */
5555

56-
unsigned resend_credentials : 1; /**< Resend with authentication */
56+
unsigned chunked : 1, /**< Response body is chunked */
57+
resend_credentials : 1; /**< Resend with authentication */
5758
} git_http_response;
5859

5960
typedef struct {

0 commit comments

Comments
 (0)