diff options
| -rw-r--r-- | lib/http2.c | 36 | 
1 files changed, 33 insertions, 3 deletions
diff --git a/lib/http2.c b/lib/http2.c index a56535471..fa47d0ece 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -1248,6 +1248,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,    CURLcode result;    struct http_conn *httpc = &conn->proto.httpc;    int rv; +  ssize_t nproc;    struct SessionHandle *data = conn->data;    struct HTTP *stream = conn->data->req.protop; @@ -1290,14 +1291,43 @@ CURLcode Curl_http2_switched(struct connectdata *conn,      }    } -  rv = (int)nghttp2_session_mem_recv(httpc->h2, (const uint8_t*)mem, nread); +  /* we are going to copy mem to httpc->inbuf.  This is required since +     mem is part of buffer pointed by stream->mem, and callbacks +     called by nghttp2_session_mem_recv() will write stream specific +     data into stream->mem, overwriting data already there. */ +  if(H2_BUFSIZE < nread) { +    failf(data, "connection buffer size is too small to store data following " +                "HTTP Upgrade response header: buflen=%zu, datalen=%zu", +          H2_BUFSIZE, nread); +    return CURLE_HTTP2; +  } + +  infof(conn->data, "Copying HTTP/2 data in stream buffer to connection buffer" +                    " after upgrade: len=%zu\n", +        nread); -  if(rv != (int)nread) { +  memcpy(httpc->inbuf, mem, nread); +  httpc->inbuflen = nread; + +  nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf, +                                   httpc->inbuflen); + +  if(nghttp2_is_fatal((int)nproc)) {      failf(data, "nghttp2_session_mem_recv() failed: %s(%d)", -          nghttp2_strerror(rv), rv); +          nghttp2_strerror((int)nproc), (int)nproc);      return CURLE_HTTP2;    } +  DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc)); + +  if((ssize_t)nread == nproc) { +    httpc->inbuflen = 0; +    httpc->nread_inbuf = 0; +  } +  else { +    httpc->nread_inbuf += nproc; +  } +    /* Try to send some frames since we may read SETTINGS already. */    rv = nghttp2_session_send(httpc->h2);  | 
