httpclient: read_body should return 0 at EOF When users call `git_http_client_read_body`, it should return 0 at the end of a message. When the `on_message_complete` callback is called, this will set `client->state` to `DONE`. In our read loop, we look for this condition and exit. Without this, when there is no data left except the end of message chunk (`0\r\n`) in the http stream, we would block by reading the three bytes off the stream but not making progress in any `on_body` callbacks. Listening to the `on_message_complete` callback allows us to stop trying to read from the socket when we've read the end of message chunk.
diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c
index bde67ca..af90129 100644
--- a/src/transports/httpclient.c
+++ b/src/transports/httpclient.c
@@ -1419,15 +1419,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);