mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-07 18:48:54 +08:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c76aaeea4 | ||
|
|
2b51ad67d3 | ||
|
|
708379dcab | ||
|
|
73106b0d0d | ||
|
|
572735e496 | ||
|
|
e8d693c395 | ||
|
|
f44dfcd9dc | ||
|
|
1f1b0d93d4 | ||
|
|
ce8c749b77 | ||
|
|
3e4f257b91 | ||
|
|
86fab997b4 | ||
|
|
c3ecd44592 | ||
|
|
c65ca20a49 | ||
|
|
a5c408c5e3 | ||
|
|
06379b2861 | ||
|
|
e04de48ed9 | ||
|
|
009646421c | ||
|
|
8d0b4544f8 | ||
|
|
d8a34131e1 | ||
|
|
5db17d0af9 | ||
|
|
1bf69b5662 | ||
|
|
3febaef1fa | ||
|
|
b1bd6035e8 | ||
|
|
b48bcb214a | ||
|
|
6f3ce2c72d | ||
|
|
2f9121cf44 | ||
|
|
e65e7711ca | ||
|
|
636ef51b0f | ||
|
|
400934e5a3 | ||
|
|
4c3a3acf9b | ||
|
|
9aa6002c37 | ||
|
|
f342260bfe | ||
|
|
a6dd497016 | ||
|
|
842509dab6 | ||
|
|
4add618a3f |
2
AUTHORS
2
AUTHORS
@@ -92,6 +92,7 @@ Tomasz Buchert
|
||||
Tomasz Torcz
|
||||
Vernon Tang
|
||||
Viacheslav Biriukov
|
||||
Viktor Szakats
|
||||
Viktor Szépe
|
||||
Wenfeng Liu
|
||||
Xiaoguang Sun
|
||||
@@ -103,6 +104,7 @@ clemahieu
|
||||
dalf
|
||||
es
|
||||
fangdingjun
|
||||
jwchoi
|
||||
kumagi
|
||||
lstefani
|
||||
makovich
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
# XXX using 1.8.90 instead of 1.9.0-DEV
|
||||
project(nghttp2 VERSION 1.31.0)
|
||||
project(nghttp2 VERSION 1.32.1)
|
||||
|
||||
# See versioning rule:
|
||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
set(LT_CURRENT 30)
|
||||
set(LT_REVISION 0)
|
||||
set(LT_REVISION 3)
|
||||
set(LT_AGE 16)
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
@@ -14,6 +14,7 @@ option(ENABLE_PYTHON_BINDINGS "Build Python bindings"
|
||||
${ENABLE_PYTHON_BINDINGS_DEFAULT})
|
||||
option(ENABLE_FAILMALLOC "Build failmalloc test program" ON)
|
||||
option(ENABLE_LIB_ONLY "Build libnghttp2 only. This is a short hand for -DENABLE_APP=0 -DENABLE_EXAMPLES=0 -DENABLE_HPACK_TOOLS=0 -DENABLE_PYTHON_BINDINGS=0")
|
||||
option(ENABLE_STATIC_LIB "Build libnghttp2 in static mode also")
|
||||
|
||||
option(WITH_LIBXML2 "Use libxml2"
|
||||
${WITH_LIBXML2_DEFAULT})
|
||||
|
||||
@@ -951,7 +951,7 @@ output_length
|
||||
The length of the compressed header block.
|
||||
|
||||
percentage_of_original_size
|
||||
``input_length`` / ``output_length`` * 100
|
||||
``output_length`` / ``input_length`` * 100
|
||||
|
||||
wire
|
||||
The compressed header block as a hex string.
|
||||
|
||||
@@ -25,7 +25,7 @@ dnl Do not change user variables!
|
||||
dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
|
||||
|
||||
AC_PREREQ(2.61)
|
||||
AC_INIT([nghttp2], [1.31.0], [t-tujikawa@users.sourceforge.net])
|
||||
AC_INIT([nghttp2], [1.32.1], [t-tujikawa@users.sourceforge.net])
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
@@ -45,7 +45,7 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
dnl See versioning rule:
|
||||
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
AC_SUBST(LT_CURRENT, 30)
|
||||
AC_SUBST(LT_REVISION, 0)
|
||||
AC_SUBST(LT_REVISION, 3)
|
||||
AC_SUBST(LT_AGE, 16)
|
||||
|
||||
major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "H2LOAD" "1" "Feb 27, 2018" "1.31.0" "nghttp2"
|
||||
.TH "H2LOAD" "1" "Aug 25, 2018" "1.32.1" "nghttp2"
|
||||
.SH NAME
|
||||
h2load \- HTTP/2 benchmarking tool
|
||||
.
|
||||
@@ -155,7 +155,7 @@ example, with \fI\%\-t\fP2 and \fI\%\-r\fP4, each thread gets 2
|
||||
connections per period. When the rate is 0, the program
|
||||
will run as it normally does, creating connections at
|
||||
whatever variable rate it wants. The default value for
|
||||
this option is 0.
|
||||
this option is 0. \fI\%\-r\fP and \fI\%\-D\fP are mutually exclusive.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -170,7 +170,8 @@ option is 1s.
|
||||
.TP
|
||||
.B \-D, \-\-duration=<N>
|
||||
Specifies the main duration for the measurements in case
|
||||
of timing\-based benchmarking.
|
||||
of timing\-based benchmarking. \fI\%\-D\fP and \fI\%\-r\fP are mutually
|
||||
exclusive.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
|
||||
@@ -124,7 +124,7 @@ OPTIONS
|
||||
connections per period. When the rate is 0, the program
|
||||
will run as it normally does, creating connections at
|
||||
whatever variable rate it wants. The default value for
|
||||
this option is 0.
|
||||
this option is 0. :option:`-r` and :option:`\-D` are mutually exclusive.
|
||||
|
||||
.. option:: --rate-period=<DURATION>
|
||||
|
||||
@@ -137,7 +137,8 @@ OPTIONS
|
||||
.. option:: -D, --duration=<N>
|
||||
|
||||
Specifies the main duration for the measurements in case
|
||||
of timing-based benchmarking.
|
||||
of timing-based benchmarking. :option:`-D` and :option:`\-r` are mutually
|
||||
exclusive.
|
||||
|
||||
.. option:: --warm-up-time=<DURATION>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "NGHTTP" "1" "Feb 27, 2018" "1.31.0" "nghttp2"
|
||||
.TH "NGHTTP" "1" "Aug 25, 2018" "1.32.1" "nghttp2"
|
||||
.SH NAME
|
||||
nghttp \- HTTP/2 client
|
||||
.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "NGHTTPD" "1" "Feb 27, 2018" "1.31.0" "nghttp2"
|
||||
.TH "NGHTTPD" "1" "Aug 25, 2018" "1.32.1" "nghttp2"
|
||||
.SH NAME
|
||||
nghttpd \- HTTP/2 server
|
||||
.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "NGHTTPX" "1" "Feb 27, 2018" "1.31.0" "nghttp2"
|
||||
.TH "NGHTTPX" "1" "Aug 25, 2018" "1.32.1" "nghttp2"
|
||||
.SH NAME
|
||||
nghttpx \- HTTP/2 proxy
|
||||
.
|
||||
|
||||
@@ -67,14 +67,14 @@ int main(int argc, char *argv[]) {
|
||||
return;
|
||||
}
|
||||
|
||||
req->on_response([&sess](const response &res) {
|
||||
req->on_response([](const response &res) {
|
||||
std::cerr << "HTTP/2 " << res.status_code() << std::endl;
|
||||
for (auto &kv : res.header()) {
|
||||
std::cerr << kv.first << ": " << kv.second.value << "\n";
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
|
||||
res.on_data([&sess](const uint8_t *data, std::size_t len) {
|
||||
res.on_data([](const uint8_t *data, std::size_t len) {
|
||||
std::cerr.write(reinterpret_cast<const char *>(data), len);
|
||||
std::cerr << std::endl;
|
||||
});
|
||||
|
||||
@@ -91,17 +91,17 @@ int main(int argc, char *argv[]) {
|
||||
return;
|
||||
}
|
||||
|
||||
req->on_response([&sess, req](const response &res) {
|
||||
req->on_response([](const response &res) {
|
||||
std::cerr << "response header was received" << std::endl;
|
||||
print_header(res);
|
||||
|
||||
res.on_data([&sess](const uint8_t *data, std::size_t len) {
|
||||
res.on_data([](const uint8_t *data, std::size_t len) {
|
||||
std::cerr.write(reinterpret_cast<const char *>(data), len);
|
||||
std::cerr << std::endl;
|
||||
});
|
||||
});
|
||||
|
||||
req->on_close([&sess](uint32_t error_code) {
|
||||
req->on_close([](uint32_t error_code) {
|
||||
std::cerr << "request done with error_code=" << error_code << std::endl;
|
||||
});
|
||||
|
||||
|
||||
@@ -345,6 +345,7 @@ static void setup_nghttp2_callbacks(nghttp2_session_callbacks *callbacks) {
|
||||
callbacks, on_data_chunk_recv_callback);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
/*
|
||||
* Callback function for TLS NPN. Since this program only supports
|
||||
* HTTP/2 protocol, if server does not offer HTTP/2 the nghttp2
|
||||
@@ -365,6 +366,7 @@ static int select_next_proto_cb(SSL *ssl, unsigned char **out,
|
||||
}
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
#endif /* !OPENSSL_NO_NEXTPROTONEG */
|
||||
|
||||
/*
|
||||
* Setup SSL/TLS context.
|
||||
@@ -375,7 +377,9 @@ static void init_ssl_ctx(SSL_CTX *ssl_ctx) {
|
||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||
/* Set NPN callback */
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
|
||||
#endif /* !OPENSSL_NO_NEXTPROTONEG */
|
||||
}
|
||||
|
||||
static void ssl_handshake(SSL *ssl, int fd) {
|
||||
|
||||
@@ -308,6 +308,7 @@ static int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
/* NPN TLS extension client callback. We check that server advertised
|
||||
the HTTP/2 protocol the nghttp2 library supports. If not, exit
|
||||
the program. */
|
||||
@@ -322,6 +323,7 @@ static int select_next_proto_cb(SSL *ssl, unsigned char **out,
|
||||
}
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
#endif /* !OPENSSL_NO_NEXTPROTONEG */
|
||||
|
||||
/* Create SSL_CTX. */
|
||||
static SSL_CTX *create_ssl_ctx(void) {
|
||||
@@ -335,11 +337,13 @@ static SSL_CTX *create_ssl_ctx(void) {
|
||||
SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
|
||||
SSL_OP_NO_COMPRESSION |
|
||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
|
||||
#endif /* !OPENSSL_NO_NEXTPROTONEG */
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
|
||||
|
||||
return ssl_ctx;
|
||||
}
|
||||
@@ -504,12 +508,14 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr) {
|
||||
|
||||
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
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
|
||||
|
||||
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
||||
fprintf(stderr, "h2 is not negotiated\n");
|
||||
|
||||
@@ -109,6 +109,7 @@ struct app_context {
|
||||
static unsigned char next_proto_list[256];
|
||||
static size_t next_proto_list_len;
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
static int next_proto_cb(SSL *ssl, const unsigned char **data,
|
||||
unsigned int *len, void *arg) {
|
||||
(void)ssl;
|
||||
@@ -118,6 +119,7 @@ static int next_proto_cb(SSL *ssl, const unsigned char **data,
|
||||
*len = (unsigned int)next_proto_list_len;
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
#endif /* !OPENSSL_NO_NEXTPROTONEG */
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
static int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
|
||||
@@ -135,7 +137,7 @@ static int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
|
||||
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
|
||||
|
||||
/* Create SSL_CTX. */
|
||||
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
|
||||
@@ -172,11 +174,13 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
|
||||
NGHTTP2_PROTO_VERSION_ID_LEN);
|
||||
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
|
||||
#endif /* !OPENSSL_NO_NEXTPROTONEG */
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
|
||||
|
||||
return ssl_ctx;
|
||||
}
|
||||
@@ -690,12 +694,14 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr) {
|
||||
|
||||
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
|
||||
#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);
|
||||
|
||||
@@ -49,7 +49,7 @@ target_include_directories(nghttp2 INTERFACE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
|
||||
)
|
||||
|
||||
if(HAVE_CUNIT)
|
||||
if(HAVE_CUNIT OR ENABLE_STATIC_LIB)
|
||||
# Static library (for unittests because of symbol visibility)
|
||||
add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES})
|
||||
set_target_properties(nghttp2_static PROPERTIES
|
||||
@@ -58,6 +58,10 @@ if(HAVE_CUNIT)
|
||||
ARCHIVE_OUTPUT_NAME nghttp2
|
||||
)
|
||||
target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
|
||||
if(ENABLE_STATIC_LIB)
|
||||
install(TARGETS nghttp2_static
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install(TARGETS nghttp2
|
||||
|
||||
@@ -3797,10 +3797,13 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
|
||||
* .. warning::
|
||||
*
|
||||
* This function returns assigned stream ID if it succeeds. But
|
||||
* that stream is not opened yet. The application must not submit
|
||||
* that stream is not created yet. The application must not submit
|
||||
* frame to that stream ID before
|
||||
* :type:`nghttp2_before_frame_send_callback` is called for this
|
||||
* frame.
|
||||
* frame. This means `nghttp2_session_get_stream_user_data()` does
|
||||
* not work before the callback. But
|
||||
* `nghttp2_session_set_stream_user_data()` handles this situation
|
||||
* specially, and it can set data to a stream during this period.
|
||||
*
|
||||
*/
|
||||
NGHTTP2_EXTERN int32_t nghttp2_submit_request(
|
||||
|
||||
@@ -215,6 +215,9 @@ void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem) {
|
||||
nghttp2_ext_altsvc *altsvc;
|
||||
|
||||
altsvc = frame->payload;
|
||||
if (altsvc == NULL) {
|
||||
return;
|
||||
}
|
||||
/* We use the same buffer for altsvc->origin and
|
||||
altsvc->field_value. */
|
||||
nghttp2_mem_free(mem, altsvc->origin);
|
||||
|
||||
@@ -244,7 +244,7 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
stream->status_code = (int16_t)parse_uint(nv->value->base, nv->value->len);
|
||||
if (stream->status_code == -1) {
|
||||
if (stream->status_code == -1 || stream->status_code == 101) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -219,6 +219,10 @@ static int session_terminate_session(nghttp2_session *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ignore all incoming frames because we are going to tear down the
|
||||
session. */
|
||||
session->iframe.state = NGHTTP2_IB_IGN_ALL;
|
||||
|
||||
if (reason == NULL) {
|
||||
debug_data = NULL;
|
||||
debug_datalen = 0;
|
||||
@@ -5346,9 +5350,6 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
|
||||
if (iframe->sbuf.pos[3] != NGHTTP2_SETTINGS ||
|
||||
(iframe->sbuf.pos[4] & NGHTTP2_FLAG_ACK)) {
|
||||
|
||||
iframe->state = NGHTTP2_IB_IGN_ALL;
|
||||
|
||||
rv = session_call_error_callback(
|
||||
session, NGHTTP2_ERR_SETTINGS_EXPECTED,
|
||||
"Remote peer returned unexpected data while we expected "
|
||||
@@ -5395,10 +5396,6 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
DEBUGF("recv: length is too large %zu > %u\n", iframe->frame.hd.length,
|
||||
session->local_settings.max_frame_size);
|
||||
|
||||
busy = 1;
|
||||
|
||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||
|
||||
rv = nghttp2_session_terminate_session_with_reason(
|
||||
session, NGHTTP2_FRAME_SIZE_ERROR, "too large frame size");
|
||||
|
||||
@@ -5406,7 +5403,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
break;
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
switch (iframe->frame.hd.type) {
|
||||
@@ -5420,6 +5417,9 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
busy = 1;
|
||||
|
||||
rv = session_on_data_received_fail_fast(session);
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
if (rv == NGHTTP2_ERR_IGN_PAYLOAD) {
|
||||
DEBUGF("recv: DATA not allowed stream_id=%d\n",
|
||||
iframe->frame.hd.stream_id);
|
||||
@@ -5433,7 +5433,6 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
|
||||
rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd);
|
||||
if (rv < 0) {
|
||||
iframe->state = NGHTTP2_IB_IGN_DATA;
|
||||
rv = nghttp2_session_terminate_session_with_reason(
|
||||
session, NGHTTP2_PROTOCOL_ERROR,
|
||||
"DATA: insufficient padding space");
|
||||
@@ -5441,7 +5440,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
if (rv == 1) {
|
||||
@@ -5462,17 +5461,13 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
|
||||
rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd);
|
||||
if (rv < 0) {
|
||||
busy = 1;
|
||||
|
||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||
|
||||
rv = nghttp2_session_terminate_session_with_reason(
|
||||
session, NGHTTP2_PROTOCOL_ERROR,
|
||||
"HEADERS: insufficient padding space");
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
if (rv == 1) {
|
||||
@@ -5514,6 +5509,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
|
||||
busy = 1;
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
||||
rv = nghttp2_session_add_rst_stream(
|
||||
session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
|
||||
@@ -5628,15 +5627,13 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
|
||||
rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd);
|
||||
if (rv < 0) {
|
||||
busy = 1;
|
||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||
rv = nghttp2_session_terminate_session_with_reason(
|
||||
session, NGHTTP2_PROTOCOL_ERROR,
|
||||
"PUSH_PROMISE: insufficient padding space");
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
if (rv == 1) {
|
||||
@@ -5696,11 +5693,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
busy = 1;
|
||||
|
||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||
|
||||
break;
|
||||
return (ssize_t)inlen;
|
||||
default:
|
||||
DEBUGF("recv: extension frame\n");
|
||||
|
||||
@@ -5770,6 +5763,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
case NGHTTP2_IB_IGN_PAYLOAD:
|
||||
case NGHTTP2_IB_FRAME_SIZE_ERROR:
|
||||
case NGHTTP2_IB_IGN_DATA:
|
||||
case NGHTTP2_IB_IGN_ALL:
|
||||
break;
|
||||
default:
|
||||
rv = session_call_on_begin_frame(session, &iframe->frame.hd);
|
||||
@@ -5800,21 +5794,19 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
case NGHTTP2_HEADERS:
|
||||
if (iframe->padlen == 0 &&
|
||||
(iframe->frame.hd.flags & NGHTTP2_FLAG_PADDED)) {
|
||||
pri_fieldlen = nghttp2_frame_priority_len(iframe->frame.hd.flags);
|
||||
padlen = inbound_frame_compute_pad(iframe);
|
||||
if (padlen < 0) {
|
||||
busy = 1;
|
||||
if (padlen < 0 ||
|
||||
(size_t)padlen + pri_fieldlen > 1 + iframe->payloadleft) {
|
||||
rv = nghttp2_session_terminate_session_with_reason(
|
||||
session, NGHTTP2_PROTOCOL_ERROR, "HEADERS: invalid padding");
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||
break;
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
iframe->frame.headers.padlen = (size_t)padlen;
|
||||
|
||||
pri_fieldlen = nghttp2_frame_priority_len(iframe->frame.hd.flags);
|
||||
|
||||
if (pri_fieldlen > 0) {
|
||||
if (iframe->payloadleft < pri_fieldlen) {
|
||||
busy = 1;
|
||||
@@ -5837,6 +5829,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
|
||||
busy = 1;
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
||||
rv = nghttp2_session_add_rst_stream(
|
||||
session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
|
||||
@@ -5861,6 +5857,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
session_inbound_frame_reset(session);
|
||||
|
||||
break;
|
||||
@@ -5870,6 +5870,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
session_inbound_frame_reset(session);
|
||||
|
||||
break;
|
||||
@@ -5877,16 +5881,15 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
if (iframe->padlen == 0 &&
|
||||
(iframe->frame.hd.flags & NGHTTP2_FLAG_PADDED)) {
|
||||
padlen = inbound_frame_compute_pad(iframe);
|
||||
if (padlen < 0) {
|
||||
busy = 1;
|
||||
if (padlen < 0 || (size_t)padlen + 4 /* promised stream id */
|
||||
> 1 + iframe->payloadleft) {
|
||||
rv = nghttp2_session_terminate_session_with_reason(
|
||||
session, NGHTTP2_PROTOCOL_ERROR,
|
||||
"PUSH_PROMISE: invalid padding");
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||
break;
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
iframe->frame.push_promise.padlen = (size_t)padlen;
|
||||
@@ -5911,6 +5914,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
|
||||
busy = 1;
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
||||
rv = nghttp2_session_add_rst_stream(
|
||||
session, iframe->frame.push_promise.promised_stream_id,
|
||||
@@ -5936,6 +5943,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
session_inbound_frame_reset(session);
|
||||
|
||||
break;
|
||||
@@ -5967,6 +5978,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
session_inbound_frame_reset(session);
|
||||
|
||||
break;
|
||||
@@ -6028,6 +6043,12 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
|
||||
data_readlen = inbound_frame_effective_readlen(
|
||||
iframe, iframe->payloadleft - readlen, readlen);
|
||||
|
||||
if (data_readlen == -1) {
|
||||
/* everything is padding */
|
||||
data_readlen = 0;
|
||||
}
|
||||
|
||||
trail_padlen = nghttp2_frame_trail_padlen(&iframe->frame, iframe->padlen);
|
||||
|
||||
final = (iframe->frame.hd.flags & NGHTTP2_FLAG_END_HEADERS) &&
|
||||
@@ -6047,6 +6068,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
if (rv == NGHTTP2_ERR_PAUSE) {
|
||||
in += hd_proclen;
|
||||
iframe->payloadleft -= hd_proclen;
|
||||
@@ -6156,11 +6181,9 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
busy = 1;
|
||||
assert(iframe->state == NGHTTP2_IB_IGN_ALL);
|
||||
|
||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||
|
||||
break;
|
||||
return (ssize_t)inlen;
|
||||
case NGHTTP2_IB_READ_SETTINGS:
|
||||
DEBUGF("recv: [IB_READ_SETTINGS]\n");
|
||||
|
||||
@@ -6189,6 +6212,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
session_inbound_frame_reset(session);
|
||||
|
||||
break;
|
||||
@@ -6219,6 +6246,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
session_inbound_frame_reset(session);
|
||||
|
||||
break;
|
||||
@@ -6258,11 +6289,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
busy = 1;
|
||||
|
||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||
|
||||
break;
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
/* CONTINUATION won't bear NGHTTP2_PADDED flag */
|
||||
@@ -6306,6 +6333,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
/* Pad Length field is consumed immediately */
|
||||
rv =
|
||||
nghttp2_session_consume(session, iframe->frame.hd.stream_id, readlen);
|
||||
@@ -6314,6 +6345,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id);
|
||||
if (stream) {
|
||||
rv = session_update_recv_stream_window_size(
|
||||
@@ -6334,8 +6369,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
iframe->state = NGHTTP2_IB_IGN_DATA;
|
||||
break;
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
iframe->frame.data.padlen = (size_t)padlen;
|
||||
@@ -6369,6 +6403,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
rv = session_update_recv_stream_window_size(
|
||||
session, stream, readlen,
|
||||
iframe->payloadleft ||
|
||||
@@ -6395,6 +6433,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUGF("recv: data_readlen=%zd\n", data_readlen);
|
||||
@@ -6410,6 +6452,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_DATA) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
}
|
||||
|
||||
rv = nghttp2_session_add_rst_stream(
|
||||
@@ -6467,6 +6513,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
|
||||
|
||||
/* Ignored DATA is considered as "consumed" immediately. */
|
||||
@@ -6475,6 +6525,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7031,12 +7085,42 @@ int nghttp2_session_set_stream_user_data(nghttp2_session *session,
|
||||
int32_t stream_id,
|
||||
void *stream_user_data) {
|
||||
nghttp2_stream *stream;
|
||||
nghttp2_frame *frame;
|
||||
nghttp2_outbound_item *item;
|
||||
|
||||
stream = nghttp2_session_get_stream(session, stream_id);
|
||||
if (!stream) {
|
||||
if (stream) {
|
||||
stream->stream_user_data = stream_user_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (session->server || !nghttp2_session_is_my_stream_id(session, stream_id) ||
|
||||
!nghttp2_outbound_queue_top(&session->ob_syn)) {
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
stream->stream_user_data = stream_user_data;
|
||||
return 0;
|
||||
|
||||
frame = &nghttp2_outbound_queue_top(&session->ob_syn)->frame;
|
||||
assert(frame->hd.type == NGHTTP2_HEADERS);
|
||||
|
||||
if (frame->hd.stream_id > stream_id ||
|
||||
(uint32_t)stream_id >= session->next_stream_id) {
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
for (item = session->ob_syn.head; item; item = item->qnext) {
|
||||
if (item->frame.hd.stream_id < stream_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item->frame.hd.stream_id > stream_id) {
|
||||
break;
|
||||
}
|
||||
|
||||
item->aux_data.headers.stream_user_data = stream_user_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
int nghttp2_session_resume_data(nghttp2_session *session, int32_t stream_id) {
|
||||
|
||||
@@ -888,7 +888,9 @@ int Http2Handler::verify_npn_result() {
|
||||
const unsigned char *next_proto = nullptr;
|
||||
unsigned int next_proto_len;
|
||||
// Check the negotiated protocol in NPN or ALPN
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_get0_next_proto_negotiated(ssl_, &next_proto, &next_proto_len);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (next_proto) {
|
||||
auto proto = StringRef{next_proto, next_proto_len};
|
||||
@@ -1982,6 +1984,7 @@ HttpServer::HttpServer(const Config *config) : config_(config) {
|
||||
};
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
namespace {
|
||||
int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len,
|
||||
void *arg) {
|
||||
@@ -1991,6 +1994,7 @@ int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len,
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
} // namespace
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
|
||||
namespace {
|
||||
int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
|
||||
@@ -2205,7 +2209,9 @@ int HttpServer::run() {
|
||||
|
||||
next_proto = util::get_default_alpn();
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, &next_proto);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
// ALPN selection callback
|
||||
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, this);
|
||||
|
||||
@@ -38,6 +38,10 @@ session_tls_impl::session_tls_impl(
|
||||
// ssl::context::set_verify_mode(boost::asio::ssl::verify_peer) is
|
||||
// not used, which is what we want.
|
||||
socket_.set_verify_callback(boost::asio::ssl::rfc2818_verification(host));
|
||||
auto ssl = socket_.native_handle();
|
||||
if (!util::numeric_host(host.c_str())) {
|
||||
SSL_set_tlsext_host_name(ssl, host.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
session_tls_impl::~session_tls_impl() {}
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace nghttp2 {
|
||||
namespace asio_http2 {
|
||||
namespace client {
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
namespace {
|
||||
int client_select_next_proto_cb(SSL *ssl, unsigned char **out,
|
||||
unsigned char *outlen, const unsigned char *in,
|
||||
@@ -46,6 +47,7 @@ int client_select_next_proto_cb(SSL *ssl, unsigned char **out,
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
} // namespace
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
|
||||
boost::system::error_code
|
||||
configure_tls_context(boost::system::error_code &ec,
|
||||
@@ -54,7 +56,9 @@ configure_tls_context(boost::system::error_code &ec,
|
||||
|
||||
auto ctx = tls_ctx.native_handle();
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_CTX_set_next_proto_select_cb(ctx, client_select_next_proto_cb, nullptr);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
auto proto_list = util::get_default_alpn();
|
||||
|
||||
@@ -177,7 +177,9 @@ bool tls_h2_negotiated(ssl_socket &socket) {
|
||||
const unsigned char *next_proto = nullptr;
|
||||
unsigned int next_proto_len = 0;
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_get0_next_proto_negotiated(ssl, &next_proto, &next_proto_len);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
if (next_proto == nullptr) {
|
||||
SSL_get0_alpn_selected(ssl, &next_proto, &next_proto_len);
|
||||
|
||||
@@ -35,12 +35,14 @@ namespace nghttp2 {
|
||||
namespace asio_http2 {
|
||||
namespace server {
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
namespace {
|
||||
std::vector<unsigned char> &get_alpn_token() {
|
||||
static auto alpn_token = util::get_default_alpn();
|
||||
return alpn_token;
|
||||
}
|
||||
} // namespace
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
namespace {
|
||||
@@ -82,6 +84,7 @@ configure_tls_context_easy(boost::system::error_code &ec,
|
||||
}
|
||||
#endif /* OPENSSL_NO_EC */
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_CTX_set_next_protos_advertised_cb(
|
||||
ctx,
|
||||
[](SSL *s, const unsigned char **data, unsigned int *len, void *arg) {
|
||||
@@ -93,6 +96,7 @@ configure_tls_context_easy(boost::system::error_code &ec,
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
},
|
||||
nullptr);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
// ALPN selection callback
|
||||
|
||||
@@ -857,7 +857,9 @@ int Client::connection_made() {
|
||||
const unsigned char *next_proto = nullptr;
|
||||
unsigned int next_proto_len;
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_get0_next_proto_negotiated(ssl, &next_proto, &next_proto_len);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
if (next_proto == nullptr) {
|
||||
SSL_get0_alpn_selected(ssl, &next_proto, &next_proto_len);
|
||||
@@ -1563,6 +1565,7 @@ std::string get_reqline(const char *uri, const http_parser_url &u) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
namespace {
|
||||
int client_select_next_proto_cb(SSL *ssl, unsigned char **out,
|
||||
unsigned char *outlen, const unsigned char *in,
|
||||
@@ -1577,6 +1580,7 @@ int client_select_next_proto_cb(SSL *ssl, unsigned char **out,
|
||||
return SSL_TLSEXT_ERR_NOACK;
|
||||
}
|
||||
} // namespace
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
|
||||
namespace {
|
||||
constexpr char UNIX_PATH_PREFIX[] = "unix:";
|
||||
@@ -1852,7 +1856,7 @@ Options:
|
||||
connections per period. When the rate is 0, the program
|
||||
will run as it normally does, creating connections at
|
||||
whatever variable rate it wants. The default value for
|
||||
this option is 0.
|
||||
this option is 0. -r and -D are mutually exclusive.
|
||||
--rate-period=<DURATION>
|
||||
Specifies the time period between creating connections.
|
||||
The period must be a positive number, representing the
|
||||
@@ -1861,7 +1865,8 @@ Options:
|
||||
option is 1s.
|
||||
-D, --duration=<N>
|
||||
Specifies the main duration for the measurements in case
|
||||
of timing-based benchmarking.
|
||||
of timing-based benchmarking. -D and -r are mutually
|
||||
exclusive.
|
||||
--warm-up-time=<DURATION>
|
||||
Specifies the time period before starting the actual
|
||||
measurements, in case of timing-based benchmarking.
|
||||
@@ -2294,6 +2299,11 @@ int main(int argc, char **argv) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (config.is_timing_based_mode() && config.is_rate_mode()) {
|
||||
std::cerr << "-r, -D: they are mutually exclusive." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (config.nreqs == 0 && !config.is_timing_based_mode()) {
|
||||
std::cerr << "-n: the number of requests must be strictly greater than 0 "
|
||||
"if timing-based test is not being run."
|
||||
@@ -2399,8 +2409,10 @@ int main(int argc, char **argv) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_CTX_set_next_proto_select_cb(ssl_ctx, client_select_next_proto_cb,
|
||||
nullptr);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
std::vector<unsigned char> proto_list;
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include "base64.h"
|
||||
#include "tls.h"
|
||||
#include "template.h"
|
||||
#include "ssl_compat.h"
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY (0)
|
||||
@@ -680,15 +681,16 @@ int HttpClient::initiate_connection() {
|
||||
const auto &host_string =
|
||||
config.host_override.empty() ? host : config.host_override;
|
||||
|
||||
#if (!defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
OPENSSL_VERSION_NUMBER >= 0x10002000L) || \
|
||||
#if LIBRESSL_2_7_API || \
|
||||
(!LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L) || \
|
||||
defined(OPENSSL_IS_BORINGSSL)
|
||||
auto param = SSL_get0_param(ssl);
|
||||
X509_VERIFY_PARAM_set_hostflags(param, 0);
|
||||
X509_VERIFY_PARAM_set1_host(param, host_string.c_str(),
|
||||
host_string.size());
|
||||
#endif // (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >=
|
||||
// 0x10002000L) || defined(OPENSSL_IS_BORINGSSL)
|
||||
#endif // LIBRESSL_2_7_API || (!LIBRESSL_IN_USE &&
|
||||
// OPENSSL_VERSION_NUMBER >= 0x10002000L) ||
|
||||
// defined(OPENSSL_IS_BORINGSSL)
|
||||
SSL_set_verify(ssl, SSL_VERIFY_PEER, verify_cb);
|
||||
|
||||
if (!util::numeric_host(host_string.c_str())) {
|
||||
@@ -1095,7 +1097,9 @@ int HttpClient::connection_made() {
|
||||
// Check NPN or ALPN result
|
||||
const unsigned char *next_proto = nullptr;
|
||||
unsigned int next_proto_len;
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_get0_next_proto_negotiated(ssl, &next_proto, &next_proto_len);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (next_proto) {
|
||||
auto proto = StringRef{next_proto, next_proto_len};
|
||||
@@ -2220,6 +2224,7 @@ id responseEnd requestStart process code size request path)"
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
namespace {
|
||||
int client_select_next_proto_cb(SSL *ssl, unsigned char **out,
|
||||
unsigned char *outlen, const unsigned char *in,
|
||||
@@ -2243,6 +2248,7 @@ int client_select_next_proto_cb(SSL *ssl, unsigned char **out,
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
} // namespace
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
|
||||
namespace {
|
||||
int communicate(
|
||||
@@ -2308,8 +2314,10 @@ int communicate(
|
||||
goto fin;
|
||||
}
|
||||
}
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_CTX_set_next_proto_select_cb(ssl_ctx, client_select_next_proto_cb,
|
||||
nullptr);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
auto proto_list = util::get_default_alpn();
|
||||
|
||||
@@ -549,7 +549,9 @@ int ClientHandler::validate_next_proto() {
|
||||
// First set callback for catch all cases
|
||||
on_read_ = &ClientHandler::upstream_read;
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_get0_next_proto_negotiated(conn_.tls.ssl, &next_proto, &next_proto_len);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
if (next_proto == nullptr) {
|
||||
SSL_get0_alpn_selected(conn_.tls.ssl, &next_proto, &next_proto_len);
|
||||
|
||||
@@ -1222,7 +1222,7 @@ int parse_subcert_params(SubcertParams &out, const StringRef &src_params) {
|
||||
auto param = StringRef{first, end};
|
||||
|
||||
if (util::istarts_with_l(param, "sct-dir=")) {
|
||||
#if !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
#if !LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
auto sct_dir =
|
||||
StringRef{std::begin(param) + str_size("sct-dir="), std::end(param)};
|
||||
if (sct_dir.empty()) {
|
||||
@@ -1230,9 +1230,9 @@ int parse_subcert_params(SubcertParams &out, const StringRef &src_params) {
|
||||
return -1;
|
||||
}
|
||||
out.sct_dir = sct_dir;
|
||||
#else // !(!LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
#else // !(!LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
LOG(WARN) << "subcert: sct-dir requires OpenSSL >= 1.0.2";
|
||||
#endif // !(!LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
#endif // !(!LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
} else if (!param.empty()) {
|
||||
LOG(ERROR) << "subcert: " << param << ": unknown keyword";
|
||||
return -1;
|
||||
@@ -1364,7 +1364,7 @@ int read_tls_sct_from_dir(std::vector<uint8_t> &dst, const StringRef &opt,
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#if !LIBRESSL_IN_USE
|
||||
#if !LIBRESSL_LEGACY_API
|
||||
namespace {
|
||||
// Reads PSK secrets from path, and parses each line. The result is
|
||||
// directly stored into config->tls.psk_secrets. This function
|
||||
@@ -1428,9 +1428,9 @@ int parse_psk_secrets(Config *config, const StringRef &path) {
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
#endif // !LIBRESSL_IN_USE
|
||||
#endif // !LIBRESSL_LEGACY_API
|
||||
|
||||
#if !LIBRESSL_IN_USE
|
||||
#if !LIBRESSL_LEGACY_API
|
||||
namespace {
|
||||
// Reads PSK secrets from path, and parses each line. The result is
|
||||
// directly stored into config->tls.client.psk. This function returns
|
||||
@@ -1490,7 +1490,7 @@ int parse_client_psk_secrets(Config *config, const StringRef &path) {
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
#endif // !LIBRESSL_IN_USE
|
||||
#endif // !LIBRESSL_LEGACY_API
|
||||
|
||||
// generated by gennghttpxfun.py
|
||||
int option_lookup_token(const char *name, size_t namelen) {
|
||||
@@ -3454,19 +3454,19 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
||||
return parse_uint_with_unit(
|
||||
&config->http2.downstream.decoder_dynamic_table_size, opt, optarg);
|
||||
case SHRPX_OPTID_ECDH_CURVES:
|
||||
#if !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
#if !LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
config->tls.ecdh_curves = make_string_ref(config->balloc, optarg);
|
||||
#else // !(!LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
#else // !(!LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
LOG(WARN) << opt << ": This option requires OpenSSL >= 1.0.2";
|
||||
#endif // !(!LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
#endif // !(!LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
return 0;
|
||||
case SHRPX_OPTID_TLS_SCT_DIR:
|
||||
#if !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
#if !LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
return read_tls_sct_from_dir(config->tls.sct_data, opt, optarg);
|
||||
#else // !(!LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
#else // !(!LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
LOG(WARN) << opt << ": This option requires OpenSSL >= 1.0.2";
|
||||
return 0;
|
||||
#endif // !(!LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
#endif // !(!LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
case SHRPX_OPTID_DNS_CACHE_TIMEOUT:
|
||||
return parse_duration(&config->dns.timeout.cache, opt, optarg);
|
||||
case SHRPX_OPTID_DNS_LOOKUP_TIMEOUT:
|
||||
@@ -3489,23 +3489,23 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
||||
return parse_duration(&config->conn.upstream.timeout.idle_read, opt,
|
||||
optarg);
|
||||
case SHRPX_OPTID_PSK_SECRETS:
|
||||
#if !LIBRESSL_IN_USE
|
||||
#if !LIBRESSL_LEGACY_API
|
||||
return parse_psk_secrets(config, optarg);
|
||||
#else // LIBRESSL_IN_USE
|
||||
#else // LIBRESSL_LEGACY_API
|
||||
LOG(WARN)
|
||||
<< opt
|
||||
<< ": ignored because underlying TLS library does not support PSK";
|
||||
return 0;
|
||||
#endif // LIBRESSL_IN_USE
|
||||
#endif // LIBRESSL_LEGACY_API
|
||||
case SHRPX_OPTID_CLIENT_PSK_SECRETS:
|
||||
#if !LIBRESSL_IN_USE
|
||||
#if !LIBRESSL_LEGACY_API
|
||||
return parse_client_psk_secrets(config, optarg);
|
||||
#else // LIBRESSL_IN_USE
|
||||
#else // LIBRESSL_LEGACY_API
|
||||
LOG(WARN)
|
||||
<< opt
|
||||
<< ": ignored because underlying TLS library does not support PSK";
|
||||
return 0;
|
||||
#endif // LIBRESSL_IN_USE
|
||||
#endif // LIBRESSL_LEGACY_API
|
||||
case SHRPX_OPTID_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST:
|
||||
config->tls.client.no_http2_cipher_black_list =
|
||||
util::strieq_l("yes", optarg);
|
||||
|
||||
@@ -44,13 +44,13 @@ using namespace nghttp2;
|
||||
|
||||
namespace shrpx {
|
||||
|
||||
#if !OPENSSL_1_1_API
|
||||
#if !LIBRESSL_2_7_API && !OPENSSL_1_1_API
|
||||
|
||||
void *BIO_get_data(BIO *bio) { return bio->ptr; }
|
||||
void BIO_set_data(BIO *bio, void *ptr) { bio->ptr = ptr; }
|
||||
void BIO_set_init(BIO *bio, int init) { bio->init = init; }
|
||||
|
||||
#endif // !OPENSSL_1_1_API
|
||||
#endif // !LIBRESSL_2_7_API && !OPENSSL_1_1_API
|
||||
|
||||
Connection::Connection(struct ev_loop *loop, int fd, SSL *ssl,
|
||||
MemchunkPool *mcpool, ev_tstamp write_timeout,
|
||||
@@ -523,7 +523,9 @@ int Connection::check_http2_requirement() {
|
||||
const unsigned char *next_proto = nullptr;
|
||||
unsigned int next_proto_len;
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_get0_next_proto_negotiated(tls.ssl, &next_proto, &next_proto_len);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
if (next_proto == nullptr) {
|
||||
SSL_get0_alpn_selected(tls.ssl, &next_proto, &next_proto_len);
|
||||
|
||||
@@ -1649,7 +1649,9 @@ int Http2Session::connection_made() {
|
||||
const unsigned char *next_proto = nullptr;
|
||||
unsigned int next_proto_len = 0;
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_get0_next_proto_negotiated(conn_.tls.ssl, &next_proto, &next_proto_len);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
if (!next_proto) {
|
||||
SSL_get0_alpn_selected(conn_.tls.ssl, &next_proto, &next_proto_len);
|
||||
|
||||
@@ -406,7 +406,9 @@ int LiveCheck::tls_handshake() {
|
||||
const unsigned char *next_proto = nullptr;
|
||||
unsigned int next_proto_len = 0;
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_get0_next_proto_negotiated(conn_.tls.ssl, &next_proto, &next_proto_len);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
if (next_proto == nullptr) {
|
||||
SSL_get0_alpn_selected(conn_.tls.ssl, &next_proto, &next_proto_len);
|
||||
|
||||
@@ -80,6 +80,7 @@ const unsigned char *ASN1_STRING_get0_data(ASN1_STRING *x) {
|
||||
} // namespace
|
||||
#endif // !OPENSSL_1_1_API
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
namespace {
|
||||
int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len,
|
||||
void *arg) {
|
||||
@@ -89,6 +90,7 @@ int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len,
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
} // namespace
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
|
||||
namespace {
|
||||
int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
|
||||
@@ -192,7 +194,7 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
|
||||
const auto &ssl_ctx_list = conn_handler->get_indexed_ssl_ctx(idx);
|
||||
assert(!ssl_ctx_list.empty());
|
||||
|
||||
#if !defined(OPENSSL_IS_BORINGSSL) && !defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
#if !defined(OPENSSL_IS_BORINGSSL) && !LIBRESSL_IN_USE && \
|
||||
OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
auto num_shared_curves = SSL_get_shared_curve(ssl, -1);
|
||||
|
||||
@@ -236,7 +238,7 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // !defined(OPENSSL_IS_BORINGSSL) && !defined(LIBRESSL_VERSION_NUMBER) &&
|
||||
#endif // !defined(OPENSSL_IS_BORINGSSL) && !LIBRESSL_IN_USE &&
|
||||
// OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
SSL_set_SSL_CTX(ssl, ssl_ctx_list[0]);
|
||||
@@ -655,7 +657,7 @@ int legacy_sct_parse_cb(SSL *ssl, unsigned int ext_type,
|
||||
#endif // !OPENSSL_1_1_1_API
|
||||
#endif // !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
#if !LIBRESSL_IN_USE
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
namespace {
|
||||
unsigned int psk_server_cb(SSL *ssl, const char *identity, unsigned char *psk,
|
||||
unsigned int max_psk_len) {
|
||||
@@ -679,9 +681,9 @@ unsigned int psk_server_cb(SSL *ssl, const char *identity, unsigned char *psk,
|
||||
return static_cast<unsigned int>(secret.size());
|
||||
}
|
||||
} // namespace
|
||||
#endif // !LIBRESSL_IN_USE
|
||||
#endif // !OPENSSL_NO_PSK
|
||||
|
||||
#if !LIBRESSL_IN_USE
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
namespace {
|
||||
unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity_out,
|
||||
unsigned int max_identity_len, unsigned char *psk,
|
||||
@@ -714,7 +716,7 @@ unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity_out,
|
||||
return static_cast<unsigned int>(secret.size());
|
||||
}
|
||||
} // namespace
|
||||
#endif // !LIBRESSL_IN_USE
|
||||
#endif // !OPENSSL_NO_PSK
|
||||
|
||||
struct TLSProtocol {
|
||||
StringRef name;
|
||||
@@ -792,7 +794,7 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
#if !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
#if !LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
if (SSL_CTX_set1_curves_list(ssl_ctx, tlsconf.ecdh_curves.c_str()) != 1) {
|
||||
LOG(FATAL) << "SSL_CTX_set1_curves_list " << tlsconf.ecdh_curves
|
||||
<< " failed";
|
||||
@@ -803,7 +805,7 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
|
||||
// function was deprecated in OpenSSL 1.1.0 and BoringSSL.
|
||||
SSL_CTX_set_ecdh_auto(ssl_ctx, 1);
|
||||
#endif // !defined(OPENSSL_IS_BORINGSSL) && !OPENSSL_1_1_API
|
||||
#else // LIBRESSL_IN_USE || OPENSSL_VERSION_NUBMER < 0x10002000L
|
||||
#else // LIBRESSL_LEGACY_API || OPENSSL_VERSION_NUBMER < 0x10002000L
|
||||
// Use P-256, which is sufficiently secure at the time of this
|
||||
// writing.
|
||||
auto ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
||||
@@ -814,7 +816,7 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
|
||||
}
|
||||
SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
|
||||
EC_KEY_free(ecdh);
|
||||
#endif // LIBRESSL_IN_USE || OPENSSL_VERSION_NUBMER < 0x10002000L
|
||||
#endif // LIBRESSL_LEGACY_API || OPENSSL_VERSION_NUBMER < 0x10002000L
|
||||
#endif // OPENSSL_NO_EC
|
||||
|
||||
if (!tlsconf.dh_param_file.empty()) {
|
||||
@@ -923,7 +925,9 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
|
||||
#endif // OPENSSL_IS_BORINGSSL
|
||||
|
||||
// NPN advertisement
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, nullptr);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
// ALPN selection callback
|
||||
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, nullptr);
|
||||
@@ -962,9 +966,9 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
|
||||
}
|
||||
#endif // !LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
#if !LIBRESSL_IN_USE
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
SSL_CTX_set_psk_server_callback(ssl_ctx, psk_server_cb);
|
||||
#endif // !LIBRESSL_IN_USE
|
||||
#endif // !LIBRESSL_NO_PSK
|
||||
|
||||
auto tls_ctx_data = new TLSContextData();
|
||||
tls_ctx_data->cert_file = cert_file;
|
||||
@@ -1112,13 +1116,15 @@ SSL_CTX *create_ssl_client_context(
|
||||
#endif // HAVE_NEVERBLEED
|
||||
}
|
||||
|
||||
#if !LIBRESSL_IN_USE
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
SSL_CTX_set_psk_client_callback(ssl_ctx, psk_client_cb);
|
||||
#endif // !LIBRESSL_IN_USE
|
||||
#endif // !OPENSSL_NO_PSK
|
||||
|
||||
// NPN selection callback. This is required to set SSL_CTX because
|
||||
// OpenSSL does not offer SSL_set_next_proto_select_cb.
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
SSL_CTX_set_next_proto_select_cb(ssl_ctx, next_proto_select_cb, nullptr);
|
||||
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||
|
||||
return ssl_ctx;
|
||||
}
|
||||
@@ -1549,16 +1555,15 @@ int cert_lookup_tree_add_ssl_ctx(
|
||||
SSL_CTX *ssl_ctx) {
|
||||
std::array<uint8_t, NI_MAXHOST> buf;
|
||||
|
||||
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
#if LIBRESSL_2_7_API || \
|
||||
(!LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
auto cert = SSL_CTX_get0_certificate(ssl_ctx);
|
||||
#else // defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER <
|
||||
// 0x10002000L
|
||||
#else // !LIBRESSL_2_7_API && OPENSSL_VERSION_NUMBER < 0x10002000L
|
||||
auto tls_ctx_data =
|
||||
static_cast<TLSContextData *>(SSL_CTX_get_app_data(ssl_ctx));
|
||||
auto cert = load_certificate(tls_ctx_data->cert_file);
|
||||
auto cert_deleter = defer(X509_free, cert);
|
||||
#endif // defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER <
|
||||
// 0x10002000L
|
||||
#endif // !LIBRESSL_2_7_API && OPENSSL_VERSION_NUMBER < 0x10002000L
|
||||
|
||||
auto altnames = static_cast<GENERAL_NAMES *>(
|
||||
X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr));
|
||||
@@ -1846,7 +1851,7 @@ int proto_version_from_string(const StringRef &v) {
|
||||
int verify_ocsp_response(SSL_CTX *ssl_ctx, const uint8_t *ocsp_resp,
|
||||
size_t ocsp_resplen) {
|
||||
|
||||
#if !defined(OPENSSL_NO_OCSP) && !defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
#if !defined(OPENSSL_NO_OCSP) && !LIBRESSL_IN_USE && \
|
||||
OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
int rv;
|
||||
|
||||
@@ -1919,7 +1924,7 @@ int verify_ocsp_response(SSL_CTX *ssl_ctx, const uint8_t *ocsp_resp,
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
LOG(INFO) << "OCSP verification succeeded";
|
||||
}
|
||||
#endif // !defined(OPENSSL_NO_OCSP) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#endif // !defined(OPENSSL_NO_OCSP) && !LIBRESSL_IN_USE
|
||||
// && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -27,15 +27,17 @@
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#if defined(LIBRESSL_VERSION_NUMBER)
|
||||
#define OPENSSL_1_1_API 0
|
||||
#define OPENSSL_1_1_1_API 0
|
||||
#define LIBRESSL_IN_USE 1
|
||||
#define LIBRESSL_LEGACY_API (LIBRESSL_VERSION_NUMBER < 0x20700000L)
|
||||
#define LIBRESSL_2_7_API (LIBRESSL_VERSION_NUMBER >= 0x20700000L)
|
||||
#else // !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#define OPENSSL_1_1_API (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
|
||||
#define OPENSSL_1_1_1_API (OPENSSL_VERSION_NUMBER >= 0x10101000L)
|
||||
#define LIBRESSL_IN_USE 0
|
||||
#define LIBRESSL_LEGACY_API 0
|
||||
#define LIBRESSL_2_7_API 0
|
||||
#endif // !defined(LIBRESSL_VERSION_NUMBER)
|
||||
|
||||
#define OPENSSL_1_1_API \
|
||||
(!LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x1010000fL)
|
||||
|
||||
#define OPENSSL_1_1_1_API \
|
||||
(!LIBRESSL_IN_USE && OPENSSL_VERSION_NUMBER >= 0x10101000L)
|
||||
|
||||
#endif // OPENSSL_COMPAT_H
|
||||
|
||||
@@ -43,13 +43,13 @@ int main() {
|
||||
|
||||
/* initialize the CUnit test registry */
|
||||
if (CUE_SUCCESS != CU_initialize_registry())
|
||||
return CU_get_error();
|
||||
return (int)CU_get_error();
|
||||
|
||||
/* add a suite to the registry */
|
||||
pSuite = CU_add_suite("libnghttp2_TestSuite", init_suite1, clean_suite1);
|
||||
if (NULL == pSuite) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
return (int)CU_get_error();
|
||||
}
|
||||
|
||||
/* add the tests to the suite */
|
||||
@@ -62,7 +62,7 @@ int main() {
|
||||
!CU_add_test(pSuite, "failmalloc_frame", test_nghttp2_frame) ||
|
||||
!CU_add_test(pSuite, "failmalloc_hd", test_nghttp2_hd)) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
return (int)CU_get_error();
|
||||
}
|
||||
|
||||
/* Run all tests using the CUnit Basic interface */
|
||||
@@ -74,6 +74,6 @@ int main() {
|
||||
return (int)num_tests_failed;
|
||||
} else {
|
||||
printf("CUnit Error: %s\n", CU_get_error_msg());
|
||||
return CU_get_error();
|
||||
return (int)CU_get_error();
|
||||
}
|
||||
}
|
||||
|
||||
12
tests/main.c
12
tests/main.c
@@ -55,13 +55,13 @@ int main() {
|
||||
|
||||
/* initialize the CUnit test registry */
|
||||
if (CUE_SUCCESS != CU_initialize_registry())
|
||||
return CU_get_error();
|
||||
return (int)CU_get_error();
|
||||
|
||||
/* add a suite to the registry */
|
||||
pSuite = CU_add_suite("libnghttp2_TestSuite", init_suite1, clean_suite1);
|
||||
if (NULL == pSuite) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
return (int)CU_get_error();
|
||||
}
|
||||
|
||||
/* add the tests to the suite */
|
||||
@@ -87,6 +87,8 @@ int main() {
|
||||
test_nghttp2_session_recv_continuation) ||
|
||||
!CU_add_test(pSuite, "session_recv_headers_with_priority",
|
||||
test_nghttp2_session_recv_headers_with_priority) ||
|
||||
!CU_add_test(pSuite, "session_recv_headers_with_padding",
|
||||
test_nghttp2_session_recv_headers_with_padding) ||
|
||||
!CU_add_test(pSuite, "session_recv_headers_early_response",
|
||||
test_nghttp2_session_recv_headers_early_response) ||
|
||||
!CU_add_test(pSuite, "session_server_recv_push_response",
|
||||
@@ -314,6 +316,8 @@ int main() {
|
||||
test_nghttp2_session_pause_data) ||
|
||||
!CU_add_test(pSuite, "session_no_closed_streams",
|
||||
test_nghttp2_session_no_closed_streams) ||
|
||||
!CU_add_test(pSuite, "session_set_stream_user_data",
|
||||
test_nghttp2_session_set_stream_user_data) ||
|
||||
!CU_add_test(pSuite, "http_mandatory_headers",
|
||||
test_nghttp2_http_mandatory_headers) ||
|
||||
!CU_add_test(pSuite, "http_content_length",
|
||||
@@ -409,7 +413,7 @@ int main() {
|
||||
test_nghttp2_bufs_next_present) ||
|
||||
!CU_add_test(pSuite, "bufs_realloc", test_nghttp2_bufs_realloc)) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
return (int)CU_get_error();
|
||||
}
|
||||
|
||||
/* Run all tests using the CUnit Basic interface */
|
||||
@@ -421,6 +425,6 @@ int main() {
|
||||
return (int)num_tests_failed;
|
||||
} else {
|
||||
printf("CUnit Error: %s\n", CU_get_error_msg());
|
||||
return CU_get_error();
|
||||
return (int)CU_get_error();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1575,6 +1575,94 @@ void test_nghttp2_session_recv_headers_with_priority(void) {
|
||||
nghttp2_session_del(session);
|
||||
}
|
||||
|
||||
void test_nghttp2_session_recv_headers_with_padding(void) {
|
||||
nghttp2_session *session;
|
||||
nghttp2_session_callbacks callbacks;
|
||||
nghttp2_bufs bufs;
|
||||
nghttp2_buf *buf;
|
||||
nghttp2_frame_hd hd;
|
||||
nghttp2_outbound_item *item;
|
||||
my_user_data ud;
|
||||
ssize_t rv;
|
||||
|
||||
frame_pack_bufs_init(&bufs);
|
||||
|
||||
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
||||
callbacks.on_frame_recv_callback = on_frame_recv_callback;
|
||||
callbacks.send_callback = null_send_callback;
|
||||
|
||||
/* HEADERS: Wrong padding length */
|
||||
nghttp2_session_server_new(&session, &callbacks, &ud);
|
||||
nghttp2_session_send(session);
|
||||
|
||||
nghttp2_frame_hd_init(&hd, 10, NGHTTP2_HEADERS,
|
||||
NGHTTP2_FLAG_END_HEADERS | NGHTTP2_FLAG_PRIORITY |
|
||||
NGHTTP2_FLAG_PADDED,
|
||||
1);
|
||||
buf = &bufs.head->buf;
|
||||
nghttp2_frame_pack_frame_hd(buf->last, &hd);
|
||||
buf->last += NGHTTP2_FRAME_HDLEN;
|
||||
/* padding is 6 bytes */
|
||||
*buf->last++ = 5;
|
||||
/* priority field */
|
||||
nghttp2_put_uint32be(buf->last, 3);
|
||||
buf->last += sizeof(uint32_t);
|
||||
*buf->last++ = 1;
|
||||
/* rest is garbage */
|
||||
memset(buf->last, 0, 4);
|
||||
buf->last += 4;
|
||||
|
||||
ud.frame_recv_cb_called = 0;
|
||||
|
||||
rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
|
||||
|
||||
CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
|
||||
CU_ASSERT(0 == ud.frame_recv_cb_called);
|
||||
|
||||
item = nghttp2_session_get_next_ob_item(session);
|
||||
|
||||
CU_ASSERT(NULL != item);
|
||||
CU_ASSERT(NGHTTP2_GOAWAY == item->frame.hd.type);
|
||||
|
||||
nghttp2_bufs_reset(&bufs);
|
||||
nghttp2_session_del(session);
|
||||
|
||||
/* PUSH_PROMISE: Wrong padding length */
|
||||
nghttp2_session_client_new(&session, &callbacks, &ud);
|
||||
nghttp2_session_send(session);
|
||||
|
||||
open_sent_stream(session, 1);
|
||||
|
||||
nghttp2_frame_hd_init(&hd, 9, NGHTTP2_PUSH_PROMISE,
|
||||
NGHTTP2_FLAG_END_HEADERS | NGHTTP2_FLAG_PADDED, 1);
|
||||
buf = &bufs.head->buf;
|
||||
nghttp2_frame_pack_frame_hd(buf->last, &hd);
|
||||
buf->last += NGHTTP2_FRAME_HDLEN;
|
||||
/* padding is 6 bytes */
|
||||
*buf->last++ = 5;
|
||||
/* promised stream ID field */
|
||||
nghttp2_put_uint32be(buf->last, 2);
|
||||
buf->last += sizeof(uint32_t);
|
||||
/* rest is garbage */
|
||||
memset(buf->last, 0, 4);
|
||||
buf->last += 4;
|
||||
|
||||
ud.frame_recv_cb_called = 0;
|
||||
|
||||
rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
|
||||
|
||||
CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
|
||||
CU_ASSERT(0 == ud.frame_recv_cb_called);
|
||||
|
||||
item = nghttp2_session_get_next_ob_item(session);
|
||||
|
||||
CU_ASSERT(NULL != item);
|
||||
CU_ASSERT(NGHTTP2_GOAWAY == item->frame.hd.type);
|
||||
|
||||
nghttp2_bufs_free(&bufs);
|
||||
nghttp2_session_del(session);
|
||||
}
|
||||
|
||||
static int response_on_begin_frame_callback(nghttp2_session *session,
|
||||
const nghttp2_frame_hd *hd,
|
||||
void *user_data) {
|
||||
@@ -2297,6 +2385,31 @@ void test_nghttp2_session_recv_altsvc(void) {
|
||||
|
||||
nghttp2_session_del(session);
|
||||
|
||||
/* send too large frame */
|
||||
nghttp2_buf_reset(&buf);
|
||||
|
||||
nghttp2_session_client_new2(&session, &callbacks, &ud, option);
|
||||
|
||||
session->local_settings.max_frame_size = NGHTTP2_MAX_FRAME_SIZE_MIN - 1;
|
||||
|
||||
nghttp2_frame_hd_init(&hd, NGHTTP2_MAX_FRAME_SIZE_MIN + 1, NGHTTP2_ALTSVC,
|
||||
NGHTTP2_FLAG_NONE, 0);
|
||||
nghttp2_frame_pack_frame_hd(buf.last, &hd);
|
||||
buf.last += NGHTTP2_FRAME_HDLEN;
|
||||
nghttp2_put_uint16be(buf.last, sizeof(origin) - 1);
|
||||
buf.last += 2;
|
||||
buf.last = nghttp2_cpymem(buf.last, origin, sizeof(origin) - 1);
|
||||
memset(buf.last, 0, nghttp2_buf_avail(&buf));
|
||||
buf.last += nghttp2_buf_avail(&buf);
|
||||
|
||||
ud.frame_recv_cb_called = 0;
|
||||
rv = nghttp2_session_mem_recv(session, buf.pos, nghttp2_buf_len(&buf));
|
||||
|
||||
CU_ASSERT((ssize_t)nghttp2_buf_len(&buf) == rv);
|
||||
CU_ASSERT(0 == ud.frame_recv_cb_called);
|
||||
|
||||
nghttp2_session_del(session);
|
||||
|
||||
/* received by server */
|
||||
nghttp2_buf_reset(&buf);
|
||||
|
||||
@@ -10329,6 +10442,39 @@ void test_nghttp2_session_no_closed_streams(void) {
|
||||
nghttp2_option_del(option);
|
||||
}
|
||||
|
||||
void test_nghttp2_session_set_stream_user_data(void) {
|
||||
nghttp2_session *session;
|
||||
nghttp2_session_callbacks callbacks;
|
||||
int32_t stream_id;
|
||||
int user_data1, user_data2;
|
||||
int rv;
|
||||
const uint8_t *datap;
|
||||
ssize_t datalen;
|
||||
|
||||
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
||||
|
||||
nghttp2_session_client_new(&session, &callbacks, NULL);
|
||||
|
||||
stream_id = nghttp2_submit_request(session, NULL, reqnv, ARRLEN(reqnv), NULL,
|
||||
&user_data1);
|
||||
|
||||
rv = nghttp2_session_set_stream_user_data(session, stream_id, &user_data2);
|
||||
|
||||
CU_ASSERT(0 == rv);
|
||||
|
||||
datalen = nghttp2_session_mem_send(session, &datap);
|
||||
|
||||
CU_ASSERT(datalen > 0);
|
||||
|
||||
CU_ASSERT(&user_data2 ==
|
||||
nghttp2_session_get_stream_user_data(session, stream_id));
|
||||
|
||||
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT ==
|
||||
nghttp2_session_set_stream_user_data(session, 2, NULL));
|
||||
|
||||
nghttp2_session_del(session);
|
||||
}
|
||||
|
||||
static void check_nghttp2_http_recv_headers_fail(
|
||||
nghttp2_session *session, nghttp2_hd_deflater *deflater, int32_t stream_id,
|
||||
int stream_state, const nghttp2_nv *nva, size_t nvlen) {
|
||||
@@ -10437,6 +10583,7 @@ void test_nghttp2_http_mandatory_headers(void) {
|
||||
MAKE_NV("content-length", "0")};
|
||||
const nghttp2_nv clnonzero204_resnv[] = {MAKE_NV(":status", "204"),
|
||||
MAKE_NV("content-length", "100")};
|
||||
const nghttp2_nv status101_resnv[] = {MAKE_NV(":status", "101")};
|
||||
|
||||
/* test case for request */
|
||||
const nghttp2_nv nopath_reqnv[] = {MAKE_NV(":scheme", "https"),
|
||||
@@ -10551,6 +10698,12 @@ void test_nghttp2_http_mandatory_headers(void) {
|
||||
session, &deflater, 21, NGHTTP2_STREAM_OPENING, clnonzero204_resnv,
|
||||
ARRLEN(clnonzero204_resnv));
|
||||
|
||||
/* status code 101 should not be used in HTTP/2 because it is used
|
||||
for HTTP Upgrade which HTTP/2 removes. */
|
||||
check_nghttp2_http_recv_headers_fail(session, &deflater, 23,
|
||||
NGHTTP2_STREAM_OPENING, status101_resnv,
|
||||
ARRLEN(status101_resnv));
|
||||
|
||||
nghttp2_hd_deflate_free(&deflater);
|
||||
|
||||
nghttp2_session_del(session);
|
||||
|
||||
@@ -37,6 +37,7 @@ void test_nghttp2_session_recv_data(void);
|
||||
void test_nghttp2_session_recv_data_no_auto_flow_control(void);
|
||||
void test_nghttp2_session_recv_continuation(void);
|
||||
void test_nghttp2_session_recv_headers_with_priority(void);
|
||||
void test_nghttp2_session_recv_headers_with_padding(void);
|
||||
void test_nghttp2_session_recv_headers_early_response(void);
|
||||
void test_nghttp2_session_server_recv_push_response(void);
|
||||
void test_nghttp2_session_recv_premature_headers(void);
|
||||
@@ -155,6 +156,7 @@ void test_nghttp2_session_cancel_from_before_frame_send(void);
|
||||
void test_nghttp2_session_removed_closed_stream(void);
|
||||
void test_nghttp2_session_pause_data(void);
|
||||
void test_nghttp2_session_no_closed_streams(void);
|
||||
void test_nghttp2_session_set_stream_user_data(void);
|
||||
void test_nghttp2_http_mandatory_headers(void);
|
||||
void test_nghttp2_http_content_length(void);
|
||||
void test_nghttp2_http_content_length_mismatch(void);
|
||||
|
||||
2
third-party/neverbleed
vendored
2
third-party/neverbleed
vendored
Submodule third-party/neverbleed updated: ff1171188f...1e9b518ee9
Reference in New Issue
Block a user