From 7bbac214f5be8ab87114a0e00db2ebd390e1c64b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 29 Apr 2015 17:00:53 +0200 Subject: [PATCH] http2: move the mem+len pair to the stream struct --- lib/http.c | 4 ++++ lib/http.h | 5 +++-- lib/http2.c | 55 +++++++++++++++++++++++++++++++------------------- lib/transfer.c | 1 + lib/url.c | 2 ++ 5 files changed, 44 insertions(+), 23 deletions(-) diff --git a/lib/http.c b/lib/http.c index 4b67db4b9..7aa258d40 100644 --- a/lib/http.c +++ b/lib/http.c @@ -171,6 +171,10 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn) http->error_code = NGHTTP2_NO_ERROR; http->closed = FALSE; + /* where to store incoming data for this stream and how big the buffer is */ + http->mem = conn->data->state.buffer; + http->len = BUFSIZE; + return CURLE_OK; } diff --git a/lib/http.h b/lib/http.h index 48f5c7350..50db486d2 100644 --- a/lib/http.h +++ b/lib/http.h @@ -166,6 +166,9 @@ struct HTTP { size_t datalen; /* the number of bytes left in data */ bool closed; /* TRUE on HTTP2 stream close */ uint32_t error_code; /* HTTP/2 error code */ + + char *mem; /* points to a buffer in memory to store received data */ + size_t len; /* size of the buffer 'mem' points to */ }; typedef int (*sending)(void); /* Curl_send */ @@ -177,8 +180,6 @@ struct http_conn { nghttp2_session *h2; uint8_t binsettings[H2_BINSETTINGS_LEN]; size_t binlen; /* length of the binsettings data */ - char *mem; /* points to a buffer in memory to store */ - size_t len; /* size of the buffer 'mem' points to */ sending send_underlying; /* underlying send Curl_send callback */ recving recv_underlying; /* underlying recv Curl_recv callback */ char *inbuf; /* buffer to receive data from underlying socket */ diff --git a/lib/http2.c b/lib/http2.c index 8a60c3747..ca8299fd2 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -38,6 +38,8 @@ #include "curl_memory.h" #include "memdebug.h" +#define MIN(x,y) ((x)<(y)?(x):(y)) + #if (NGHTTP2_VERSION_NUM < 0x000600) #error too old nghttp2 version, upgrade! #endif @@ -185,7 +187,6 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, void *userp) { struct connectdata *conn = (struct connectdata *)userp; - struct http_conn *c = &conn->proto.httpc; struct SessionHandle *data_s = NULL; struct HTTP *stream = NULL; int rv; @@ -264,14 +265,14 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, Curl_add_buffer(stream->header_recvbuf, "\r\n", 2); left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf; - ncopy = c->len < left ? c->len : left; + ncopy = MIN(stream->len, left); - memcpy(c->mem, stream->header_recvbuf->buffer + + memcpy(stream->mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf, ncopy); stream->nread_header_recvbuf += ncopy; - c->mem += ncopy; - c->len -= ncopy; + stream->mem += ncopy; + stream->len -= ncopy; break; case NGHTTP2_PUSH_PROMISE: rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, @@ -303,7 +304,6 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, const uint8_t *data, size_t len, void *userp) { struct connectdata *conn = (struct connectdata *)userp; - struct http_conn *c = &conn->proto.httpc; struct HTTP *stream; struct SessionHandle *data_s; size_t nread; @@ -327,13 +327,15 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, } stream = data_s->req.protop; - nread = c->len < len ? c->len : len; - memcpy(c->mem, data, nread); + nread = MIN(stream->len, len); + memcpy(stream->mem, data, nread); - c->mem += nread; - c->len -= nread; + stream->mem += nread; + stream->len -= nread; - DEBUGF(infof(conn->data, "%zu data written\n", nread)); + DEBUGF(infof(conn->data, "%zu data received for stream %x " + "(%zu left in buffer)\n", + nread, stream_id, stream->len)); if(nread < len) { stream->data = data + nread; @@ -570,7 +572,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session, (void)stream_id; (void)source; - nread = c->upload_len < length ? c->upload_len : length; + nread = MIN(c->upload_len, length); if(nread > 0) { memcpy(buf, c->upload_mem, nread); c->upload_mem += nread; @@ -594,7 +596,7 @@ static nghttp2_settings_entry settings[] = { { NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, NGHTTP2_INITIAL_WINDOW_SIZE }, }; -#define H2_BUFSIZE 4096 +#define H2_BUFSIZE (1024) static void freestreamentry(void *freethis) { @@ -761,15 +763,18 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, /* If there is body data pending for this stream to return, do that */ size_t left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf; - size_t ncopy = len < left ? len : left; + size_t ncopy = MIN(len, left); memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf, ncopy); stream->nread_header_recvbuf += ncopy; + + infof(conn->data, "http2_recv: Got %d bytes from header_recvbuf\n", + (int)ncopy); return ncopy; } if(stream->data) { - nread = len < stream->datalen ? len : stream->datalen; + nread = MIN(len, stream->datalen); memcpy(mem, stream->data, nread); stream->data += nread; @@ -780,14 +785,17 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, stream->data = NULL; stream->datalen = 0; } + infof(conn->data, "http2_recv: Got %d bytes from stream->data\n", + (int)nread); return nread; } - conn->proto.httpc.mem = mem; - conn->proto.httpc.len = len; + /* remember where to store incoming data for this stream and how big the + buffer is */ + stream->mem = mem; + stream->len = len; - infof(conn->data, "http2_recv: %d bytes buffer\n", - conn->proto.httpc.len); + infof(conn->data, "http2_recv: %d bytes buffer\n", stream->len); nread = ((Curl_recv*)httpc->recv_underlying)(conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, @@ -828,8 +836,11 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, *err = CURLE_SEND_ERROR; return 0; } - if(len != httpc->len) { - return len - conn->proto.httpc.len; + if(len != stream->len) { + infof(conn->data, "http2_recv: returns %d for stream %x (%zu/%zu)\n", + len - stream->len, stream->stream_id, + len, stream->len); + return len - stream->len; } /* If stream is closed, return 0 to signal the http routine to close the connection */ @@ -844,9 +855,11 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, *err = CURLE_HTTP2; return -1; } + DEBUGF(infof(conn->data, "http2_recv returns 0\n")); return 0; } *err = CURLE_AGAIN; + DEBUGF(infof(conn->data, "http2_recv returns -1, AGAIN\n")); return -1; } diff --git a/lib/transfer.c b/lib/transfer.c index 2d7b13785..ee7c37216 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -432,6 +432,7 @@ static CURLcode readwrite_data(struct SessionHandle *data, else { /* read nothing but since we wanted nothing we consider this an OK situation to proceed from */ + DEBUGF(infof(data, "readwrite_data: we're done!\n")); nread = 0; } diff --git a/lib/url.c b/lib/url.c index d69139811..49b55d89d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5945,6 +5945,8 @@ CURLcode Curl_done(struct connectdata **connp, conn = *connp; data = conn->data; + DEBUGF(infof(data, "Curl_done\n")); + if(conn->bits.done) /* Stop if Curl_done() has already been called */ return CURLE_OK;