diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2019-12-18 21:55:28 +1100 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2020-01-24 10:16:36 -0600 |
commit | 6b2088363f6e6b4fea24939286eb108cfc999c77 (patch) | |
tree | 589a2bd276276d290d9358505d2e46b40a6ef9f9 | |
parent | 6a095679c83922d5b7e72a06882fe99de3bd4db6 (diff) | |
download | libgit2-6b2088363f6e6b4fea24939286eb108cfc999c77.tar.gz |
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.
-rw-r--r-- | src/transports/httpclient.c | 19 | ||||
-rw-r--r-- | src/transports/httpclient.h | 3 |
2 files changed, 15 insertions, 7 deletions
diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index 54c4fc51e..cfbe6c675 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -163,6 +163,9 @@ static int on_header_complete(http_parser *parser) } 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))) { char *dup = git__strndup(value->ptr, value->size); GIT_ERROR_CHECK_ALLOC(dup); @@ -351,7 +354,11 @@ static int on_headers_complete(http_parser *parser) /* Stop parsing. */ http_parser_pause(parser, 1); - ctx->client->state = READING_BODY; + if (ctx->response->content_type || ctx->response->chunked) + ctx->client->state = READING_BODY; + else + ctx->client->state = DONE; + return 0; } @@ -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 * 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 - * flush) and stopped reading. But if the response was chunked, we may have - * not consumed the final chunk marker. Consume it to ensure that we don't - * have it waiting in our socket. If there's more than just a chunk marker, - * close the connection. + * they knew that the stream had finished (in a git response, seeing a + * final flush) and stopped reading. But if the response was chunked, + * we may have not consumed the final chunk marker. Consume it to + * ensure that we don't have it waiting in our socket. If there's + * more than just a chunk marker, close the connection. */ static void complete_response_body(git_http_client *client) { diff --git a/src/transports/httpclient.h b/src/transports/httpclient.h index 5f3c2caf8..e22ab4e1c 100644 --- a/src/transports/httpclient.h +++ b/src/transports/httpclient.h @@ -53,7 +53,8 @@ typedef struct { unsigned proxy_auth_schemetypes; /**< Schemes requested by 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; typedef struct { |