From 99114faf8281e13492e857c935f51d3fad6f22dc Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 20 May 2014 16:50:24 +0200 Subject: http2: make connection re-use work Http2 connections would wrongly get closed after each individual request. Co-authored-by: Tatsuhiro Tsujikawa Bug: http://curl.haxx.se/bug/view.cgi?id=1374 --- lib/http.c | 11 +++++++++-- lib/http2.c | 34 +++++++++++++++++++--------------- lib/http2.h | 2 ++ 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/lib/http.c b/lib/http.c index 1bb9ffb69..7dde8212e 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1744,9 +1744,12 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) the rest of the request in the PERFORM phase. */ *done = TRUE; - switch (conn->negnpn) { + if(conn->httpversion < 20) { /* unless the connection is re-used and already + http2 */ + switch (conn->negnpn) { case NPN_HTTP2: Curl_http2_init(conn); + Curl_http2_setup(conn); Curl_http2_switched(conn); break; case NPN_HTTP1_1: @@ -1755,7 +1758,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) default: /* and as fallback */ break; + } } + else + /* prepare for a http2 request */ + Curl_http2_setup(conn); http = data->req.protop; @@ -2999,7 +3006,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, k->header = FALSE; /* no more header to parse! */ if((k->size == -1) && !k->chunk && !conn->bits.close && - (conn->httpversion >= 11) && + (conn->httpversion == 11) && !(conn->handler->protocol & CURLPROTO_RTSP) && data->set.httpreq != HTTPREQ_HEAD) { /* On HTTP 1.1, when connection is not to get closed, but no diff --git a/lib/http2.c b/lib/http2.c index 3ee99e20b..1e6e07d78 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -103,8 +103,8 @@ static CURLcode http2_disconnect(struct connectdata *conn, const struct Curl_handler Curl_handler_http2 = { "HTTP2", /* scheme */ ZERO_NULL, /* setup_connection */ - ZERO_NULL, /* do_it */ - ZERO_NULL , /* done */ + Curl_http, /* do_it */ + ZERO_NULL, /* done */ ZERO_NULL, /* do_more */ ZERO_NULL, /* connect_it */ ZERO_NULL, /* connecting */ @@ -123,8 +123,8 @@ const struct Curl_handler Curl_handler_http2 = { const struct Curl_handler Curl_handler_http2_ssl = { "HTTP2", /* scheme */ ZERO_NULL, /* setup_connection */ - ZERO_NULL, /* do_it */ - ZERO_NULL , /* done */ + Curl_http, /* do_it */ + ZERO_NULL, /* done */ ZERO_NULL, /* do_more */ ZERO_NULL, /* connect_it */ ZERO_NULL, /* connecting */ @@ -778,24 +778,15 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, return len; } -int Curl_http2_switched(struct connectdata *conn) +void Curl_http2_setup(struct connectdata *conn) { - int rv; - CURLcode rc; struct http_conn *httpc = &conn->proto.httpc; - /* we are switched! */ - /* Don't know this is needed here at this moment. Original - handler->flags is still useful. */ if(conn->handler->flags & PROTOPT_SSL) conn->handler = &Curl_handler_http2_ssl; else conn->handler = &Curl_handler_http2; - httpc->recv_underlying = (recving)conn->recv[FIRSTSOCKET]; - httpc->send_underlying = (sending)conn->send[FIRSTSOCKET]; - conn->recv[FIRSTSOCKET] = http2_recv; - conn->send[FIRSTSOCKET] = http2_send; - infof(conn->data, "We have switched to HTTP2\n"); + infof(conn->data, "Using HTTP2\n"); httpc->bodystarted = FALSE; httpc->closed = FALSE; httpc->header_recvbuf = Curl_add_buffer_init(); @@ -805,13 +796,26 @@ int Curl_http2_switched(struct connectdata *conn) httpc->upload_left = 0; httpc->upload_mem = NULL; httpc->upload_len = 0; + httpc->stream_id = -1; conn->httpversion = 20; /* Put place holder for status line */ Curl_add_buffer(httpc->header_recvbuf, "HTTP/2.0 200\r\n", 14); +} +int Curl_http2_switched(struct connectdata *conn) +{ /* TODO: May get CURLE_AGAIN */ + CURLcode rc; + struct http_conn *httpc = &conn->proto.httpc; + int rv; + + httpc->recv_underlying = (recving)conn->recv[FIRSTSOCKET]; + httpc->send_underlying = (sending)conn->send[FIRSTSOCKET]; + conn->recv[FIRSTSOCKET] = http2_recv; + conn->send[FIRSTSOCKET] = http2_send; + rv = (int) ((Curl_send*)httpc->send_underlying) (conn, FIRSTSOCKET, NGHTTP2_CLIENT_CONNECTION_PREFACE, diff --git a/lib/http2.h b/lib/http2.h index ef994b7ba..5b14f21e2 100644 --- a/lib/http2.h +++ b/lib/http2.h @@ -36,12 +36,14 @@ CURLcode Curl_http2_init(struct connectdata *conn); CURLcode Curl_http2_send_request(struct connectdata *conn); CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req, struct connectdata *conn); +void Curl_http2_setup(struct connectdata *conn); int Curl_http2_switched(struct connectdata *conn); #else /* USE_NGHTTP2 */ #define Curl_http2_init(x) #define Curl_http2_send_request(x) #define Curl_http2_request_upgrade(x,y) CURLE_OK #define Curl_http2_switched(x) +#define Curl_http2_setup(x) #endif #endif /* HEADER_CURL_HTTP2_H */ -- cgit v1.2.1