Skip to content
Snippets Groups Projects
http2.c 33.2 KiB
Newer Older
  • Learn to ignore specific revisions
  •   if((conn->handler == &Curl_handler_http2_ssl) ||
         (conn->handler == &Curl_handler_http2))
        return CURLE_OK; /* already done */
    
    
      if(conn->handler->flags & PROTOPT_SSL)
        conn->handler = &Curl_handler_http2_ssl;
      else
        conn->handler = &Curl_handler_http2;
    
    
      result = Curl_http2_init(conn);
      if(result)
        return result;
    
    
      infof(conn->data, "Using HTTP2, server supports multi-use\n");
    
      httpc->bodystarted = FALSE;
    
      httpc->error_code = NGHTTP2_NO_ERROR;
    
      httpc->header_recvbuf = Curl_add_buffer_init();
      httpc->nread_header_recvbuf = 0;
    
      httpc->data = NULL;
      httpc->datalen = 0;
    
      httpc->upload_left = 0;
      httpc->upload_mem = NULL;
      httpc->upload_len = 0;
    
      httpc->status_code = -1;
    
      conn->httpversion = 20;
    
      conn->bundle->server_supports_pipelining = TRUE;
    
    CURLcode Curl_http2_switched(struct connectdata *conn,
                                 const char *mem, size_t nread)
    
      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)
        return result;
    
    
      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,
         NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN,
    
        /* TODO: This may get CURLE_AGAIN */
    
    
      if(rv != 24) {
        failf(data, "Only sent partial HTTP2 packet");
        return CURLE_SEND_ERROR;
      }
    
    
      if(conn->data->req.upgr101 == UPGR101_RECEIVED) {
    
        /* stream 1 is opened implicitly on upgrade */
    
        /* queue SETTINGS frame (again) */
        rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings,
                                     httpc->binlen, NULL);
        if(rv != 0) {
    
          failf(data, "nghttp2_session_upgrade() failed: %s(%d)",
    
          return CURLE_HTTP2;
    
        /* stream ID is unknown at this point */
    
        rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, NULL, 0);
        if(rv != 0) {
    
          failf(data, "nghttp2_submit_settings() failed: %s(%d)",
    
          return CURLE_HTTP2;
    
    
      rv = (int)nghttp2_session_mem_recv(httpc->h2, (const uint8_t*)mem, nread);
    
      if(rv != (int)nread) {
        failf(data, "nghttp2_session_mem_recv() failed: %s(%d)",
              nghttp2_strerror(rv), rv);
        return CURLE_HTTP2;
      }
    
    
      /* Try to send some frames since we may read SETTINGS already. */
      rv = nghttp2_session_send(httpc->h2);
    
      if(rv != 0) {
        failf(data, "nghttp2_session_send() failed: %s(%d)",
              nghttp2_strerror(rv), rv);
        return CURLE_HTTP2;
      }
    
    
      return CURLE_OK;