Commit 99114faf authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

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
parent 316f79ce
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -1744,9 +1744,12 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     the rest of the request in the PERFORM phase. */
  *done = TRUE;

  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:
@@ -1756,6 +1759,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
      /* 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
+19 −15
Original line number Diff line number Diff line
@@ -103,7 +103,7 @@ static CURLcode http2_disconnect(struct connectdata *conn,
const struct Curl_handler Curl_handler_http2 = {
  "HTTP2",                              /* scheme */
  ZERO_NULL,                            /* setup_connection */
  ZERO_NULL,                            /* do_it */
  Curl_http,                            /* do_it */
  ZERO_NULL,                            /* done */
  ZERO_NULL,                            /* do_more */
  ZERO_NULL,                            /* connect_it */
@@ -123,7 +123,7 @@ 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 */
  Curl_http,                            /* do_it */
  ZERO_NULL,                            /* done */
  ZERO_NULL,                            /* do_more */
  ZERO_NULL,                            /* connect_it */
@@ -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,
+2 −0
Original line number Diff line number Diff line
@@ -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 */