summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2014-05-20 16:50:24 +0200
committerDaniel Stenberg <daniel@haxx.se>2014-05-20 16:50:24 +0200
commit99114faf8281e13492e857c935f51d3fad6f22dc (patch)
tree043482db2034e88a139b35e8bd6963dfab432e14
parent316f79cef2318baf65dc55dec9b1617684fd78dd (diff)
downloadcurl-99114faf8281e13492e857c935f51d3fad6f22dc.tar.gz
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
-rw-r--r--lib/http.c11
-rw-r--r--lib/http2.c34
-rw-r--r--lib/http2.h2
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 */