/* eventcb for bufferevent. For the purpose of simplicity and readability of the example program, we omitted the certificate and peer verification. After SSL/TLS handshake is over, initialize nghttp2 library session, and send client connection header. Then send HTTP request. */ static void eventcb(struct bufferevent *bev, short events, void *ptr) { http2_session_data *session_data = (http2_session_data*)ptr; if(events & BEV_EVENT_CONNECTED) { int fd = bufferevent_getfd(bev); int val = 1; fprintf(stderr, "Connected\n"); setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); initialize_nghttp2_session(session_data); send_client_connection_header(session_data); submit_request(session_data); if(session_send(session_data) != 0) { delete_http2_session_data(session_data); } return; } if(events & BEV_EVENT_EOF) { warnx("Disconnected from the remote host"); } else if(events & BEV_EVENT_ERROR) { warnx("Network error"); } else if(events & BEV_EVENT_TIMEOUT) { warnx("Timeout"); } delete_http2_session_data(session_data); }
/* readcb for bufferevent to check first 24 bytes client connection header. */ static void handshake_readcb(struct bufferevent *bev, void *ptr) { http2_session_data *session_data = (http2_session_data*)ptr; uint8_t data[24]; struct evbuffer *input = bufferevent_get_input(session_data->bev); int readlen = evbuffer_remove(input, data, session_data->handshake_leftlen); const char *conhead = NGHTTP2_CLIENT_CONNECTION_HEADER; if(memcmp(conhead + NGHTTP2_CLIENT_CONNECTION_HEADER_LEN - session_data->handshake_leftlen, data, readlen) != 0) { delete_http2_session_data(session_data); return; } session_data->handshake_leftlen -= readlen; if(session_data->handshake_leftlen == 0) { bufferevent_setcb(session_data->bev, readcb, writecb, eventcb, ptr); /* Process pending data in buffer since they are not notified further */ initialize_nghttp2_session(session_data); if(send_server_connection_header(session_data) != 0) { delete_http2_session_data(session_data); return; } if(session_recv(session_data) != 0) { delete_http2_session_data(session_data); return; } } }
/* eventcb for bufferevent. For the purpose of simplicity and readability of the example program, we omitted the certificate and peer verification. After SSL/TLS handshake is over, initialize nghttp2 library session, and send client connection header. Then send HTTP request. */ static void eventcb(struct bufferevent *bev, short events, void *ptr) { http2_session_data *session_data = (http2_session_data *)ptr; if (events & BEV_EVENT_CONNECTED) { int fd = bufferevent_getfd(bev); int val = 1; const unsigned char *alpn = NULL; unsigned int alpnlen = 0; SSL *ssl; fprintf(stderr, "Connected\n"); ssl = bufferevent_openssl_get_ssl(session_data->bev); #ifndef OPENSSL_NO_NEXTPROTONEG SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen); #endif /* !OPENSSL_NO_NEXTPROTONEG */ #if OPENSSL_VERSION_NUMBER >= 0x10002000L if (alpn == NULL) { SSL_get0_alpn_selected(ssl, &alpn, &alpnlen); } #endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */ if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) { fprintf(stderr, "h2 is not negotiated\n"); delete_http2_session_data(session_data); return; } setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); initialize_nghttp2_session(session_data); send_client_connection_header(session_data); submit_request(session_data); if (session_send(session_data) != 0) { delete_http2_session_data(session_data); } return; } if (events & BEV_EVENT_EOF) { warnx("Disconnected from the remote host"); } else if (events & BEV_EVENT_ERROR) { warnx("Network error"); } else if (events & BEV_EVENT_TIMEOUT) { warnx("Timeout"); } delete_http2_session_data(session_data); }
/* eventcb for bufferevent */ static void eventcb(struct bufferevent *bev, short events, void *ptr) { http2_session_data *session_data = (http2_session_data *)ptr; if (events & BEV_EVENT_CONNECTED) { const unsigned char *alpn = NULL; unsigned int alpnlen = 0; SSL *ssl; (void)bev; fprintf(stderr, "%s connected\n", session_data->client_addr); ssl = bufferevent_openssl_get_ssl(session_data->bev); SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen); #if OPENSSL_VERSION_NUMBER >= 0x10002000L if (alpn == NULL) { SSL_get0_alpn_selected(ssl, &alpn, &alpnlen); } #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) { fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr); delete_http2_session_data(session_data); return; } initialize_nghttp2_session(session_data); if (send_server_connection_header(session_data) != 0 || session_send(session_data) != 0) { delete_http2_session_data(session_data); return; } return; } if (events & BEV_EVENT_EOF) { fprintf(stderr, "%s EOF\n", session_data->client_addr); } else if (events & BEV_EVENT_ERROR) { fprintf(stderr, "%s network error\n", session_data->client_addr); } else if (events & BEV_EVENT_TIMEOUT) { fprintf(stderr, "%s timeout\n", session_data->client_addr); } delete_http2_session_data(session_data); }