Thanks, Peff, for noticing this. It's because the client sometimes sends
"0000" as a single request (that is, it flushes, and then before it
sends any data, it flushes again). And post_rpc() assumes that it can
always read something - which is usually correct, but not in this case;
we read in stateless_connect() first, and if we read "0000", we need to
tell post_rpc() to not read at all.

This is a fixup on the tip of jt/http-auth-proto-v2-fix that fixes that.

As for why the client sends a lone "0000", I'm not sure, but that's
outside the scope of this patch set, I think.

Signed-off-by: Jonathan Tan <jonathanta...@google.com>
---
 remote-curl.c | 32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/remote-curl.c b/remote-curl.c
index 2394a00650..6c0207f4f9 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -747,7 +747,11 @@ static curl_off_t xcurl_off_t(size_t len)
        return (curl_off_t)size;
 }
 
-static int post_rpc(struct rpc_state *rpc)
+/*
+ * If flush_received is true, do not attempt to read any more; just use what's
+ * in rpc->buf.
+ */
+static int post_rpc(struct rpc_state *rpc, int flush_received)
 {
        struct active_request_slot *slot;
        struct curl_slist *headers = http_copy_default_headers();
@@ -762,17 +766,19 @@ static int post_rpc(struct rpc_state *rpc)
         * allocated buffer space we can use HTTP/1.0 and avoid the
         * chunked encoding mess.
         */
-       while (1) {
-               size_t n;
-               enum packet_read_status status;
-
-               if (!rpc_read_from_out(rpc, 0, &n, &status)) {
-                       large_request = 1;
-                       use_gzip = 0;
-                       break;
+       if (!flush_received) {
+               while (1) {
+                       size_t n;
+                       enum packet_read_status status;
+
+                       if (!rpc_read_from_out(rpc, 0, &n, &status)) {
+                               large_request = 1;
+                               use_gzip = 0;
+                               break;
+                       }
+                       if (status == PACKET_READ_FLUSH)
+                               break;
                }
-               if (status == PACKET_READ_FLUSH)
-                       break;
        }
 
        if (large_request) {
@@ -952,7 +958,7 @@ static int rpc_service(struct rpc_state *rpc, struct 
discovery *heads,
                        break;
                rpc->pos = 0;
                rpc->len = n;
-               err |= post_rpc(rpc);
+               err |= post_rpc(rpc, 0);
        }
 
        close(client.in);
@@ -1308,7 +1314,7 @@ static int stateless_connect(const char *service_name)
                        BUG("The entire rpc->buf should be larger than 
LARGE_PACKET_MAX");
                if (status == PACKET_READ_EOF)
                        break;
-               if (post_rpc(&rpc))
+               if (post_rpc(&rpc, status == PACKET_READ_FLUSH))
                        /* We would have an err here */
                        break;
                /* Reset the buffer for next request */
-- 
2.19.0.271.gfe8321ec05.dirty

Reply via email to