diff options
| -rw-r--r-- | src/transports/httpclient.c | 20 | ||||
| -rw-r--r-- | tests/online/clone.c | 8 |
2 files changed, 24 insertions, 4 deletions
diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index bde67ca9f..010baa604 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -1038,6 +1038,7 @@ on_error: GIT_INLINE(int) client_read(git_http_client *client) { + http_parser_context *parser_context = client->parser.data; git_stream *stream; char *buf = client->read_buf.ptr + client->read_buf.size; size_t max_len; @@ -1054,6 +1055,9 @@ GIT_INLINE(int) client_read(git_http_client *client) max_len = client->read_buf.asize - client->read_buf.size; max_len = min(max_len, INT_MAX); + if (parser_context->output_size) + max_len = min(max_len, parser_context->output_size); + if (max_len == 0) { git_error_set(GIT_ERROR_HTTP, "no room in output buffer"); return -1; @@ -1191,7 +1195,7 @@ static void complete_response_body(git_http_client *client) /* If we're not keeping alive, don't bother. */ if (!client->keepalive) { client->connected = 0; - return; + goto done; } parser_context.client = client; @@ -1205,6 +1209,9 @@ static void complete_response_body(git_http_client *client) git_error_clear(); client->connected = 0; } + +done: + git_buf_clear(&client->read_buf); } int git_http_client_send_request( @@ -1419,15 +1426,20 @@ int git_http_client_read_body( client->parser.data = &parser_context; /* - * Clients expect to get a non-zero amount of data from us. - * With a sufficiently small buffer, one might only read a chunk - * length. Loop until we actually have data to return. + * Clients expect to get a non-zero amount of data from us, + * so we either block until we have data to return, until we + * hit EOF or there's an error. Do this in a loop, since we + * may end up reading only some stream metadata (like chunk + * information). */ while (!parser_context.output_written) { error = client_read_and_parse(client); if (error <= 0) goto done; + + if (client->state == DONE) + break; } assert(parser_context.output_written <= INT_MAX); diff --git a/tests/online/clone.c b/tests/online/clone.c index 034d0c2e8..9107956bd 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -11,6 +11,7 @@ #define BB_REPO_URL "https://libgit3@bitbucket.org/libgit2/testgitrepository.git" #define BB_REPO_URL_WITH_PASS "https://libgit3:libgit3@bitbucket.org/libgit2/testgitrepository.git" #define BB_REPO_URL_WITH_WRONG_PASS "https://libgit3:wrong@bitbucket.org/libgit2/testgitrepository.git" +#define GOOGLESOURCE_REPO_URL "https://chromium.googlesource.com/external/github.com/sergi/go-diff" #define SSH_REPO_URL "ssh://github.com/libgit2/TestGitRepository" @@ -463,6 +464,13 @@ void test_online_clone__bitbucket_falls_back_to_specified_creds(void) cl_fixture_cleanup("./foo"); } +void test_online_clone__googlesource(void) +{ + cl_git_pass(git_clone(&g_repo, GOOGLESOURCE_REPO_URL, "./foo", &g_options)); + git_repository_free(g_repo); g_repo = NULL; + cl_fixture_cleanup("./foo"); +} + static int cancel_at_half(const git_indexer_progress *stats, void *payload) { GIT_UNUSED(payload); |
