static void initialize_nghttp2_session(http2_session_data *session_data) { nghttp2_session_callbacks *callbacks; nghttp2_session_callbacks_new(&callbacks); nghttp2_session_callbacks_set_send_callback(callbacks, send_callback); nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks, on_frame_recv_callback); nghttp2_session_callbacks_set_on_data_chunk_recv_callback( callbacks, on_data_chunk_recv_callback); nghttp2_session_callbacks_set_on_stream_close_callback( callbacks, on_stream_close_callback); nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header_callback); nghttp2_session_callbacks_set_on_begin_headers_callback( callbacks, on_begin_headers_callback); nghttp2_session_client_new(&session_data->session, callbacks, session_data); nghttp2_session_callbacks_del(callbacks); }
static int prepare_h2_session(session *sess) { int ret; nghttp2_option *option; nghttp2_session_callbacks *callbacks; if(nghttp2_option_new(&option)==0 && nghttp2_session_callbacks_new(&callbacks)==0) { h2session_setup_h2(&sess->S, callbacks, option); if(nghttp2_session_server_new2(&sess->S.h2sess, callbacks, sess, option)) { fprintf(stderr, "Failed to create server session\n"); ret = 1; } else ret = 0; } else { fprintf(stderr, "Failed to alloc options/callbacks\n"); ret = 1; } nghttp2_session_callbacks_del(callbacks); nghttp2_option_del(option); return ret; }
static apr_status_t init_callbacks(conn_rec *c, nghttp2_session_callbacks **pcb) { int rv = nghttp2_session_callbacks_new(pcb); if (rv != 0) { ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02926) "nghttp2_session_callbacks_new: %s", nghttp2_strerror(rv)); return APR_EGENERAL; } NGH2_SET_CALLBACK(*pcb, send, send_cb); NGH2_SET_CALLBACK(*pcb, on_frame_recv, on_frame_recv_cb); NGH2_SET_CALLBACK(*pcb, on_invalid_frame_recv, on_invalid_frame_recv_cb); NGH2_SET_CALLBACK(*pcb, on_data_chunk_recv, on_data_chunk_recv_cb); NGH2_SET_CALLBACK(*pcb, before_frame_send, before_frame_send_cb); NGH2_SET_CALLBACK(*pcb, on_frame_send, on_frame_send_cb); NGH2_SET_CALLBACK(*pcb, on_frame_not_send, on_frame_not_send_cb); NGH2_SET_CALLBACK(*pcb, on_stream_close, on_stream_close_cb); NGH2_SET_CALLBACK(*pcb, on_begin_headers, on_begin_headers_cb); NGH2_SET_CALLBACK(*pcb, on_header, on_header_cb); NGH2_SET_CALLBACK(*pcb, send_data, on_send_data_cb); NGH2_SET_CALLBACK(*pcb, data_source_read_length, on_data_source_read_length_cb); return APR_SUCCESS; }
/* * Initialize nghttp2 for a Curl connection */ CURLcode Curl_http2_init(struct connectdata *conn) { if(!conn->proto.httpc.h2) { int rc; nghttp2_session_callbacks *callbacks; conn->proto.httpc.inbuf = malloc(H2_BUFSIZE); if(conn->proto.httpc.inbuf == NULL) return CURLE_OUT_OF_MEMORY; rc = nghttp2_session_callbacks_new(&callbacks); if(rc) { failf(conn->data, "Couldn't initialize nghttp2 callbacks!"); return CURLE_OUT_OF_MEMORY; /* most likely at least */ } /* nghttp2_send_callback */ nghttp2_session_callbacks_set_send_callback(callbacks, send_callback); /* nghttp2_on_frame_recv_callback */ nghttp2_session_callbacks_set_on_frame_recv_callback (callbacks, on_frame_recv); /* nghttp2_on_invalid_frame_recv_callback */ nghttp2_session_callbacks_set_on_invalid_frame_recv_callback (callbacks, on_invalid_frame_recv); /* nghttp2_on_data_chunk_recv_callback */ nghttp2_session_callbacks_set_on_data_chunk_recv_callback (callbacks, on_data_chunk_recv); /* nghttp2_before_frame_send_callback */ nghttp2_session_callbacks_set_before_frame_send_callback (callbacks, before_frame_send); /* nghttp2_on_frame_send_callback */ nghttp2_session_callbacks_set_on_frame_send_callback (callbacks, on_frame_send); /* nghttp2_on_frame_not_send_callback */ nghttp2_session_callbacks_set_on_frame_not_send_callback (callbacks, on_frame_not_send); /* nghttp2_on_stream_close_callback */ nghttp2_session_callbacks_set_on_stream_close_callback (callbacks, on_stream_close); /* nghttp2_on_begin_headers_callback */ nghttp2_session_callbacks_set_on_begin_headers_callback (callbacks, on_begin_headers); /* nghttp2_on_header_callback */ nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header); /* The nghttp2 session is not yet setup, do it */ rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn); nghttp2_session_callbacks_del(callbacks); if(rc) { failf(conn->data, "Couldn't initialize nghttp2!"); return CURLE_OUT_OF_MEMORY; /* most likely at least */ } } return CURLE_OK; }
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); }
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; }
/* * 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); }