diff options
| author | Daniel Stenberg <daniel@haxx.se> | 2015-04-27 13:54:47 +0200 | 
|---|---|---|
| committer | Daniel Stenberg <daniel@haxx.se> | 2015-05-18 08:54:54 +0200 | 
| commit | d6440d73667e11fec607d7560fca2cdde0b171a8 (patch) | |
| tree | 547367b3668a6144012303e5ae26ec5d19438309 | |
| parent | f8586240522fe2405759ad6cb57eb2d4b142907c (diff) | |
http2: move stream_id to the HTTP struct (per-stream)
| -rw-r--r-- | lib/http.h | 4 | ||||
| -rw-r--r-- | lib/http2.c | 33 | 
2 files changed, 24 insertions, 13 deletions
| diff --git a/lib/http.h b/lib/http.h index f7d64e8c4..fb924c609 100644 --- a/lib/http.h +++ b/lib/http.h @@ -152,6 +152,9 @@ struct HTTP {    void *send_buffer; /* used if the request couldn't be sent in one chunk,                          points to an allocated send_buffer struct */ + +  /* for HTTP/2 we store stream-local data here */ +  int32_t stream_id; /* stream we are interested in */  };  typedef int (*sending)(void); /* Curl_send */ @@ -175,7 +178,6 @@ struct http_conn {                                         response headers into it. */    size_t nread_header_recvbuf; /* number of bytes in header_recvbuf                                    fed into upper layer */ -  int32_t stream_id; /* stream we are interested in */    const uint8_t *data; /* pointer to data chunk, received in                            on_data_chunk */    size_t datalen; /* the number of bytes left in data */ diff --git a/lib/http2.c b/lib/http2.c index d01b52efd..4bc8fc57c 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -291,6 +291,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,  {    struct connectdata *conn = (struct connectdata *)userp;    struct http_conn *c = &conn->proto.httpc; +  struct HTTP *stream = conn->data->req.protop;    size_t nread;    (void)session;    (void)flags; @@ -298,7 +299,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,    DEBUGF(infof(conn->data, "on_data_chunk_recv() "                 "len = %u, stream = %x\n", len, stream_id)); -  if(stream_id != c->stream_id) { +  if(stream_id != stream->stream_id) {      return 0;    } @@ -355,12 +356,13 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,  {    struct connectdata *conn = (struct connectdata *)userp;    struct http_conn *c = &conn->proto.httpc; +  struct HTTP *stream = conn->data->req.protop;    (void)session;    (void)stream_id;    DEBUGF(infof(conn->data, "on_stream_close() was called, error_code = %d\n",                 error_code)); -  if(stream_id != c->stream_id) { +  if(stream_id != stream->stream_id) {      return 0;    } @@ -418,6 +420,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,  {    struct connectdata *conn = (struct connectdata *)userp;    struct http_conn *c = &conn->proto.httpc; +  struct HTTP *stream = conn->data->req.protop;    int rv;    int goodname;    int goodheader; @@ -431,7 +434,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,      return 0;    } -  if(frame->hd.stream_id != c->stream_id) { +  if(frame->hd.stream_id != stream->stream_id) {      return 0;    } @@ -680,6 +683,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,    ssize_t rv;    ssize_t nread;    struct http_conn *httpc = &conn->proto.httpc; +  struct HTTP *stream = conn->data->req.protop;    (void)sockindex; /* we always do HTTP2 on sockindex 0 */ @@ -778,7 +782,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,      if(httpc->error_code != NGHTTP2_NO_ERROR) {        failf(conn->data,              "HTTP/2 stream = %x was not closed cleanly: error_code = %d", -            httpc->stream_id, httpc->error_code); +            stream->stream_id, httpc->error_code);        *err = CURLE_HTTP2;        return -1;      } @@ -803,6 +807,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,     */    int rv;    struct http_conn *httpc = &conn->proto.httpc; +  struct HTTP *stream = conn->data->req.protop;    nghttp2_nv *nva;    size_t nheader;    size_t i; @@ -816,12 +821,12 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,    DEBUGF(infof(conn->data, "http2_send len=%zu\n", len)); -  if(httpc->stream_id != -1) { +  if(stream->stream_id != -1) {      /* If stream_id != -1, we have dispatched request HEADERS, and now         are going to send or sending request body in DATA frame */      httpc->upload_mem = mem;      httpc->upload_len = len; -    nghttp2_session_resume_data(httpc->h2, httpc->stream_id); +    nghttp2_session_resume_data(httpc->h2, stream->stream_id);      rv = nghttp2_session_send(httpc->h2);      if(nghttp2_is_fatal(rv)) {        *err = CURLE_SEND_ERROR; @@ -945,7 +950,8 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,      return -1;    } -  httpc->stream_id = stream_id; +  infof(conn->data, "Using Stream ID: %x\n", stream_id); +  stream->stream_id = stream_id;    rv = nghttp2_session_send(httpc->h2); @@ -954,7 +960,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,      return -1;    } -  if(httpc->stream_id != -1) { +  if(stream->stream_id != -1) {      /* If whole HEADERS frame was sent off to the underlying socket,         the nghttp2 library calls data_source_read_callback. But only         it found that no data available, so it deferred the DATA @@ -963,7 +969,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,         writable socket check is performed. To workaround this, we         issue nghttp2_session_resume_data() here to bring back DATA         transmission from deferred state. */ -    nghttp2_session_resume_data(httpc->h2, httpc->stream_id); +    nghttp2_session_resume_data(httpc->h2, stream->stream_id);    }    return len; @@ -973,6 +979,9 @@ CURLcode Curl_http2_setup(struct connectdata *conn)  {    CURLcode result;    struct http_conn *httpc = &conn->proto.httpc; +  struct HTTP *stream = conn->data->req.protop; + +  stream->stream_id = -1;    if((conn->handler == &Curl_handler_http2_ssl) ||       (conn->handler == &Curl_handler_http2)) @@ -998,7 +1007,6 @@ CURLcode Curl_http2_setup(struct connectdata *conn)    httpc->upload_left = 0;    httpc->upload_mem = NULL;    httpc->upload_len = 0; -  httpc->stream_id = -1;    httpc->status_code = -1;    conn->httpversion = 20; @@ -1014,6 +1022,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,    struct http_conn *httpc = &conn->proto.httpc;    int rv;    struct SessionHandle *data = conn->data; +  struct HTTP *stream = conn->data->req.protop;    result = Curl_http2_setup(conn);    if(result) @@ -1040,7 +1049,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,    if(conn->data->req.upgr101 == UPGR101_RECEIVED) {      /* stream 1 is opened implicitly on upgrade */ -    httpc->stream_id = 1; +    stream->stream_id = 1;      /* queue SETTINGS frame (again) */      rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings,                                   httpc->binlen, NULL); @@ -1052,7 +1061,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,    }    else {      /* stream ID is unknown at this point */ -    httpc->stream_id = -1; +    stream->stream_id = -1;      rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, NULL, 0);      if(rv != 0) {        failf(data, "nghttp2_submit_settings() failed: %s(%d)", | 
