Exemplo n.º 1
0
static CURLcode http2_disconnect(struct connectdata *conn,
                                 bool dead_connection)
{
  struct HTTP *http = conn->data->req.protop;
  struct http_conn *c = &conn->proto.httpc;
  (void)dead_connection;

  DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));

  nghttp2_session_del(c->h2);
  Curl_safefree(c->inbuf);

  if(http) {
    Curl_add_buffer_free(http->header_recvbuf);
    http->header_recvbuf = NULL; /* clear the pointer */
    for(; http->push_headers_used > 0; --http->push_headers_used) {
      free(http->push_headers[http->push_headers_used - 1]);
    }
    free(http->push_headers);
    http->push_headers = NULL;
  }

  DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));

  return CURLE_OK;
}
Exemplo n.º 2
0
void h2_session_destroy(h2_session *session)
{
    AP_DEBUG_ASSERT(session);
    if (session->mplx) {
        h2_mplx_release_and_join(session->mplx, session->iowait);
        session->mplx = NULL;
    }
    if (session->streams) {
        if (h2_stream_set_size(session->streams)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c,
                          "h2_session(%ld): destroy, %d streams open",
                          session->id, (int)h2_stream_set_size(session->streams));
        }
        h2_stream_set_destroy(session->streams);
        session->streams = NULL;
    }
    if (session->ngh2) {
        nghttp2_session_del(session->ngh2);
        session->ngh2 = NULL;
    }
    h2_conn_io_destroy(&session->io);
    
    if (session->iowait) {
        apr_thread_cond_destroy(session->iowait);
        session->iowait = NULL;
    }
    
    if (session->pool) {
        apr_pool_destroy(session->pool);
    }
}
Exemplo n.º 3
0
static
void cleanup_session(h2session *h2sess)
{
    session *sess = CONTAINER(h2sess, session, S);
    nghttp2_session_del(sess->S.h2sess);
    event_free(sess->pingtimer);
    bufferevent_free(sess->S.bev);
    free(sess);
}
Exemplo n.º 4
0
static CURLcode http2_disconnect(struct connectdata *conn,
                                 bool dead_connection)
{
  struct http_conn *c = &conn->proto.httpc;
  (void)dead_connection;

  DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));

  nghttp2_session_del(c->h2);
  Curl_safefree(c->inbuf);
  Curl_hash_destroy(&c->streamsh);

  DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));

  return CURLE_OK;
}
Exemplo n.º 5
0
static void delete_http2_session_data(http2_session_data *session_data) {
  http2_stream_data *stream_data;
  SSL *ssl = bufferevent_openssl_get_ssl(session_data->bev);
  fprintf(stderr, "%s disconnected\n", session_data->client_addr);
  if (ssl) {
    SSL_shutdown(ssl);
  }
  bufferevent_free(session_data->bev);
  nghttp2_session_del(session_data->session);
  for (stream_data = session_data->root.next; stream_data;) {
    http2_stream_data *next = stream_data->next;
    delete_http2_stream_data(stream_data);
    stream_data = next;
  }
  free(session_data->client_addr);
  free(session_data);
}
Exemplo n.º 6
0
static void delete_http2_session_data(http2_session_data *session_data) {
  SSL *ssl = bufferevent_openssl_get_ssl(session_data->bev);

  if (ssl) {
    SSL_shutdown(ssl);
  }
  bufferevent_free(session_data->bev);
  session_data->bev = NULL;
  evdns_base_free(session_data->dnsbase, 1);
  session_data->dnsbase = NULL;
  nghttp2_session_del(session_data->session);
  session_data->session = NULL;
  if (session_data->stream_data) {
    delete_http2_stream_data(session_data->stream_data);
    session_data->stream_data = NULL;
  }
  free(session_data);
}
Exemplo n.º 7
0
Arquivo: http2.c Projeto: RexSi/curl
static CURLcode http2_disconnect(struct connectdata *conn,
                                 bool dead_connection)
{
  struct http_conn *httpc = &conn->proto.httpc;
  (void)dead_connection;

  infof(conn->data, "HTTP/2 DISCONNECT starts now\n");

  nghttp2_session_del(httpc->h2);

  Curl_safefree(httpc->header_recvbuf->buffer);
  Curl_safefree(httpc->header_recvbuf);

  Curl_safefree(httpc->inbuf);

  infof(conn->data, "HTTP/2 DISCONNECT done\n");

  return CURLE_OK;
}
Exemplo n.º 8
0
static void run_nghttp2_session_send_server(void) {
  nghttp2_session *session;
  nghttp2_session_callbacks *callbacks;
  int rv;
  const uint8_t *txdata;
  ssize_t txdatalen;
  const uint8_t origin[] = "nghttp2.org";
  const uint8_t altsvc_field_value[] = "h2=\":443\"";

  rv = nghttp2_session_callbacks_new(&callbacks);
  if (rv != 0) {
    return;
  }

  rv = nghttp2_session_server_new3(&session, callbacks, NULL, NULL,
                                   nghttp2_mem_fm());

  nghttp2_session_callbacks_del(callbacks);

  if (rv != 0) {
    return;
  }

  rv = nghttp2_submit_altsvc(session, NGHTTP2_FLAG_NONE, 0, origin,
                             sizeof(origin) - 1, altsvc_field_value,
                             sizeof(altsvc_field_value) - 1);
  if (rv != 0) {
    goto fail;
  }

  txdatalen = nghttp2_session_mem_send(session, &txdata);

  if (txdatalen < 0) {
    goto fail;
  }

fail:
  nghttp2_session_del(session);
}
Exemplo n.º 9
0
    int nghttp2client_connect(httpclient *pclient, char *url, int port, http2_ssl_custom_conf_t *ssl_config, const struct URI *uri)
    {
        struct Connection connection;
        nghttp2_session_callbacks *callbacks;
        int rv;
        int ret = 0;
        struct Request req;
        request_init(&req, uri);

        if (0 == (ret = nghttp2s_client_conn(pclient, url, port, ssl_config))) {
            pclient->remote_port = HTTPS_PORT;
            nghttp2_socket.fd = pclient->fd.fd;
        } else {
            printf("https_client_conn failed %d\r\n", ret);
            /* Resource cleanup */
            mbedtls_ssl_close_notify( &(pclient->ssl) );
            mbedtls_net_free( &pclient->fd );
            mbedtls_x509_crt_free( &(ssl_config->verify_source.cacertl) );
            mbedtls_ssl_free( &(pclient->ssl) );
            mbedtls_ssl_config_free( &(ssl_config->conf) );
            mbedtls_ctr_drbg_free(&ctr_drbg);
            mbedtls_entropy_free(&entropy);
            request_free(&req);
            return ret;

        }

        //set_tcp_nodelay(nghttp2_socket.fd);

        connection.ssl = &(pclient->ssl);
        rv = nghttp2_session_callbacks_new(&callbacks);

        if (rv != 0) {
            printf("nghttp2_session_callbacks_new1 %d", rv);
        }

        setup_nghttp2_callbacks(callbacks);
        rv = nghttp2_session_client_new(&connection.session, callbacks, &connection);


        nghttp2_session_callbacks_del(callbacks);

        if (rv != 0) {
            printf("nghttp2_session_client_new2 %d", rv);
        }

        nghttp2_submit_settings(connection.session, NGHTTP2_FLAG_NONE, NULL, 0);

        /* Submit the HTTP request to the outbound queue. */

        submit_request(&connection, &req);

        /* Event loop */
        while (1) {
            int read_flag = 0;
            int write_flag = 0;

            write_flag = nghttp2_session_want_write(connection.session);
            if (write_flag) {
                int rv = nghttp2_session_send(connection.session);
                printf("nghttp2_session_send %d\r\n", rv);
                if (rv < 0) {
                    write_flag = 0;
                    //break;
                }
            }

            read_flag = nghttp2_session_want_read(connection.session);
            if (read_flag) {
                int rv = nghttp2_session_recv(connection.session);
                printf("nghttp2_session_recv %d\r\n", rv);
                if (rv < 0) {
                    read_flag = 0;
                    //break;
                }
            }

            printf("write_flag = %d, read_flag = %d\r\n", write_flag, read_flag);

            if ((read_flag == 0) && (write_flag == 0)) {
                printf("No active stream!\r\n");
                break;
            }
        }

        /* Resource cleanup */

        nghttp2_session_del(connection.session);

        mbedtls_ssl_close_notify( &(pclient->ssl) );
        mbedtls_net_free( &pclient->fd );
        mbedtls_x509_crt_free( &(ssl_config->verify_source.cacertl) );
        mbedtls_ssl_free( &(pclient->ssl) );
        mbedtls_ssl_config_free( &(ssl_config->conf) );
        mbedtls_ctr_drbg_free(&ctr_drbg);
        mbedtls_entropy_free(&entropy);

        request_free(&req);
        return 0;

    }
Exemplo n.º 10
0
void h2_session_destroy(h2_session *session)
{
    assert(session);
    if (session->streams) {
        if (h2_stream_set_size(session->streams)) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c,
                          "h2_session(%ld): destroy, %ld streams open",
                          session->id, h2_stream_set_size(session->streams));
            /* destroy all sessions, join all existing tasks */
            h2_stream_set_iter(session->streams, close_active_iter, session);
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c,
                          "h2_session(%ld): destroy, %ld streams remain",
                          session->id, h2_stream_set_size(session->streams));
        }
        h2_stream_set_destroy(session->streams);
        session->streams = NULL;
    }
    if (session->zombies) {
        if (h2_stream_set_size(session->zombies)) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c,
                          "h2_session(%ld): destroy, %ld zombie streams",
                          session->id, h2_stream_set_size(session->zombies));
            /* destroy all zombies, join all existing tasks */
            h2_stream_set_iter(session->zombies, close_zombie_iter, session);
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c,
                          "h2_session(%ld): destroy, %ld zombies remain",
                          session->id, h2_stream_set_size(session->zombies));
        }
        h2_stream_set_destroy(session->zombies);
        session->zombies = NULL;
    }
    if (session->ngh2) {
        nghttp2_session_del(session->ngh2);
        session->ngh2 = NULL;
    }
    if (session->mplx) {
        h2_mplx_destroy(session->mplx);
        session->mplx = NULL;
    }
    h2_conn_io_destroy(&session->io);
    
    if (session->iowait) {
        apr_thread_cond_destroy(session->iowait);
        session->iowait = NULL;
    }
    
    apr_allocator_t *allocator = session->allocator;
    if (session->alock) {
        if (allocator) {
            apr_allocator_mutex_set(allocator, session->alock);
        }
        apr_thread_mutex_destroy(session->alock);
        session->alock = NULL;
    }
    if (session->pool) {
        apr_pool_destroy(session->pool);
    }
    if (allocator) {
        apr_allocator_destroy(allocator);
    }
}
Exemplo n.º 11
0
/*
 * Fetches the resource denoted by |uri|.
 */
static void fetch_uri(const struct URI *uri) {
  nghttp2_session_callbacks *callbacks;
  int fd;
  SSL_CTX *ssl_ctx;
  SSL *ssl;
  struct Request req;
  struct Connection connection;
  int rv;
  nfds_t npollfds = 1;
  struct pollfd pollfds[1];

  request_init(&req, uri);

  /* Establish connection and setup SSL */
  fd = connect_to(req.host, req.port);
  if (fd == -1) {
    die("Could not open file descriptor");
  }
  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
  if (ssl_ctx == NULL) {
    dief("SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL));
  }
  init_ssl_ctx(ssl_ctx);
  ssl = SSL_new(ssl_ctx);
  if (ssl == NULL) {
    dief("SSL_new", ERR_error_string(ERR_get_error(), NULL));
  }
  /* To simplify the program, we perform SSL/TLS handshake in blocking
     I/O. */
  ssl_handshake(ssl, fd);

  connection.ssl = ssl;
  connection.want_io = IO_NONE;

  /* Here make file descriptor non-block */
  make_non_block(fd);
  set_tcp_nodelay(fd);

  printf("[INFO] SSL/TLS handshake completed\n");

  rv = nghttp2_session_callbacks_new(&callbacks);

  if (rv != 0) {
    diec("nghttp2_session_callbacks_new", rv);
  }

  setup_nghttp2_callbacks(callbacks);

  rv = nghttp2_session_client_new(&connection.session, callbacks, &connection);

  nghttp2_session_callbacks_del(callbacks);

  if (rv != 0) {
    diec("nghttp2_session_client_new", rv);
  }

  rv = nghttp2_submit_settings(connection.session, NGHTTP2_FLAG_NONE, NULL, 0);

  if (rv != 0) {
    diec("nghttp2_submit_settings", rv);
  }

  /* Submit the HTTP request to the outbound queue. */
  submit_request(&connection, &req);

  pollfds[0].fd = fd;
  ctl_poll(pollfds, &connection);

  /* Event loop */
  while (nghttp2_session_want_read(connection.session) ||
         nghttp2_session_want_write(connection.session)) {
    int nfds = poll(pollfds, npollfds, -1);
    if (nfds == -1) {
      dief("poll", strerror(errno));
    }
    if (pollfds[0].revents & (POLLIN | POLLOUT)) {
      exec_io(&connection);
    }
    if ((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) {
      die("Connection error");
    }
    ctl_poll(pollfds, &connection);
  }

  /* Resource cleanup */
  nghttp2_session_del(connection.session);
  SSL_shutdown(ssl);
  SSL_free(ssl);
  SSL_CTX_free(ssl_ctx);
  shutdown(fd, SHUT_WR);
  close(fd);
  request_free(&req);
}
Exemplo n.º 12
0
static void run_nghttp2_session_recv(void) {
  nghttp2_session *session;
  nghttp2_session_callbacks callbacks;
  nghttp2_hd_deflater deflater;
  nghttp2_frame frame;
  nghttp2_bufs bufs;
  nghttp2_nv nv[] = {MAKE_NV(":authority", "example.org"),
                     MAKE_NV(":scheme", "https")};
  nghttp2_settings_entry iv[2];
  my_user_data ud;
  data_feed df;
  int rv;
  nghttp2_nv *nva;
  size_t nvlen;

  rv = frame_pack_bufs_init(&bufs);

  if (rv != 0) {
    return;
  }

  memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
  callbacks.recv_callback = data_feed_recv_callback;
  ud.df = &df;

  nghttp2_failmalloc_pause();
  nvlen = ARRLEN(nv);
  nghttp2_nv_array_copy(&nva, nv, nvlen, nghttp2_mem_fm());
  nghttp2_hd_deflate_init(&deflater, nghttp2_mem_fm());
  nghttp2_session_server_new3(&session, &callbacks, &ud, NULL,
                              nghttp2_mem_fm());
  nghttp2_failmalloc_unpause();

  /* HEADERS */
  nghttp2_failmalloc_pause();
  nghttp2_frame_headers_init(&frame.headers, NGHTTP2_FLAG_END_STREAM, 1,
                             NGHTTP2_HCAT_REQUEST, NULL, nva, nvlen);
  nghttp2_frame_pack_headers(&bufs, &frame.headers, &deflater);
  nghttp2_frame_headers_free(&frame.headers, nghttp2_mem_fm());
  data_feed_init(&df, &bufs);
  nghttp2_bufs_reset(&bufs);

  nghttp2_failmalloc_unpause();

  rv = nghttp2_session_recv(session);
  if (rv != 0) {
    goto fail;
  }

  /* PING */
  nghttp2_failmalloc_pause();
  nghttp2_frame_ping_init(&frame.ping, NGHTTP2_FLAG_NONE, NULL);
  nghttp2_frame_pack_ping(&bufs, &frame.ping);
  nghttp2_frame_ping_free(&frame.ping);
  data_feed_init(&df, &bufs);
  nghttp2_bufs_reset(&bufs);

  nghttp2_failmalloc_unpause();

  rv = nghttp2_session_recv(session);
  if (rv != 0) {
    goto fail;
  }

  /* RST_STREAM */
  nghttp2_failmalloc_pause();
  nghttp2_frame_rst_stream_init(&frame.rst_stream, 1, NGHTTP2_PROTOCOL_ERROR);
  nghttp2_frame_pack_rst_stream(&bufs, &frame.rst_stream);
  nghttp2_frame_rst_stream_free(&frame.rst_stream);
  nghttp2_bufs_reset(&bufs);

  nghttp2_failmalloc_unpause();

  rv = nghttp2_session_recv(session);
  if (rv != 0) {
    goto fail;
  }

  /* SETTINGS */
  nghttp2_failmalloc_pause();
  iv[0].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
  iv[0].value = 4096;
  iv[1].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
  iv[1].value = 100;
  nghttp2_frame_settings_init(&frame.settings, NGHTTP2_FLAG_NONE,
                              nghttp2_frame_iv_copy(iv, 2, nghttp2_mem_fm()),
                              2);
  nghttp2_frame_pack_settings(&bufs, &frame.settings);
  nghttp2_frame_settings_free(&frame.settings, nghttp2_mem_fm());
  nghttp2_bufs_reset(&bufs);

  nghttp2_failmalloc_unpause();

  rv = nghttp2_session_recv(session);
  if (rv != 0) {
    goto fail;
  }

fail:
  nghttp2_bufs_free(&bufs);
  nghttp2_session_del(session);
  nghttp2_hd_deflate_free(&deflater);
}
Exemplo n.º 13
0
static void run_nghttp2_session_send(void) {
  nghttp2_session *session;
  nghttp2_session_callbacks callbacks;
  nghttp2_nv nv[] = {MAKE_NV(":host", "example.org"),
                     MAKE_NV(":scheme", "https")};
  nghttp2_data_provider data_prd;
  nghttp2_settings_entry iv[2];
  my_user_data ud;
  int rv;
  memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
  callbacks.send_callback = null_send_callback;

  data_prd.read_callback = fixed_length_data_source_read_callback;
  ud.data_source_length = 64 * 1024;

  iv[0].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
  iv[0].value = 4096;
  iv[1].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
  iv[1].value = 100;

  rv = nghttp2_session_client_new3(&session, &callbacks, &ud, NULL,
                                   nghttp2_mem_fm());
  if (rv != 0) {
    goto client_new_fail;
  }
  rv = nghttp2_submit_request(session, NULL, nv, ARRLEN(nv), &data_prd, NULL);
  if (rv < 0) {
    goto fail;
  }
  rv = nghttp2_submit_headers(session, NGHTTP2_FLAG_NONE, -1, NULL, nv,
                              ARRLEN(nv), NULL);
  if (rv < 0) {
    goto fail;
  }
  rv = nghttp2_session_send(session);
  if (rv != 0) {
    goto fail;
  }
  /* The HEADERS submitted by the previous nghttp2_submit_headers will
     have stream ID 3. Send HEADERS to that stream. */
  rv = nghttp2_submit_headers(session, NGHTTP2_FLAG_NONE, 3, NULL, nv,
                              ARRLEN(nv), NULL);
  if (rv != 0) {
    goto fail;
  }
  rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM, 3, &data_prd);
  if (rv != 0) {
    goto fail;
  }
  rv = nghttp2_session_send(session);
  if (rv != 0) {
    goto fail;
  }
  rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, 3, NGHTTP2_CANCEL);
  if (rv != 0) {
    goto fail;
  }
  rv = nghttp2_session_send(session);
  if (rv != 0) {
    goto fail;
  }
  /* Sending against half-closed stream */
  rv = nghttp2_submit_headers(session, NGHTTP2_FLAG_NONE, 3, NULL, nv,
                              ARRLEN(nv), NULL);
  if (rv != 0) {
    goto fail;
  }
  rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM, 3, &data_prd);
  if (rv != 0) {
    goto fail;
  }
  rv = nghttp2_submit_ping(session, NGHTTP2_FLAG_NONE, NULL);
  if (rv != 0) {
    goto fail;
  }
  rv = nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, iv, 2);
  if (rv != 0) {
    goto fail;
  }
  rv = nghttp2_session_send(session);
  if (rv != 0) {
    goto fail;
  }
  rv = nghttp2_submit_goaway(session, NGHTTP2_FLAG_NONE, 100, NGHTTP2_NO_ERROR,
                             NULL, 0);
  if (rv != 0) {
    goto fail;
  }
  rv = nghttp2_session_send(session);
  if (rv != 0) {
    goto fail;
  }

fail:
  nghttp2_session_del(session);
client_new_fail:;
}