Commit 6b208836 by Edward Thomson

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.
parent 6a095679
...@@ -163,6 +163,9 @@ static int on_header_complete(http_parser *parser) ...@@ -163,6 +163,9 @@ static int on_header_complete(http_parser *parser)
} }
response->content_length = (size_t)len; response->content_length = (size_t)len;
} else if (!strcasecmp("Transfer-Encoding", name->ptr) &&
!strcasecmp("chunked", value->ptr)) {
ctx->response->chunked = 1;
} else if (!strcasecmp("Proxy-Authenticate", git_buf_cstr(name))) { } else if (!strcasecmp("Proxy-Authenticate", git_buf_cstr(name))) {
char *dup = git__strndup(value->ptr, value->size); char *dup = git__strndup(value->ptr, value->size);
GIT_ERROR_CHECK_ALLOC(dup); GIT_ERROR_CHECK_ALLOC(dup);
...@@ -351,7 +354,11 @@ static int on_headers_complete(http_parser *parser) ...@@ -351,7 +354,11 @@ static int on_headers_complete(http_parser *parser)
/* Stop parsing. */ /* Stop parsing. */
http_parser_pause(parser, 1); http_parser_pause(parser, 1);
if (ctx->response->content_type || ctx->response->chunked)
ctx->client->state = READING_BODY; ctx->client->state = READING_BODY;
else
ctx->client->state = DONE;
return 0; return 0;
} }
...@@ -1003,11 +1010,11 @@ GIT_INLINE(int) client_read_and_parse(git_http_client *client) ...@@ -1003,11 +1010,11 @@ GIT_INLINE(int) client_read_and_parse(git_http_client *client)
/* /*
* See if we've consumed the entire response body. If the client was * See if we've consumed the entire response body. If the client was
* reading the body but did not consume it entirely, it's possible that * reading the body but did not consume it entirely, it's possible that
* they knew that the stream had finished (in a git response, seeing a final * they knew that the stream had finished (in a git response, seeing a
* flush) and stopped reading. But if the response was chunked, we may have * final flush) and stopped reading. But if the response was chunked,
* not consumed the final chunk marker. Consume it to ensure that we don't * we may have not consumed the final chunk marker. Consume it to
* have it waiting in our socket. If there's more than just a chunk marker, * ensure that we don't have it waiting in our socket. If there's
* close the connection. * more than just a chunk marker, close the connection.
*/ */
static void complete_response_body(git_http_client *client) static void complete_response_body(git_http_client *client)
{ {
......
...@@ -53,7 +53,8 @@ typedef struct { ...@@ -53,7 +53,8 @@ typedef struct {
unsigned proxy_auth_schemetypes; /**< Schemes requested by proxy */ unsigned proxy_auth_schemetypes; /**< Schemes requested by proxy */
unsigned proxy_auth_credtypes; /**< Supported cred types for proxy */ unsigned proxy_auth_credtypes; /**< Supported cred types for proxy */
unsigned resend_credentials : 1; /**< Resend with authentication */ unsigned chunked : 1, /**< Response body is chunked */
resend_credentials : 1; /**< Resend with authentication */
} git_http_response; } git_http_response;
typedef struct { typedef struct {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment