Commit 414dbe9633ace4991a32eb34e092449d6bbaa18b

Vicent Marti 2014-08-18T12:26:18

Merge pull request #2525 from libgit2/cmn/http-recv-buffer http: make sure we can consume the data we request

diff --git a/src/transports/http.c b/src/transports/http.c
index 5c5e5d3..f9df53b 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -607,7 +607,23 @@ replay:
 	}
 
 	while (!*bytes_read && !t->parse_finished) {
-		t->parse_buffer.offset = 0;
+		size_t data_offset;
+
+		/*
+		 * Make the parse_buffer think it's as full of data as
+		 * the buffer, so it won't try to recv more data than
+		 * we can put into it.
+		 *
+		 * data_offset is the actual data offset from which we
+		 * should tell the parser to start reading.
+		 */
+		if (buf_size >= t->parse_buffer.len) {
+			t->parse_buffer.offset = 0;
+		} else {
+			t->parse_buffer.offset = t->parse_buffer.len - buf_size;
+		}
+
+		data_offset = t->parse_buffer.offset;
 
 		if (gitno_recv(&t->parse_buffer) < 0)
 			return -1;
@@ -628,8 +644,8 @@ replay:
 
 		bytes_parsed = http_parser_execute(&t->parser,
 			&t->settings,
-			t->parse_buffer.data,
-			t->parse_buffer.offset);
+			t->parse_buffer.data + data_offset,
+			t->parse_buffer.offset - data_offset);
 
 		t->parser.data = NULL;
 
@@ -647,7 +663,7 @@ replay:
 		if (t->parse_error < 0)
 			return -1;
 
-		if (bytes_parsed != t->parse_buffer.offset) {
+		if (bytes_parsed != t->parse_buffer.offset - data_offset) {
 			giterr_set(GITERR_NET,
 				"HTTP parser error: %s",
 				http_errno_description((enum http_errno)t->parser.http_errno));