summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2019-12-18 21:55:28 +1100
committerEdward Thomson <ethomson@edwardthomson.com>2020-01-24 10:16:36 -0600
commit6b2088363f6e6b4fea24939286eb108cfc999c77 (patch)
tree589a2bd276276d290d9358505d2e46b40a6ef9f9
parent6a095679c83922d5b7e72a06882fe99de3bd4db6 (diff)
downloadlibgit2-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.c19
-rw-r--r--src/transports/httpclient.h3
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 {