summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 08:52:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 08:52:22 +0000
commit6a7eecec57783a042d12f895d5ae148c44f4d074 (patch)
tree77a2c3c5612655f1dd15e9a2ddf14e13bab90b1f /src
parentReleasing progress-linux version 1.59.0-1~progress7.99u1. (diff)
downloadnghttp2-6a7eecec57783a042d12f895d5ae148c44f4d074.tar.xz
nghttp2-6a7eecec57783a042d12f895d5ae148c44f4d074.zip
Merging upstream version 1.60.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt84
-rw-r--r--src/HttpServer.cc60
-rw-r--r--src/HttpServer.h7
-rw-r--r--src/Makefile.am13
-rw-r--r--src/allocator.h2
-rw-r--r--src/app_helper.cc40
-rw-r--r--src/app_helper.h3
-rw-r--r--src/base64_test.cc67
-rw-r--r--src/base64_test.h10
-rw-r--r--src/buffer_test.cc51
-rw-r--r--src/buffer_test.h8
-rw-r--r--src/deflatehd.cc6
-rw-r--r--src/h2load.cc37
-rw-r--r--src/h2load.h6
-rw-r--r--src/h2load_http2_session.cc23
-rw-r--r--src/h2load_http3_session.cc2
-rw-r--r--src/h2load_quic.cc3
-rw-r--r--src/http2_test.cc777
-rw-r--r--src/http2_test.h40
-rw-r--r--src/inflatehd.cc9
-rw-r--r--src/libevent_util.cc162
-rw-r--r--src/libevent_util.h75
-rw-r--r--src/memchunk_test.cc218
-rw-r--r--src/memchunk_test.h26
-rw-r--r--src/nghttp.cc66
-rw-r--r--src/nghttp.h9
-rw-r--r--src/nghttp2_gzip_test.c52
-rw-r--r--src/nghttp2_gzip_test.h8
-rw-r--r--src/shrpx-unittest.cc210
-rw-r--r--src/shrpx.h2
-rw-r--r--src/shrpx_config.cc34
-rw-r--r--src/shrpx_config.h5
-rw-r--r--src/shrpx_config_test.cc238
-rw-r--r--src/shrpx_config_test.h15
-rw-r--r--src/shrpx_connection.cc14
-rw-r--r--src/shrpx_connection.h16
-rw-r--r--src/shrpx_connection_handler.cc23
-rw-r--r--src/shrpx_downstream_test.cc66
-rw-r--r--src/shrpx_downstream_test.h20
-rw-r--r--src/shrpx_http.cc6
-rw-r--r--src/shrpx_http.h6
-rw-r--r--src/shrpx_http2_downstream_connection.cc13
-rw-r--r--src/shrpx_http2_session.cc20
-rw-r--r--src/shrpx_http2_session.h2
-rw-r--r--src/shrpx_http2_upstream.cc51
-rw-r--r--src/shrpx_http3_upstream.cc9
-rw-r--r--src/shrpx_http_test.cc130
-rw-r--r--src/shrpx_http_test.h16
-rw-r--r--src/shrpx_live_check.cc12
-rw-r--r--src/shrpx_mruby.cc4
-rw-r--r--src/shrpx_quic.cc34
-rw-r--r--src/shrpx_quic.h11
-rw-r--r--src/shrpx_quic_connection_handler.cc6
-rw-r--r--src/shrpx_router_test.cc88
-rw-r--r--src/shrpx_router_test.h12
-rw-r--r--src/shrpx_tls.cc159
-rw-r--r--src/shrpx_tls_test.cc125
-rw-r--r--src/shrpx_tls_test.h16
-rw-r--r--src/shrpx_worker.cc138
-rw-r--r--src/shrpx_worker_process.cc10
-rw-r--r--src/shrpx_worker_test.cc305
-rw-r--r--src/shrpx_worker_test.h8
-rw-r--r--src/template_test.cc132
-rw-r--r--src/template_test.h10
-rw-r--r--src/tls.cc56
-rw-r--r--src/tls.h9
-rw-r--r--src/util_test.cc841
-rw-r--r--src/util_test.h82
68 files changed, 2611 insertions, 2207 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 201c5a2..6583324 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -21,6 +21,8 @@ include_directories(
${JANSSON_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS}
${LIBBPF_INCLUDE_DIRS}
+ ${LIBBROTLIENC_INCLUDE_DIRS}
+ ${LIBBROTLIDEC_INCLUDE_DIRS}
)
# XXX per-target?
@@ -38,6 +40,8 @@ link_libraries(
${ZLIB_LIBRARIES}
${APP_LIBRARIES}
${LIBBPF_LIBRARIES}
+ ${LIBBROTLIENC_LIBRARIES}
+ ${LIBBROTLIDEC_LIBRARIES}
)
if(ENABLE_APP)
@@ -163,45 +167,45 @@ if(ENABLE_APP)
target_link_libraries(nghttpx_static neverbleed)
endif()
-
- if(HAVE_CUNIT)
- set(NGHTTPX_UNITTEST_SOURCES
- shrpx-unittest.cc
- shrpx_tls_test.cc
- shrpx_downstream_test.cc
- shrpx_config_test.cc
- shrpx_worker_test.cc
- shrpx_http_test.cc
- shrpx_router_test.cc
- http2_test.cc
- util_test.cc
- nghttp2_gzip_test.c
- nghttp2_gzip.c
- buffer_test.cc
- memchunk_test.cc
- template_test.cc
- base64_test.cc
- )
- add_executable(nghttpx-unittest EXCLUDE_FROM_ALL
- ${NGHTTPX_UNITTEST_SOURCES}
- $<TARGET_OBJECTS:llhttp>
- $<TARGET_OBJECTS:url-parser>
- )
- target_include_directories(nghttpx-unittest PRIVATE ${CUNIT_INCLUDE_DIRS})
- target_compile_definitions(nghttpx-unittest
- PRIVATE "-DNGHTTP2_SRC_DIR=\"${CMAKE_SOURCE_DIR}/src\""
+ set(NGHTTPX_UNITTEST_SOURCES
+ shrpx-unittest.cc
+ shrpx_tls_test.cc
+ shrpx_downstream_test.cc
+ shrpx_config_test.cc
+ shrpx_worker_test.cc
+ shrpx_http_test.cc
+ shrpx_router_test.cc
+ http2_test.cc
+ util_test.cc
+ nghttp2_gzip_test.c
+ nghttp2_gzip.c
+ buffer_test.cc
+ memchunk_test.cc
+ template_test.cc
+ base64_test.cc
+ ${CMAKE_SOURCE_DIR}/tests/munit/munit.c
+ )
+ add_executable(nghttpx-unittest EXCLUDE_FROM_ALL
+ ${NGHTTPX_UNITTEST_SOURCES}
+ $<TARGET_OBJECTS:llhttp>
+ $<TARGET_OBJECTS:url-parser>
)
- target_link_libraries(nghttpx-unittest nghttpx_static ${CUNIT_LIBRARIES})
- if(HAVE_MRUBY)
- target_link_libraries(nghttpx-unittest mruby-lib)
- endif()
- if(HAVE_NEVERBLEED)
- target_link_libraries(nghttpx-unittest neverbleed)
- endif()
-
- add_test(nghttpx-unittest nghttpx-unittest)
- add_dependencies(check nghttpx-unittest)
+ target_include_directories(nghttpx-unittest PRIVATE
+ ${CMAKE_SOURCE_DIR}/tests/munit
+ )
+ target_compile_definitions(nghttpx-unittest
+ PRIVATE "-DNGHTTP2_SRC_DIR=\"${CMAKE_SOURCE_DIR}/src\""
+ )
+ target_link_libraries(nghttpx-unittest nghttpx_static)
+ if(HAVE_MRUBY)
+ target_link_libraries(nghttpx-unittest mruby-lib)
endif()
+ if(HAVE_NEVERBLEED)
+ target_link_libraries(nghttpx-unittest neverbleed)
+ endif()
+
+ add_test(nghttpx-unittest nghttpx-unittest)
+ add_dependencies(check nghttpx-unittest)
add_executable(nghttp ${NGHTTP_SOURCES} $<TARGET_OBJECTS:llhttp>
$<TARGET_OBJECTS:url-parser>
@@ -221,8 +225,7 @@ if(ENABLE_APP)
$<TARGET_OBJECTS:url-parser>
)
- install(TARGETS nghttp nghttpd nghttpx h2load
- RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+ install(TARGETS nghttp nghttpd nghttpx h2load)
endif()
if(ENABLE_HPACK_TOOLS)
@@ -238,6 +241,5 @@ if(ENABLE_HPACK_TOOLS)
)
add_executable(inflatehd ${inflatehd_SOURCES})
add_executable(deflatehd ${deflatehd_SOURCES})
- install(TARGETS inflatehd deflatehd
- RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+ install(TARGETS inflatehd deflatehd)
endif()
diff --git a/src/HttpServer.cc b/src/HttpServer.cc
index 0385cd0..b59cecd 100644
--- a/src/HttpServer.cc
+++ b/src/HttpServer.cc
@@ -607,10 +607,10 @@ int Http2Handler::fill_wb() {
for (;;) {
const uint8_t *data;
- auto datalen = nghttp2_session_mem_send(session_, &data);
+ auto datalen = nghttp2_session_mem_send2(session_, &data);
if (datalen < 0) {
- std::cerr << "nghttp2_session_mem_send() returned error: "
+ std::cerr << "nghttp2_session_mem_send2() returned error: "
<< nghttp2_strerror(datalen) << std::endl;
return -1;
}
@@ -648,10 +648,10 @@ int Http2Handler::read_clear() {
util::hexdump(stdout, buf.data(), nread);
}
- rv = nghttp2_session_mem_recv(session_, buf.data(), nread);
+ rv = nghttp2_session_mem_recv2(session_, buf.data(), nread);
if (rv < 0) {
if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
- std::cerr << "nghttp2_session_mem_recv() returned error: "
+ std::cerr << "nghttp2_session_mem_recv2() returned error: "
<< nghttp2_strerror(rv) << std::endl;
}
return -1;
@@ -771,10 +771,10 @@ int Http2Handler::read_tls() {
util::hexdump(stdout, buf.data(), nread);
}
- rv = nghttp2_session_mem_recv(session_, buf.data(), nread);
+ rv = nghttp2_session_mem_recv2(session_, buf.data(), nread);
if (rv < 0) {
if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
- std::cerr << "nghttp2_session_mem_recv() returned error: "
+ std::cerr << "nghttp2_session_mem_recv2() returned error: "
<< nghttp2_strerror(rv) << std::endl;
}
return -1;
@@ -917,7 +917,7 @@ int Http2Handler::verify_alpn_result() {
int Http2Handler::submit_file_response(const StringRef &status, Stream *stream,
time_t last_modified, off_t file_length,
const std::string *content_type,
- nghttp2_data_provider *data_prd) {
+ nghttp2_data_provider2 *data_prd) {
std::string last_modified_str;
auto nva = make_array(http2::make_nv_ls_nocopy(":status", status),
http2::make_nv_ls_nocopy("server", NGHTTPD_SERVER),
@@ -942,13 +942,13 @@ int Http2Handler::submit_file_response(const StringRef &status, Stream *stream,
if (!trailer_names.empty()) {
nva[nvlen++] = http2::make_nv_ls_nocopy("trailer", trailer_names);
}
- return nghttp2_submit_response(session_, stream->stream_id, nva.data(), nvlen,
- data_prd);
+ return nghttp2_submit_response2(session_, stream->stream_id, nva.data(),
+ nvlen, data_prd);
}
int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
const HeaderRefs &headers,
- nghttp2_data_provider *data_prd) {
+ nghttp2_data_provider2 *data_prd) {
auto nva = std::vector<nghttp2_nv>();
nva.reserve(4 + headers.size());
nva.push_back(http2::make_nv_ls_nocopy(":status", status));
@@ -965,13 +965,13 @@ int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
for (auto &nv : headers) {
nva.push_back(http2::make_nv_nocopy(nv.name, nv.value, nv.no_index));
}
- int r = nghttp2_submit_response(session_, stream_id, nva.data(), nva.size(),
- data_prd);
+ int r = nghttp2_submit_response2(session_, stream_id, nva.data(), nva.size(),
+ data_prd);
return r;
}
int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
- nghttp2_data_provider *data_prd) {
+ nghttp2_data_provider2 *data_prd) {
auto nva = make_array(http2::make_nv_ls_nocopy(":status", status),
http2::make_nv_ls_nocopy("server", NGHTTPD_SERVER),
http2::make_nv_ls("date", sessions_->get_cached_date()),
@@ -985,8 +985,8 @@ int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
}
}
- return nghttp2_submit_response(session_, stream_id, nva.data(), nvlen,
- data_prd);
+ return nghttp2_submit_response2(session_, stream_id, nva.data(), nvlen,
+ data_prd);
}
int Http2Handler::submit_non_final_response(const std::string &status,
@@ -1076,9 +1076,10 @@ void Http2Handler::terminate_session(uint32_t error_code) {
nghttp2_session_terminate_session(session_, error_code);
}
-ssize_t file_read_callback(nghttp2_session *session, int32_t stream_id,
- uint8_t *buf, size_t length, uint32_t *data_flags,
- nghttp2_data_source *source, void *user_data) {
+nghttp2_ssize file_read_callback(nghttp2_session *session, int32_t stream_id,
+ uint8_t *buf, size_t length,
+ uint32_t *data_flags,
+ nghttp2_data_source *source, void *user_data) {
int rv;
auto hd = static_cast<Http2Handler *>(user_data);
auto stream = hd->get_stream(stream_id);
@@ -1127,7 +1128,7 @@ void prepare_status_response(Stream *stream, Http2Handler *hd, int status) {
// we don't set stream->file_ent since we don't want to expire it.
stream->body_length = file_ent->length;
- nghttp2_data_provider data_prd;
+ nghttp2_data_provider2 data_prd;
data_prd.source.fd = file_ent->fd;
data_prd.read_callback = file_read_callback;
@@ -1155,7 +1156,7 @@ void prepare_echo_response(Stream *stream, Http2Handler *hd) {
hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
return;
}
- nghttp2_data_provider data_prd;
+ nghttp2_data_provider2 data_prd;
data_prd.source.fd = stream->file_ent->fd;
data_prd.read_callback = file_read_callback;
@@ -1378,7 +1379,7 @@ void prepare_response(Stream *stream, Http2Handler *hd,
stream->body_length = file_ent->length;
- nghttp2_data_provider data_prd;
+ nghttp2_data_provider2 data_prd;
data_prd.source.fd = file_ent->fd;
data_prd.read_callback = file_read_callback;
@@ -1676,9 +1677,9 @@ int send_data_callback(nghttp2_session *session, nghttp2_frame *frame,
} // namespace
namespace {
-ssize_t select_padding_callback(nghttp2_session *session,
- const nghttp2_frame *frame, size_t max_payload,
- void *user_data) {
+nghttp2_ssize select_padding_callback(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ size_t max_payload, void *user_data) {
auto hd = static_cast<Http2Handler *>(user_data);
return std::min(max_payload, frame->hd.length + hd->get_config()->padding);
}
@@ -1765,7 +1766,7 @@ void fill_callback(nghttp2_session_callbacks *callbacks, const Config *config) {
send_data_callback);
if (config->padding) {
- nghttp2_session_callbacks_set_select_padding_callback(
+ nghttp2_session_callbacks_set_select_padding_callback2(
callbacks, select_padding_callback);
}
}
@@ -2205,6 +2206,15 @@ int HttpServer::run() {
// ALPN selection callback
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, this);
+
+#if defined(NGHTTP2_OPENSSL_IS_BORINGSSL) && defined(HAVE_LIBBROTLI)
+ if (!SSL_CTX_add_cert_compression_alg(
+ ssl_ctx, nghttp2::tls::CERTIFICATE_COMPRESSION_ALGO_BROTLI,
+ nghttp2::tls::cert_compress, nghttp2::tls::cert_decompress)) {
+ std::cerr << "SSL_CTX_add_cert_compression_alg failed." << std::endl;
+ return -1;
+ }
+#endif // NGHTTP2_OPENSSL_IS_BORINGSSL && HAVE_LIBBROTLI
}
auto loop = EV_DEFAULT;
diff --git a/src/HttpServer.h b/src/HttpServer.h
index 949bd1f..00fd6bf 100644
--- a/src/HttpServer.h
+++ b/src/HttpServer.h
@@ -41,6 +41,7 @@
#include <ev.h>
+#define NGHTTP2_NO_SSIZE_T
#include <nghttp2/nghttp2.h>
#include "http2.h"
@@ -172,14 +173,14 @@ public:
int submit_file_response(const StringRef &status, Stream *stream,
time_t last_modified, off_t file_length,
const std::string *content_type,
- nghttp2_data_provider *data_prd);
+ nghttp2_data_provider2 *data_prd);
int submit_response(const StringRef &status, int32_t stream_id,
- nghttp2_data_provider *data_prd);
+ nghttp2_data_provider2 *data_prd);
int submit_response(const StringRef &status, int32_t stream_id,
const HeaderRefs &headers,
- nghttp2_data_provider *data_prd);
+ nghttp2_data_provider2 *data_prd);
int submit_non_final_response(const std::string &status, int32_t stream_id);
diff --git a/src/Makefile.am b/src/Makefile.am
index f112ac2..5e90018 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -53,6 +53,8 @@ AM_CPPFLAGS = \
@JANSSON_CFLAGS@ \
@LIBBPF_CFLAGS@ \
@ZLIB_CFLAGS@ \
+ @LIBBROTLIENC_CFLAGS@ \
+ @LIBBROTLIDEC_CFLAGS@ \
@EXTRA_DEFS@ \
@DEFS@
AM_LDFLAGS = @LIBTOOL_LDFLAGS@
@@ -73,6 +75,8 @@ LDADD = $(top_builddir)/lib/libnghttp2.la \
@JANSSON_LIBS@ \
@LIBBPF_LIBS@ \
@ZLIB_LIBS@ \
+ @LIBBROTLIENC_LIBS@ \
+ @LIBBROTLIDEC_LIBS@ \
@APPLDFLAGS@
if ENABLE_APP
@@ -203,7 +207,6 @@ libnghttpx_a_CPPFLAGS += -I${top_srcdir}/third-party/neverbleed
nghttpx_LDADD += ${top_builddir}/third-party/libneverbleed.la
endif # HAVE_NEVERBLEED
-if HAVE_CUNIT
check_PROGRAMS += nghttpx-unittest
nghttpx_unittest_SOURCES = shrpx-unittest.cc \
shrpx_tls_test.cc shrpx_tls_test.h \
@@ -219,10 +222,13 @@ nghttpx_unittest_SOURCES = shrpx-unittest.cc \
buffer_test.cc buffer_test.h \
memchunk_test.cc memchunk_test.h \
template_test.cc template_test.h \
- base64_test.cc base64_test.h
+ base64_test.cc base64_test.h \
+ $(top_srcdir)/tests/munit/munit.c $(top_srcdir)/tests/munit/munit.h \
+ $(top_srcdir)/tests/munit/munitxx.h
nghttpx_unittest_CPPFLAGS = ${AM_CPPFLAGS} \
+ -I$(top_srcdir)/tests/munit \
-DNGHTTP2_SRC_DIR=\"$(top_srcdir)/src\"
-nghttpx_unittest_LDADD = libnghttpx.a ${LDADD} @CUNIT_LIBS@ @TESTLDADD@
+nghttpx_unittest_LDADD = libnghttpx.a ${LDADD} @TESTLDADD@
if HAVE_MRUBY
nghttpx_unittest_CPPFLAGS += \
@@ -237,7 +243,6 @@ nghttpx_unittest_LDADD += ${top_builddir}/third-party/libneverbleed.la
endif # HAVE_NEVERBLEED
TESTS += nghttpx-unittest
-endif # HAVE_CUNIT
endif # ENABLE_APP
diff --git a/src/allocator.h b/src/allocator.h
index 97b9a41..363ee91 100644
--- a/src/allocator.h
+++ b/src/allocator.h
@@ -119,7 +119,7 @@ struct BlockAllocator {
}
if (!head ||
- head->end - head->last < static_cast<ssize_t>(size + sizeof(size_t))) {
+ static_cast<size_t>(head->end - head->last) < size + sizeof(size_t)) {
head = alloc_mem_block(block_size);
}
diff --git a/src/app_helper.cc b/src/app_helper.cc
index ef92762..666d16c 100644
--- a/src/app_helper.cc
+++ b/src/app_helper.cc
@@ -53,8 +53,6 @@
#include <iomanip>
#include <fstream>
-#include <zlib.h>
-
#include "app_helper.h"
#include "util.h"
#include "http2.h"
@@ -477,42 +475,4 @@ std::chrono::steady_clock::time_point get_time() {
return std::chrono::steady_clock::now();
}
-ssize_t deflate_data(uint8_t *out, size_t outlen, const uint8_t *in,
- size_t inlen) {
- int rv;
- z_stream zst{};
- uint8_t temp_out[8_k];
- auto temp_outlen = sizeof(temp_out);
-
- rv = deflateInit2(&zst, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31, 9,
- Z_DEFAULT_STRATEGY);
-
- if (rv != Z_OK) {
- return -1;
- }
-
- zst.avail_in = inlen;
- zst.next_in = (uint8_t *)in;
- zst.avail_out = temp_outlen;
- zst.next_out = temp_out;
-
- rv = deflate(&zst, Z_FINISH);
-
- deflateEnd(&zst);
-
- if (rv != Z_STREAM_END) {
- return -1;
- }
-
- temp_outlen -= zst.avail_out;
-
- if (temp_outlen > outlen) {
- return -1;
- }
-
- memcpy(out, temp_out, temp_outlen);
-
- return temp_outlen;
-}
-
} // namespace nghttp2
diff --git a/src/app_helper.h b/src/app_helper.h
index 5424054..a7ef7cc 100644
--- a/src/app_helper.h
+++ b/src/app_helper.h
@@ -90,9 +90,6 @@ void set_color_output(bool f);
// used.
void set_output(FILE *file);
-ssize_t deflate_data(uint8_t *out, size_t outlen, const uint8_t *in,
- size_t inlen);
-
} // namespace nghttp2
#endif // APP_HELPER_H
diff --git a/src/base64_test.cc b/src/base64_test.cc
index 4324bd7..9ab770f 100644
--- a/src/base64_test.cc
+++ b/src/base64_test.cc
@@ -27,7 +27,7 @@
#include <cstring>
#include <iostream>
-#include <CUnit/CUnit.h>
+#include "munitxx.h"
#include <nghttp2/nghttp2.h>
@@ -35,26 +35,38 @@
namespace nghttp2 {
+namespace {
+const MunitTest tests[]{
+ munit_void_test(test_base64_encode),
+ munit_void_test(test_base64_decode),
+ munit_test_end(),
+};
+} // namespace
+
+const MunitSuite base64_suite{
+ "/base64", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
void test_base64_encode(void) {
{
std::string in = "\xff";
auto out = base64::encode(std::begin(in), std::end(in));
- CU_ASSERT("/w==" == out);
+ assert_stdstring_equal("/w==", out);
}
{
std::string in = "\xff\xfe";
auto out = base64::encode(std::begin(in), std::end(in));
- CU_ASSERT("//4=" == out);
+ assert_stdstring_equal("//4=", out);
}
{
std::string in = "\xff\xfe\xfd";
auto out = base64::encode(std::begin(in), std::end(in));
- CU_ASSERT("//79" == out);
+ assert_stdstring_equal("//79", out);
}
{
std::string in = "\xff\xfe\xfd\xfc";
auto out = base64::encode(std::begin(in), std::end(in));
- CU_ASSERT("//79/A==" == out);
+ assert_stdstring_equal("//79/A==", out);
}
}
@@ -63,58 +75,65 @@ void test_base64_decode(void) {
{
std::string in = "/w==";
auto out = base64::decode(std::begin(in), std::end(in));
- CU_ASSERT("\xff" == out);
- CU_ASSERT("\xff" == base64::decode(balloc, std::begin(in), std::end(in)));
+ assert_stdstring_equal("\xff", out);
+ assert_stdstring_equal(
+ "\xff", base64::decode(balloc, std::begin(in), std::end(in)).str());
}
{
std::string in = "//4=";
auto out = base64::decode(std::begin(in), std::end(in));
- CU_ASSERT("\xff\xfe" == out);
- CU_ASSERT("\xff\xfe" ==
- base64::decode(balloc, std::begin(in), std::end(in)));
+ assert_stdstring_equal("\xff\xfe", out);
+ assert_stdstring_equal(
+ "\xff\xfe", base64::decode(balloc, std::begin(in), std::end(in)).str());
}
{
std::string in = "//79";
auto out = base64::decode(std::begin(in), std::end(in));
- CU_ASSERT("\xff\xfe\xfd" == out);
- CU_ASSERT("\xff\xfe\xfd" ==
- base64::decode(balloc, std::begin(in), std::end(in)));
+ assert_stdstring_equal("\xff\xfe\xfd", out);
+ assert_stdstring_equal(
+ "\xff\xfe\xfd",
+ base64::decode(balloc, std::begin(in), std::end(in)).str());
}
{
std::string in = "//79/A==";
auto out = base64::decode(std::begin(in), std::end(in));
- CU_ASSERT("\xff\xfe\xfd\xfc" == out);
- CU_ASSERT("\xff\xfe\xfd\xfc" ==
- base64::decode(balloc, std::begin(in), std::end(in)));
+ assert_stdstring_equal("\xff\xfe\xfd\xfc", out);
+ assert_stdstring_equal(
+ "\xff\xfe\xfd\xfc",
+ base64::decode(balloc, std::begin(in), std::end(in)).str());
}
{
// we check the number of valid input must be multiples of 4
std::string in = "//79=";
auto out = base64::decode(std::begin(in), std::end(in));
- CU_ASSERT("" == out);
- CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
+ assert_stdstring_equal("", out);
+ assert_stdstring_equal(
+ "", base64::decode(balloc, std::begin(in), std::end(in)).str());
}
{
// ending invalid character at the boundary of multiples of 4 is
// bad
std::string in = "bmdodHRw\n";
auto out = base64::decode(std::begin(in), std::end(in));
- CU_ASSERT("" == out);
- CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
+ assert_stdstring_equal("", out);
+ assert_stdstring_equal(
+ "", base64::decode(balloc, std::begin(in), std::end(in)).str());
}
{
// after seeing '=', subsequent input must be also '='.
std::string in = "//79/A=A";
auto out = base64::decode(std::begin(in), std::end(in));
- CU_ASSERT("" == out);
- CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
+ assert_stdstring_equal("", out);
+ assert_stdstring_equal(
+ "", base64::decode(balloc, std::begin(in), std::end(in)).str());
}
{
// additional '=' at the end is bad
std::string in = "//79/A======";
auto out = base64::decode(std::begin(in), std::end(in));
- CU_ASSERT("" == out);
- CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
+ assert_stdstring_equal("", out);
+ assert_stdstring_equal(
+ "", base64::decode(balloc, std::begin(in), std::end(in)).str());
}
}
diff --git a/src/base64_test.h b/src/base64_test.h
index 8bdb84f..fd74f27 100644
--- a/src/base64_test.h
+++ b/src/base64_test.h
@@ -29,10 +29,16 @@
# include <config.h>
#endif // HAVE_CONFIG_H
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
namespace nghttp2 {
-void test_base64_encode(void);
-void test_base64_decode(void);
+extern const MunitSuite base64_suite;
+
+munit_void_test_decl(test_base64_encode);
+munit_void_test_decl(test_base64_decode);
} // namespace nghttp2
diff --git a/src/buffer_test.cc b/src/buffer_test.cc
index 38688ed..2079086 100644
--- a/src/buffer_test.cc
+++ b/src/buffer_test.cc
@@ -28,7 +28,7 @@
#include <iostream>
#include <tuple>
-#include <CUnit/CUnit.h>
+#include "munitxx.h"
#include <nghttp2/nghttp2.h>
@@ -36,43 +36,54 @@
namespace nghttp2 {
+namespace {
+const MunitTest tests[]{
+ munit_void_test(test_buffer_write),
+ munit_test_end(),
+};
+} // namespace
+
+const MunitSuite buffer_suite{
+ "/buffer", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
void test_buffer_write(void) {
Buffer<16> b;
- CU_ASSERT(0 == b.rleft());
- CU_ASSERT(16 == b.wleft());
+ assert_size(0, ==, b.rleft());
+ assert_size(16, ==, b.wleft());
b.write("012", 3);
- CU_ASSERT(3 == b.rleft());
- CU_ASSERT(13 == b.wleft());
- CU_ASSERT(b.pos == std::begin(b.buf));
+ assert_size(3, ==, b.rleft());
+ assert_size(13, ==, b.wleft());
+ assert_ptr_equal(b.pos, std::begin(b.buf));
b.drain(3);
- CU_ASSERT(0 == b.rleft());
- CU_ASSERT(13 == b.wleft());
- CU_ASSERT(3 == b.pos - std::begin(b.buf));
+ assert_size(0, ==, b.rleft());
+ assert_size(13, ==, b.wleft());
+ assert_ptrdiff(3, ==, b.pos - std::begin(b.buf));
auto n = b.write("0123456789ABCDEF", 16);
- CU_ASSERT(n == 13);
+ assert_ssize(13, ==, n);
- CU_ASSERT(13 == b.rleft());
- CU_ASSERT(0 == b.wleft());
- CU_ASSERT(3 == b.pos - std::begin(b.buf));
- CU_ASSERT(0 == memcmp(b.pos, "0123456789ABC", 13));
+ assert_size(13, ==, b.rleft());
+ assert_size(0, ==, b.wleft());
+ assert_ptrdiff(3, ==, b.pos - std::begin(b.buf));
+ assert_memory_equal(13, b.pos, "0123456789ABC");
b.reset();
- CU_ASSERT(0 == b.rleft());
- CU_ASSERT(16 == b.wleft());
- CU_ASSERT(b.pos == std::begin(b.buf));
+ assert_size(0, ==, b.rleft());
+ assert_size(16, ==, b.wleft());
+ assert_ptr_equal(b.pos, std::begin(b.buf));
b.write(5);
- CU_ASSERT(5 == b.rleft());
- CU_ASSERT(11 == b.wleft());
- CU_ASSERT(b.pos == std::begin(b.buf));
+ assert_size(5, ==, b.rleft());
+ assert_size(11, ==, b.wleft());
+ assert_ptr_equal(b.pos, std::begin(b.buf));
}
} // namespace nghttp2
diff --git a/src/buffer_test.h b/src/buffer_test.h
index 6789aa3..4fb004f 100644
--- a/src/buffer_test.h
+++ b/src/buffer_test.h
@@ -29,9 +29,15 @@
# include <config.h>
#endif // HAVE_CONFIG_H
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
namespace nghttp2 {
-void test_buffer_write(void);
+extern const MunitSuite buffer_suite;
+
+munit_void_test_decl(test_buffer_write);
} // namespace nghttp2
diff --git a/src/deflatehd.cc b/src/deflatehd.cc
index 7dcfccf..ad472de 100644
--- a/src/deflatehd.cc
+++ b/src/deflatehd.cc
@@ -41,6 +41,7 @@
#include <jansson.h>
+#define NGHTTP2_NO_SSIZE_T
#include <nghttp2/nghttp2.h>
#include "template.h"
@@ -113,11 +114,10 @@ static void output_to_json(nghttp2_hd_deflater *deflater, const uint8_t *buf,
static void deflate_hd(nghttp2_hd_deflater *deflater,
const std::vector<nghttp2_nv> &nva, size_t inputlen,
int seq) {
- ssize_t rv;
std::array<uint8_t, 64_k> buf;
- rv = nghttp2_hd_deflate_hd(deflater, buf.data(), buf.size(),
- (nghttp2_nv *)nva.data(), nva.size());
+ auto rv = nghttp2_hd_deflate_hd2(deflater, buf.data(), buf.size(),
+ (nghttp2_nv *)nva.data(), nva.size());
if (rv < 0) {
fprintf(stderr, "deflate failed with error code %zd at %d\n", rv, seq);
exit(EXIT_FAILURE);
diff --git a/src/h2load.cc b/src/h2load.cc
index 0f07610..8136a9f 100644
--- a/src/h2load.cc
+++ b/src/h2load.cc
@@ -410,7 +410,7 @@ namespace {
void client_request_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
auto client = static_cast<Client *>(w->data);
- if (client->streams.size() >= (size_t)config.max_concurrent_streams) {
+ if (client->streams.size() >= config.max_concurrent_streams) {
ev_timer_stop(client->worker->loop, w);
return;
}
@@ -582,8 +582,12 @@ int Client::make_socket(addrinfo *addr) {
}
}
- if (ssl && !util::numeric_host(config.host.c_str())) {
- SSL_set_tlsext_host_name(ssl, config.host.c_str());
+ if (ssl) {
+ if (!config.sni.empty()) {
+ SSL_set_tlsext_host_name(ssl, config.sni.c_str());
+ } else if (!util::numeric_host(config.host.c_str())) {
+ SSL_set_tlsext_host_name(ssl, config.host.c_str());
+ }
}
if (config.is_quic()) {
@@ -2301,6 +2305,9 @@ Options:
--max-udp-payload-size=<SIZE>
Specify the maximum outgoing UDP datagram payload size.
--ktls Enable ktls.
+ --sni=<DNSNAME>
+ Send <DNSNAME> in TLS SNI, overriding the host name
+ specified in URI.
-v, --verbose
Output debug information.
--version Display version information and exit.
@@ -2363,6 +2370,7 @@ int main(int argc, char **argv) {
{"max-udp-payload-size", required_argument, &flag, 17},
{"ktls", no_argument, &flag, 18},
{"alpn-list", required_argument, &flag, 19},
+ {"sni", required_argument, &flag, 20},
{nullptr, 0, nullptr, 0}};
int option_index = 0;
auto c = getopt_long(argc, argv,
@@ -2699,6 +2707,10 @@ int main(int argc, char **argv) {
// alpn-list option
config.alpn_list = util::parse_config_str_list(StringRef{optarg});
break;
+ case 20:
+ // --sni
+ config.sni = optarg;
+ break;
}
break;
default:
@@ -2973,6 +2985,15 @@ int main(int argc, char **argv) {
}
}
+#if defined(NGHTTP2_OPENSSL_IS_BORINGSSL) && defined(HAVE_LIBBROTLI)
+ if (!SSL_CTX_add_cert_compression_alg(
+ ssl_ctx, nghttp2::tls::CERTIFICATE_COMPRESSION_ALGO_BROTLI,
+ nghttp2::tls::cert_compress, nghttp2::tls::cert_decompress)) {
+ std::cerr << "SSL_CTX_add_cert_compression_alg failed" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+#endif // NGHTTP2_OPENSSL_IS_BORINGSSL && HAVE_LIBBROTLI
+
std::string user_agent = "h2load nghttp2/" NGHTTP2_VERSION;
Headers shared_nva;
shared_nva.emplace_back(":scheme", config.scheme);
@@ -3079,18 +3100,18 @@ int main(int argc, char **argv) {
#ifndef NOTHREADS
size_t nreqs_per_thread = 0;
- ssize_t nreqs_rem = 0;
+ size_t nreqs_rem = 0;
if (!config.timing_script) {
nreqs_per_thread = config.nreqs / config.nthreads;
nreqs_rem = config.nreqs % config.nthreads;
}
- size_t nclients_per_thread = config.nclients / config.nthreads;
- ssize_t nclients_rem = config.nclients % config.nthreads;
+ auto nclients_per_thread = config.nclients / config.nthreads;
+ auto nclients_rem = config.nclients % config.nthreads;
- size_t rate_per_thread = config.rate / config.nthreads;
- ssize_t rate_per_thread_rem = config.rate % config.nthreads;
+ auto rate_per_thread = config.rate / config.nthreads;
+ auto rate_per_thread_rem = config.rate % config.nthreads;
size_t max_samples_per_thread =
std::max(static_cast<size_t>(256), MAX_SAMPLES / config.nthreads);
diff --git a/src/h2load.h b/src/h2load.h
index 11bb54c..860bf77 100644
--- a/src/h2load.h
+++ b/src/h2load.h
@@ -43,6 +43,7 @@
#include <chrono>
#include <array>
+#define NGHTTP2_NO_SSIZE_T
#include <nghttp2/nghttp2.h>
#ifdef ENABLE_HTTP3
@@ -92,7 +93,7 @@ struct Config {
size_t nclients;
size_t nthreads;
// The maximum number of concurrent streams per session.
- ssize_t max_concurrent_streams;
+ size_t max_concurrent_streams;
size_t window_bits;
size_t connection_window_bits;
size_t max_frame_size;
@@ -138,6 +139,9 @@ struct Config {
size_t max_udp_payload_size;
// Enable ktls.
bool ktls;
+ // sni is the value sent in TLS SNI, overriding DNS name of the
+ // remote host.
+ std::string sni;
Config();
~Config();
diff --git a/src/h2load_http2_session.cc b/src/h2load_http2_session.cc
index b058a33..6e810ab 100644
--- a/src/h2load_http2_session.cc
+++ b/src/h2load_http2_session.cc
@@ -124,9 +124,10 @@ int before_frame_send_callback(nghttp2_session *session,
} // namespace
namespace {
-ssize_t file_read_callback(nghttp2_session *session, int32_t stream_id,
- uint8_t *buf, size_t length, uint32_t *data_flags,
- nghttp2_data_source *source, void *user_data) {
+nghttp2_ssize file_read_callback(nghttp2_session *session, int32_t stream_id,
+ uint8_t *buf, size_t length,
+ uint32_t *data_flags,
+ nghttp2_data_source *source, void *user_data) {
auto client = static_cast<Client *>(user_data);
auto config = client->worker->config;
auto req_stat = client->get_req_stat(stream_id);
@@ -158,8 +159,8 @@ ssize_t file_read_callback(nghttp2_session *session, int32_t stream_id,
} // namespace
namespace {
-ssize_t send_callback(nghttp2_session *session, const uint8_t *data,
- size_t length, int flags, void *user_data) {
+nghttp2_ssize send_callback(nghttp2_session *session, const uint8_t *data,
+ size_t length, int flags, void *user_data) {
auto client = static_cast<Client *>(user_data);
auto &wb = client->wb;
@@ -198,7 +199,7 @@ void Http2Session::on_connect() {
nghttp2_session_callbacks_set_before_frame_send_callback(
callbacks, before_frame_send_callback);
- nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
+ nghttp2_session_callbacks_set_send_callback2(callbacks, send_callback);
nghttp2_option *opt;
@@ -257,11 +258,11 @@ int Http2Session::submit_request() {
client_->reqidx = 0;
}
- nghttp2_data_provider prd{{0}, file_read_callback};
+ nghttp2_data_provider2 prd{{0}, file_read_callback};
auto stream_id =
- nghttp2_submit_request(session_, nullptr, nva.data(), nva.size(),
- config->data_fd == -1 ? nullptr : &prd, nullptr);
+ nghttp2_submit_request2(session_, nullptr, nva.data(), nva.size(),
+ config->data_fd == -1 ? nullptr : &prd, nullptr);
if (stream_id < 0) {
return -1;
}
@@ -272,7 +273,7 @@ int Http2Session::submit_request() {
}
int Http2Session::on_read(const uint8_t *data, size_t len) {
- auto rv = nghttp2_session_mem_recv(session_, data, len);
+ auto rv = nghttp2_session_mem_recv2(session_, data, len);
if (rv < 0) {
return -1;
}
@@ -308,7 +309,7 @@ void Http2Session::terminate() {
}
size_t Http2Session::max_concurrent_streams() {
- return (size_t)client_->worker->config->max_concurrent_streams;
+ return client_->worker->config->max_concurrent_streams;
}
} // namespace h2load
diff --git a/src/h2load_http3_session.cc b/src/h2load_http3_session.cc
index d491cba..03a2233 100644
--- a/src/h2load_http3_session.cc
+++ b/src/h2load_http3_session.cc
@@ -124,7 +124,7 @@ int Http3Session::on_write() { return -1; }
void Http3Session::terminate() {}
size_t Http3Session::max_concurrent_streams() {
- return (size_t)client_->worker->config->max_concurrent_streams;
+ return client_->worker->config->max_concurrent_streams;
}
namespace {
diff --git a/src/h2load_quic.cc b/src/h2load_quic.cc
index e492a3e..8b3c552 100644
--- a/src/h2load_quic.cc
+++ b/src/h2load_quic.cc
@@ -654,7 +654,8 @@ int Client::write_quic() {
ngtcp2_conn_get_path_max_tx_udp_payload_size(quic.conn);
#endif // UDP_SEGMENT
auto max_pktcnt =
- ngtcp2_conn_get_send_quantum(quic.conn) / max_udp_payload_size;
+ std::max(ngtcp2_conn_get_send_quantum(quic.conn) / max_udp_payload_size,
+ static_cast<size_t>(1));
uint8_t *bufpos = quic.tx.data.get();
ngtcp2_path_storage ps;
size_t gso_size = 0;
diff --git a/src/http2_test.cc b/src/http2_test.cc
index f8be9f4..3cb0b71 100644
--- a/src/http2_test.cc
+++ b/src/http2_test.cc
@@ -28,7 +28,7 @@
#include <cstring>
#include <iostream>
-#include <CUnit/CUnit.h>
+#include "munitxx.h"
#include "url-parser/url_parser.h"
@@ -46,11 +46,38 @@ using namespace nghttp2;
namespace shrpx {
namespace {
+const MunitTest tests[]{
+ munit_void_test(test_http2_add_header),
+ munit_void_test(test_http2_get_header),
+ munit_void_test(test_http2_copy_headers_to_nva),
+ munit_void_test(test_http2_build_http1_headers_from_headers),
+ munit_void_test(test_http2_lws),
+ munit_void_test(test_http2_rewrite_location_uri),
+ munit_void_test(test_http2_parse_http_status_code),
+ munit_void_test(test_http2_index_header),
+ munit_void_test(test_http2_lookup_token),
+ munit_void_test(test_http2_parse_link_header),
+ munit_void_test(test_http2_path_join),
+ munit_void_test(test_http2_normalize_path),
+ munit_void_test(test_http2_rewrite_clean_path),
+ munit_void_test(test_http2_get_pure_path_component),
+ munit_void_test(test_http2_construct_push_component),
+ munit_void_test(test_http2_contains_trailers),
+ munit_void_test(test_http2_check_transfer_encoding),
+ munit_test_end(),
+};
+} // namespace
+
+const MunitSuite http2_suite{
+ "/http2", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
+namespace {
void check_nv(const HeaderRef &a, const nghttp2_nv *b) {
- CU_ASSERT(a.name.size() == b->namelen);
- CU_ASSERT(a.value.size() == b->valuelen);
- CU_ASSERT(memcmp(a.name.c_str(), b->name, b->namelen) == 0);
- CU_ASSERT(memcmp(a.value.c_str(), b->value, b->valuelen) == 0);
+ assert_size(a.name.size(), ==, b->namelen);
+ assert_size(a.value.size(), ==, b->valuelen);
+ assert_memory_equal(b->namelen, a.name.c_str(), b->name);
+ assert_memory_equal(b->valuelen, a.value.c_str(), b->value);
}
} // namespace
@@ -59,51 +86,51 @@ void test_http2_add_header(void) {
http2::add_header(nva, (const uint8_t *)"alpha", 5, (const uint8_t *)"123", 3,
false, -1);
- CU_ASSERT(Headers::value_type("alpha", "123") == nva[0]);
- CU_ASSERT(!nva[0].no_index);
+ assert_true(Headers::value_type("alpha", "123") == nva[0]);
+ assert_false(nva[0].no_index);
nva.clear();
http2::add_header(nva, (const uint8_t *)"alpha", 5, (const uint8_t *)"", 0,
true, -1);
- CU_ASSERT(Headers::value_type("alpha", "") == nva[0]);
- CU_ASSERT(nva[0].no_index);
+ assert_true(Headers::value_type("alpha", "") == nva[0]);
+ assert_true(nva[0].no_index);
nva.clear();
http2::add_header(nva, (const uint8_t *)"a", 1, (const uint8_t *)" b", 2,
false, -1);
- CU_ASSERT(Headers::value_type("a", "b") == nva[0]);
+ assert_true(Headers::value_type("a", "b") == nva[0]);
nva.clear();
http2::add_header(nva, (const uint8_t *)"a", 1, (const uint8_t *)"b ", 2,
false, -1);
- CU_ASSERT(Headers::value_type("a", "b") == nva[0]);
+ assert_true(Headers::value_type("a", "b") == nva[0]);
nva.clear();
http2::add_header(nva, (const uint8_t *)"a", 1, (const uint8_t *)" b ", 5,
false, -1);
- CU_ASSERT(Headers::value_type("a", "b") == nva[0]);
+ assert_true(Headers::value_type("a", "b") == nva[0]);
nva.clear();
http2::add_header(nva, (const uint8_t *)"a", 1, (const uint8_t *)" bravo ",
9, false, -1);
- CU_ASSERT(Headers::value_type("a", "bravo") == nva[0]);
+ assert_true(Headers::value_type("a", "bravo") == nva[0]);
nva.clear();
http2::add_header(nva, (const uint8_t *)"a", 1, (const uint8_t *)" ", 4,
false, -1);
- CU_ASSERT(Headers::value_type("a", "") == nva[0]);
+ assert_true(Headers::value_type("a", "") == nva[0]);
nva.clear();
http2::add_header(nva, (const uint8_t *)"te", 2, (const uint8_t *)"trailers",
8, false, http2::HD_TE);
- CU_ASSERT(http2::HD_TE == nva[0].token);
+ assert_int32(http2::HD_TE, ==, nva[0].token);
}
void test_http2_get_header(void) {
@@ -112,21 +139,21 @@ void test_http2_get_header(void) {
{"content-length", "7"}};
const Headers::value_type *rv;
rv = http2::get_header(nva, "delta");
- CU_ASSERT(rv != nullptr);
- CU_ASSERT("delta" == rv->name);
+ assert_not_null(rv);
+ assert_stdstring_equal("delta", rv->name);
rv = http2::get_header(nva, "bravo");
- CU_ASSERT(rv != nullptr);
- CU_ASSERT("bravo" == rv->name);
+ assert_not_null(rv);
+ assert_stdstring_equal("bravo", rv->name);
rv = http2::get_header(nva, "foxtrot");
- CU_ASSERT(rv == nullptr);
+ assert_null(rv);
http2::HeaderIndex hdidx;
http2::init_hdidx(hdidx);
hdidx[http2::HD_CONTENT_LENGTH] = 6;
rv = http2::get_header(hdidx, http2::HD_CONTENT_LENGTH, nva);
- CU_ASSERT("content-length" == rv->name);
+ assert_stdstring_equal("content-length", rv->name);
}
namespace {
@@ -177,29 +204,31 @@ void test_http2_copy_headers_to_nva(void) {
http2::copy_headers_to_nva_nocopy(nva, headers,
http2::HDOP_STRIP_X_FORWARDED_FOR);
- CU_ASSERT(7 == nva.size());
+ assert_size(7, ==, nva.size());
for (size_t i = 0; i < ans.size(); ++i) {
check_nv(headers[ans[i]], &nva[i]);
if (ans[i] == 0) {
- CU_ASSERT((NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE |
- NGHTTP2_NV_FLAG_NO_INDEX) == nva[i].flags);
+ assert_uint8((NGHTTP2_NV_FLAG_NO_COPY_NAME |
+ NGHTTP2_NV_FLAG_NO_COPY_VALUE | NGHTTP2_NV_FLAG_NO_INDEX),
+ ==, nva[i].flags);
} else {
- CU_ASSERT((NGHTTP2_NV_FLAG_NO_COPY_NAME |
- NGHTTP2_NV_FLAG_NO_COPY_VALUE) == nva[i].flags);
+ assert_uint8(
+ (NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE), ==,
+ nva[i].flags);
}
}
nva.clear();
http2::copy_headers_to_nva(nva, headers, http2::HDOP_STRIP_X_FORWARDED_FOR);
- CU_ASSERT(7 == nva.size());
+ assert_size(7, ==, nva.size());
for (size_t i = 0; i < ans.size(); ++i) {
check_nv(headers[ans[i]], &nva[i]);
if (ans[i] == 0) {
- CU_ASSERT(nva[i].flags & NGHTTP2_NV_FLAG_NO_INDEX);
+ assert_true(nva[i].flags & NGHTTP2_NV_FLAG_NO_INDEX);
} else {
- CU_ASSERT(NGHTTP2_NV_FLAG_NONE == nva[i].flags);
+ assert_false(nva[i].flags);
}
}
@@ -207,7 +236,7 @@ void test_http2_copy_headers_to_nva(void) {
auto ans2 = std::vector<int>{0, 2, 4, 6};
http2::copy_headers_to_nva(nva, headers2, http2::HDOP_NONE);
- CU_ASSERT(ans2.size() == nva.size());
+ assert_size(ans2.size(), ==, nva.size());
for (size_t i = 0; i < ans2.size(); ++i) {
check_nv(headers2[ans2[i]], &nva[i]);
}
@@ -215,7 +244,7 @@ void test_http2_copy_headers_to_nva(void) {
nva.clear();
http2::copy_headers_to_nva(nva, headers2, http2::HDOP_STRIP_ALL);
- CU_ASSERT(nva.empty());
+ assert_true(nva.empty());
}
void test_http2_build_http1_headers_from_headers(void) {
@@ -224,36 +253,38 @@ void test_http2_build_http1_headers_from_headers(void) {
http2::build_http1_headers_from_headers(&buf, headers,
http2::HDOP_STRIP_X_FORWARDED_FOR);
auto hdrs = std::string(buf.head->pos, buf.head->last);
- CU_ASSERT("Alpha: 0\r\n"
- "Bravo: 1\r\n"
- "Delta: 4\r\n"
- "Expect: 5\r\n"
- "Foxtrot: 6\r\n"
- "Tango: 7\r\n"
- "Te: 8\r\n"
- "Te: 9\r\n"
- "Zulu: 12\r\n" == hdrs);
+ assert_stdstring_equal("Alpha: 0\r\n"
+ "Bravo: 1\r\n"
+ "Delta: 4\r\n"
+ "Expect: 5\r\n"
+ "Foxtrot: 6\r\n"
+ "Tango: 7\r\n"
+ "Te: 8\r\n"
+ "Te: 9\r\n"
+ "Zulu: 12\r\n",
+ hdrs);
buf.reset();
http2::build_http1_headers_from_headers(&buf, headers2, http2::HDOP_NONE);
hdrs = std::string(buf.head->pos, buf.head->last);
- CU_ASSERT("X-Forwarded-For: xff1\r\n"
- "X-Forwarded-Proto: xfp1\r\n"
- "Forwarded: fwd1\r\n"
- "Via: via1\r\n" == hdrs);
+ assert_stdstring_equal("X-Forwarded-For: xff1\r\n"
+ "X-Forwarded-Proto: xfp1\r\n"
+ "Forwarded: fwd1\r\n"
+ "Via: via1\r\n",
+ hdrs);
buf.reset();
http2::build_http1_headers_from_headers(&buf, headers2,
http2::HDOP_STRIP_ALL);
- CU_ASSERT(0 == buf.rleft());
+ assert_size(0, ==, buf.rleft());
}
void test_http2_lws(void) {
- CU_ASSERT(!http2::lws("alpha"));
- CU_ASSERT(http2::lws(" "));
- CU_ASSERT(http2::lws(""));
+ assert_false(http2::lws("alpha"));
+ assert_true(http2::lws(" "));
+ assert_true(http2::lws(""));
}
namespace {
@@ -263,11 +294,11 @@ void check_rewrite_location_uri(const std::string &want, const std::string &uri,
const std::string &upstream_scheme) {
BlockAllocator balloc(4096, 4096);
http_parser_url u{};
- CU_ASSERT(0 == http_parser_parse_url(uri.c_str(), uri.size(), 0, &u));
+ assert_int(0, ==, http_parser_parse_url(uri.c_str(), uri.size(), 0, &u));
auto got = http2::rewrite_location_uri(
balloc, StringRef{uri}, u, StringRef{match_host},
StringRef{req_authority}, StringRef{upstream_scheme});
- CU_ASSERT(want == got);
+ assert_stdstring_equal(want, got.str());
}
} // namespace
@@ -299,13 +330,15 @@ void test_http2_rewrite_location_uri(void) {
}
void test_http2_parse_http_status_code(void) {
- CU_ASSERT(200 == http2::parse_http_status_code(StringRef::from_lit("200")));
- CU_ASSERT(102 == http2::parse_http_status_code(StringRef::from_lit("102")));
- CU_ASSERT(-1 == http2::parse_http_status_code(StringRef::from_lit("099")));
- CU_ASSERT(-1 == http2::parse_http_status_code(StringRef::from_lit("99")));
- CU_ASSERT(-1 == http2::parse_http_status_code(StringRef::from_lit("-1")));
- CU_ASSERT(-1 == http2::parse_http_status_code(StringRef::from_lit("20a")));
- CU_ASSERT(-1 == http2::parse_http_status_code(StringRef{}));
+ assert_int(200, ==,
+ http2::parse_http_status_code(StringRef::from_lit("200")));
+ assert_int(102, ==,
+ http2::parse_http_status_code(StringRef::from_lit("102")));
+ assert_int(-1, ==, http2::parse_http_status_code(StringRef::from_lit("099")));
+ assert_int(-1, ==, http2::parse_http_status_code(StringRef::from_lit("99")));
+ assert_int(-1, ==, http2::parse_http_status_code(StringRef::from_lit("-1")));
+ assert_int(-1, ==, http2::parse_http_status_code(StringRef::from_lit("20a")));
+ assert_int(-1, ==, http2::parse_http_status_code(StringRef{}));
}
void test_http2_index_header(void) {
@@ -315,402 +348,402 @@ void test_http2_index_header(void) {
http2::index_header(hdidx, http2::HD__AUTHORITY, 0);
http2::index_header(hdidx, -1, 1);
- CU_ASSERT(0 == hdidx[http2::HD__AUTHORITY]);
+ assert_uint16(0, ==, hdidx[http2::HD__AUTHORITY]);
}
void test_http2_lookup_token(void) {
- CU_ASSERT(http2::HD__AUTHORITY ==
- http2::lookup_token(StringRef::from_lit(":authority")));
- CU_ASSERT(-1 == http2::lookup_token(StringRef::from_lit(":authorit")));
- CU_ASSERT(-1 == http2::lookup_token(StringRef::from_lit(":Authority")));
- CU_ASSERT(http2::HD_EXPECT ==
- http2::lookup_token(StringRef::from_lit("expect")));
+ assert_int(http2::HD__AUTHORITY, ==,
+ http2::lookup_token(StringRef::from_lit(":authority")));
+ assert_int(-1, ==, http2::lookup_token(StringRef::from_lit(":authorit")));
+ assert_int(-1, ==, http2::lookup_token(StringRef::from_lit(":Authority")));
+ assert_int(http2::HD_EXPECT, ==,
+ http2::lookup_token(StringRef::from_lit("expect")));
}
void test_http2_parse_link_header(void) {
{
// only URI appears; we don't extract URI unless it bears rel=preload
auto res = http2::parse_link_header(StringRef::from_lit("<url>"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// URI url should be extracted
auto res =
http2::parse_link_header(StringRef::from_lit("<url>; rel=preload"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// With extra link-param. URI url should be extracted
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; rel=preload; as=file"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// With extra link-param. URI url should be extracted
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; as=file; rel=preload"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// With extra link-param and quote-string. URI url should be
// extracted
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel=preload; title="foo,bar")"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// With extra link-param and quote-string. URI url should be
// extracted
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; title="foo,bar"; rel=preload)"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// ',' after quote-string
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; title="foo,bar", <url2>; rel=preload)"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url2" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url2", res[0].uri.str());
}
{
// Only first URI should be extracted.
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; rel=preload, <url2>"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// Both have rel=preload, so both urls should be extracted
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; rel=preload, <url2>; rel=preload"));
- CU_ASSERT(2 == res.size());
- CU_ASSERT("url" == res[0].uri);
- CU_ASSERT("url2" == res[1].uri);
+ assert_size(2, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
+ assert_stdstring_equal("url2", res[1].uri.str());
}
{
// Second URI uri should be extracted.
auto res = http2::parse_link_header(
StringRef::from_lit("<url>, <url2>;rel=preload"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url2" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url2", res[0].uri.str());
}
{
// Error if input ends with ';'
auto res =
http2::parse_link_header(StringRef::from_lit("<url>;rel=preload;"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// Error if link header ends with ';'
auto res = http2::parse_link_header(
StringRef::from_lit("<url>;rel=preload;, <url>"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// OK if input ends with ','
auto res =
http2::parse_link_header(StringRef::from_lit("<url>;rel=preload,"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// Multiple repeated ','s between fields is OK
auto res = http2::parse_link_header(
StringRef::from_lit("<url>,,,<url2>;rel=preload"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url2" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url2", res[0].uri.str());
}
{
// Error if url is not enclosed by <>
auto res =
http2::parse_link_header(StringRef::from_lit("url>;rel=preload"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// Error if url is not enclosed by <>
auto res =
http2::parse_link_header(StringRef::from_lit("<url;rel=preload"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// Empty parameter value is not allowed
auto res =
http2::parse_link_header(StringRef::from_lit("<url>;rel=preload; as="));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// Empty parameter value is not allowed
auto res =
http2::parse_link_header(StringRef::from_lit("<url>;as=;rel=preload"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// Empty parameter value is not allowed
auto res = http2::parse_link_header(
StringRef::from_lit("<url>;as=, <url>;rel=preload"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// Empty parameter name is not allowed
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; =file; rel=preload"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// Without whitespaces
auto res = http2::parse_link_header(
StringRef::from_lit("<url>;as=file;rel=preload,<url2>;rel=preload"));
- CU_ASSERT(2 == res.size());
- CU_ASSERT("url" == res[0].uri);
- CU_ASSERT("url2" == res[1].uri);
+ assert_size(2, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
+ assert_stdstring_equal("url2", res[1].uri.str());
}
{
// link-extension may have no value
auto res =
http2::parse_link_header(StringRef::from_lit("<url>; as; rel=preload"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// ext-name-star
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; foo*=bar; rel=preload"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// '*' is not allowed expect for trailing one
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; *=bar; rel=preload"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// '*' is not allowed expect for trailing one
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; foo*bar=buzz; rel=preload"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// ext-name-star must be followed by '='
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; foo*; rel=preload"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// '>' is not followed by ';'
auto res =
http2::parse_link_header(StringRef::from_lit("<url> rel=preload"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// Starting with whitespace is no problem.
auto res =
http2::parse_link_header(StringRef::from_lit(" <url>; rel=preload"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// preload is a prefix of bogus rel parameter value
auto res =
http2::parse_link_header(StringRef::from_lit("<url>; rel=preloadx"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// preload in relation-types list
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel="preload")"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// preload in relation-types list followed by another parameter
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel="preload foo")"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// preload in relation-types list following another parameter
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel="foo preload")"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// preload in relation-types list between other parameters
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel="foo preload bar")"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// preload in relation-types list between other parameters
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel="foo preload bar")"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// no preload in relation-types list
auto res =
http2::parse_link_header(StringRef::from_lit(R"(<url>; rel="foo")"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// no preload in relation-types list, multiple unrelated elements.
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel="foo bar")"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// preload in relation-types list, followed by another link-value.
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel="preload", <url2>)"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// preload in relation-types list, following another link-value.
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>, <url2>; rel="preload")"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url2" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url2", res[0].uri.str());
}
{
// preload in relation-types list, followed by another link-param.
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel="preload"; as="font")"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// preload in relation-types list, followed by character other
// than ';' or ','
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel="preload".)"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// preload in relation-types list, followed by ';' but it
// terminates input
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel="preload";)"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// preload in relation-types list, followed by ',' but it
// terminates input
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel="preload",)"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// preload in relation-types list but there is preceding white
// space.
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel=" preload")"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// preload in relation-types list but there is trailing white
// space.
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel="preload ")"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// backslash escaped characters in quoted-string
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel=preload; title="foo\"baz\"bar")"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// anchor="" is acceptable
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel=preload; anchor="")"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// With anchor="#foo", url should be ignored
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel=preload; anchor="#foo")"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// With anchor=f, url should be ignored
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; rel=preload; anchor=f"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// First url is ignored With anchor="#foo", but url should be
// accepted.
auto res = http2::parse_link_header(StringRef::from_lit(
R"(<url>; rel=preload; anchor="#foo", <url2>; rel=preload)"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url2" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url2", res[0].uri.str());
}
{
// With loadpolicy="next", url should be ignored
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel=preload; loadpolicy="next")"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// url should be picked up if empty loadpolicy is specified
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel=preload; loadpolicy="")"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// case-insensitive match
auto res = http2::parse_link_header(
StringRef::from_lit(R"(<url>; rel=preload; ANCHOR="#foo", <url2>; )"
R"(REL=PRELOAD, <url3>; REL="foo PRELOAD bar")"));
- CU_ASSERT(2 == res.size());
- CU_ASSERT("url2" == res[0].uri);
- CU_ASSERT("url3" == res[1].uri);
+ assert_size(2, ==, res.size());
+ assert_stdstring_equal("url2", res[0].uri.str());
+ assert_stdstring_equal("url3", res[1].uri.str());
}
{
// nopush at the end of input
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; rel=preload; nopush"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// nopush followed by ';'
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; rel=preload; nopush; foo"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// nopush followed by ','
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; nopush; rel=preload"));
- CU_ASSERT(0 == res.size());
+ assert_size(0, ==, res.size());
}
{
// string whose prefix is nopush
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; nopushyes; rel=preload"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
{
// rel=preload twice
auto res = http2::parse_link_header(
StringRef::from_lit("<url>; rel=preload; rel=preload"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("url" == res[0].uri);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("url", res[0].uri.str());
}
}
@@ -718,124 +751,132 @@ void test_http2_path_join(void) {
{
auto base = StringRef::from_lit("/");
auto rel = StringRef::from_lit("/");
- CU_ASSERT("/" == http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
auto base = StringRef::from_lit("/");
auto rel = StringRef::from_lit("/alpha");
- CU_ASSERT("/alpha" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/alpha", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// rel ends with trailing '/'
auto base = StringRef::from_lit("/");
auto rel = StringRef::from_lit("/alpha/");
- CU_ASSERT("/alpha/" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/alpha/", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// rel contains multiple components
auto base = StringRef::from_lit("/");
auto rel = StringRef::from_lit("/alpha/bravo");
- CU_ASSERT("/alpha/bravo" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/alpha/bravo", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// rel is relative
auto base = StringRef::from_lit("/");
auto rel = StringRef::from_lit("alpha/bravo");
- CU_ASSERT("/alpha/bravo" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/alpha/bravo", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// rel is relative and base ends without /, which means it refers
// to file.
auto base = StringRef::from_lit("/alpha");
auto rel = StringRef::from_lit("bravo/charlie");
- CU_ASSERT("/bravo/charlie" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/bravo/charlie",
+ http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// rel contains repeated '/'s
auto base = StringRef::from_lit("/");
auto rel = StringRef::from_lit("/alpha/////bravo/////");
- CU_ASSERT("/alpha/bravo/" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/alpha/bravo/", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// base ends with '/', so '..' eats 'bravo'
auto base = StringRef::from_lit("/alpha/bravo/");
auto rel = StringRef::from_lit("../charlie/delta");
- CU_ASSERT("/alpha/charlie/delta" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/alpha/charlie/delta",
+ http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// base does not end with '/', so '..' eats 'alpha/bravo'
auto base = StringRef::from_lit("/alpha/bravo");
auto rel = StringRef::from_lit("../charlie");
- CU_ASSERT("/charlie" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/charlie", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// 'charlie' is eaten by following '..'
auto base = StringRef::from_lit("/alpha/bravo/");
auto rel = StringRef::from_lit("../charlie/../delta");
- CU_ASSERT("/alpha/delta" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/alpha/delta", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// excessive '..' results in '/'
auto base = StringRef::from_lit("/alpha/bravo/");
auto rel = StringRef::from_lit("../../../");
- CU_ASSERT("/" == http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// excessive '..' and path component
auto base = StringRef::from_lit("/alpha/bravo/");
auto rel = StringRef::from_lit("../../../charlie");
- CU_ASSERT("/charlie" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/charlie", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// rel ends with '..'
auto base = StringRef::from_lit("/alpha/bravo/");
auto rel = StringRef::from_lit("charlie/..");
- CU_ASSERT("/alpha/bravo/" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/alpha/bravo/", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// base empty and rel contains '..'
auto base = StringRef{};
auto rel = StringRef::from_lit("charlie/..");
- CU_ASSERT("/" == http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// '.' is ignored
auto base = StringRef::from_lit("/");
auto rel = StringRef::from_lit("charlie/././././delta");
- CU_ASSERT("/charlie/delta" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/charlie/delta",
+ http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// trailing '.' is ignored
auto base = StringRef::from_lit("/");
auto rel = StringRef::from_lit("charlie/.");
- CU_ASSERT("/charlie/" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/charlie/", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// query
auto base = StringRef::from_lit("/");
auto rel = StringRef::from_lit("/");
auto relq = StringRef::from_lit("q");
- CU_ASSERT("/?q" == http2::path_join(base, StringRef{}, rel, relq));
+ assert_stdstring_equal("/?q",
+ http2::path_join(base, StringRef{}, rel, relq));
}
{
// empty rel and query
auto base = StringRef::from_lit("/alpha");
auto rel = StringRef{};
auto relq = StringRef::from_lit("q");
- CU_ASSERT("/alpha?q" == http2::path_join(base, StringRef{}, rel, relq));
+ assert_stdstring_equal("/alpha?q",
+ http2::path_join(base, StringRef{}, rel, relq));
}
{
// both rel and query are empty
@@ -843,26 +884,28 @@ void test_http2_path_join(void) {
auto baseq = StringRef::from_lit("r");
auto rel = StringRef{};
auto relq = StringRef{};
- CU_ASSERT("/alpha?r" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/alpha?r",
+ http2::path_join(base, baseq, rel, relq));
}
{
// empty base
auto base = StringRef{};
auto rel = StringRef::from_lit("/alpha");
- CU_ASSERT("/alpha" ==
- http2::path_join(base, StringRef{}, rel, StringRef{}));
+ assert_stdstring_equal(
+ "/alpha", http2::path_join(base, StringRef{}, rel, StringRef{}));
}
{
// everything is empty
- CU_ASSERT("/" == http2::path_join(StringRef{}, StringRef{}, StringRef{},
- StringRef{}));
+ assert_stdstring_equal("/", http2::path_join(StringRef{}, StringRef{},
+ StringRef{}, StringRef{}));
}
{
// only baseq is not empty
auto base = StringRef{};
auto baseq = StringRef::from_lit("r");
auto rel = StringRef{};
- CU_ASSERT("/?r" == http2::path_join(base, baseq, rel, StringRef{}));
+ assert_stdstring_equal("/?r",
+ http2::path_join(base, baseq, rel, StringRef{}));
}
{
// path starts with multiple '/'s.
@@ -870,8 +913,8 @@ void test_http2_path_join(void) {
auto baseq = StringRef{};
auto rel = StringRef::from_lit("//alpha//bravo");
auto relq = StringRef::from_lit("charlie");
- CU_ASSERT("/alpha/bravo?charlie" ==
- http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/alpha/bravo?charlie",
+ http2::path_join(base, baseq, rel, relq));
}
// Test cases from RFC 3986, section 5.4.
constexpr auto base = StringRef::from_lit("/b/c/d;p");
@@ -879,239 +922,266 @@ void test_http2_path_join(void) {
{
auto rel = StringRef::from_lit("g");
auto relq = StringRef{};
- CU_ASSERT("/b/c/g" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/g", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("./g");
auto relq = StringRef{};
- CU_ASSERT("/b/c/g" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/g", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g/");
auto relq = StringRef{};
- CU_ASSERT("/b/c/g/" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/g/", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("/g");
auto relq = StringRef{};
- CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/g", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef{};
auto relq = StringRef::from_lit("y");
- CU_ASSERT("/b/c/d;p?y" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/d;p?y",
+ http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g");
auto relq = StringRef::from_lit("y");
- CU_ASSERT("/b/c/g?y" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/g?y",
+ http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit(";x");
auto relq = StringRef{};
- CU_ASSERT("/b/c/;x" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/;x", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g;x");
auto relq = StringRef{};
- CU_ASSERT("/b/c/g;x" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/g;x",
+ http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g;x");
auto relq = StringRef::from_lit("y");
- CU_ASSERT("/b/c/g;x?y" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/g;x?y",
+ http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef{};
auto relq = StringRef{};
- CU_ASSERT("/b/c/d;p?q" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/d;p?q",
+ http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit(".");
auto relq = StringRef{};
- CU_ASSERT("/b/c/" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("./");
auto relq = StringRef{};
- CU_ASSERT("/b/c/" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("..");
auto relq = StringRef{};
- CU_ASSERT("/b/" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../");
auto relq = StringRef{};
- CU_ASSERT("/b/" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../g");
auto relq = StringRef{};
- CU_ASSERT("/b/g" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/g", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../..");
auto relq = StringRef{};
- CU_ASSERT("/" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../../");
auto relq = StringRef{};
- CU_ASSERT("/" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../../g");
auto relq = StringRef{};
- CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/g", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../../../g");
auto relq = StringRef{};
- CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/g", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("../../../../g");
auto relq = StringRef{};
- CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/g", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("/./g");
auto relq = StringRef{};
- CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/g", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("/../g");
auto relq = StringRef{};
- CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/g", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g.");
auto relq = StringRef{};
- CU_ASSERT("/b/c/g." == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/g.", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit(".g");
auto relq = StringRef{};
- CU_ASSERT("/b/c/.g" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/.g", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g..");
auto relq = StringRef{};
- CU_ASSERT("/b/c/g.." == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/g..",
+ http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("..g");
auto relq = StringRef{};
- CU_ASSERT("/b/c/..g" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/..g",
+ http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("./../g");
auto relq = StringRef{};
- CU_ASSERT("/b/g" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/g", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("./g/.");
auto relq = StringRef{};
- CU_ASSERT("/b/c/g/" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/g/", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g/./h");
auto relq = StringRef{};
- CU_ASSERT("/b/c/g/h" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/g/h",
+ http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g/../h");
auto relq = StringRef{};
- CU_ASSERT("/b/c/h" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/h", http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g;x=1/./y");
auto relq = StringRef{};
- CU_ASSERT("/b/c/g;x=1/y" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/g;x=1/y",
+ http2::path_join(base, baseq, rel, relq));
}
{
auto rel = StringRef::from_lit("g;x=1/../y");
auto relq = StringRef{};
- CU_ASSERT("/b/c/y" == http2::path_join(base, baseq, rel, relq));
+ assert_stdstring_equal("/b/c/y", http2::path_join(base, baseq, rel, relq));
}
}
void test_http2_normalize_path(void) {
- CU_ASSERT("/alpha/charlie" ==
- http2::normalize_path(
- StringRef::from_lit("/alpha/bravo/../charlie"), StringRef{}));
+ assert_stdstring_equal(
+ "/alpha/charlie",
+ http2::normalize_path(StringRef::from_lit("/alpha/bravo/../charlie"),
+ StringRef{}));
- CU_ASSERT("/alpha" ==
- http2::normalize_path(StringRef::from_lit("/a%6c%70%68%61"),
- StringRef{}));
+ assert_stdstring_equal(
+ "/alpha", http2::normalize_path(StringRef::from_lit("/a%6c%70%68%61"),
+ StringRef{}));
- CU_ASSERT(
- "/alpha%2F%3A" ==
+ assert_stdstring_equal(
+ "/alpha%2F%3A",
http2::normalize_path(StringRef::from_lit("/alpha%2f%3a"), StringRef{}));
- CU_ASSERT("/%2F" ==
- http2::normalize_path(StringRef::from_lit("%2f"), StringRef{}));
+ assert_stdstring_equal(
+ "/%2F", http2::normalize_path(StringRef::from_lit("%2f"), StringRef{}));
- CU_ASSERT("/%f" ==
- http2::normalize_path(StringRef::from_lit("%f"), StringRef{}));
+ assert_stdstring_equal(
+ "/%f", http2::normalize_path(StringRef::from_lit("%f"), StringRef{}));
- CU_ASSERT("/%" ==
- http2::normalize_path(StringRef::from_lit("%"), StringRef{}));
+ assert_stdstring_equal(
+ "/%", http2::normalize_path(StringRef::from_lit("%"), StringRef{}));
- CU_ASSERT("/" == http2::normalize_path(StringRef{}, StringRef{}));
+ assert_stdstring_equal("/", http2::normalize_path(StringRef{}, StringRef{}));
- CU_ASSERT("/alpha?bravo" ==
- http2::normalize_path(StringRef::from_lit("/alpha"),
- StringRef::from_lit("bravo")));
+ assert_stdstring_equal("/alpha?bravo",
+ http2::normalize_path(StringRef::from_lit("/alpha"),
+ StringRef::from_lit("bravo")));
}
void test_http2_rewrite_clean_path(void) {
BlockAllocator balloc(4096, 4096);
// unreserved characters
- CU_ASSERT("/alpha/bravo/" ==
- http2::rewrite_clean_path(balloc,
- StringRef::from_lit("/alpha/%62ravo/")));
+ assert_stdstring_equal(
+ "/alpha/bravo/",
+ http2::rewrite_clean_path(balloc, StringRef::from_lit("/alpha/%62ravo/"))
+ .str());
// percent-encoding is converted to upper case.
- CU_ASSERT("/delta%3A" == http2::rewrite_clean_path(
- balloc, StringRef::from_lit("/delta%3a")));
+ assert_stdstring_equal(
+ "/delta%3A",
+ http2::rewrite_clean_path(balloc, StringRef::from_lit("/delta%3a"))
+ .str());
// path component is normalized before matching
- CU_ASSERT(
- "/alpha/bravo/" ==
+ assert_stdstring_equal(
+ "/alpha/bravo/",
http2::rewrite_clean_path(
- balloc, StringRef::from_lit("/alpha/charlie/%2e././bravo/delta/..")));
+ balloc, StringRef::from_lit("/alpha/charlie/%2e././bravo/delta/.."))
+ .str());
- CU_ASSERT("alpha%3a" ==
- http2::rewrite_clean_path(balloc, StringRef::from_lit("alpha%3a")));
+ assert_stdstring_equal(
+ "alpha%3a",
+ http2::rewrite_clean_path(balloc, StringRef::from_lit("alpha%3a")).str());
- CU_ASSERT("" == http2::rewrite_clean_path(balloc, StringRef{}));
+ assert_stdstring_equal("",
+ http2::rewrite_clean_path(balloc, StringRef{}).str());
- CU_ASSERT(
- "/alpha?bravo" ==
- http2::rewrite_clean_path(balloc, StringRef::from_lit("//alpha?bravo")));
+ assert_stdstring_equal(
+ "/alpha?bravo",
+ http2::rewrite_clean_path(balloc, StringRef::from_lit("//alpha?bravo"))
+ .str());
}
void test_http2_get_pure_path_component(void) {
- CU_ASSERT("/" == http2::get_pure_path_component(StringRef::from_lit("/")));
-
- CU_ASSERT("/foo" ==
- http2::get_pure_path_component(StringRef::from_lit("/foo")));
-
- CU_ASSERT("/bar" == http2::get_pure_path_component(
- StringRef::from_lit("https://example.org/bar")));
-
- CU_ASSERT("/alpha" == http2::get_pure_path_component(StringRef::from_lit(
- "https://example.org/alpha?q=a")));
-
- CU_ASSERT("/bravo" == http2::get_pure_path_component(StringRef::from_lit(
- "https://example.org/bravo?q=a#fragment")));
-
- CU_ASSERT("" ==
- http2::get_pure_path_component(StringRef::from_lit("\x01\x02")));
+ assert_stdstring_equal(
+ "/", http2::get_pure_path_component(StringRef::from_lit("/")).str());
+
+ assert_stdstring_equal(
+ "/foo",
+ http2::get_pure_path_component(StringRef::from_lit("/foo")).str());
+
+ assert_stdstring_equal("/bar",
+ http2::get_pure_path_component(
+ StringRef::from_lit("https://example.org/bar"))
+ .str());
+
+ assert_stdstring_equal(
+ "/alpha", http2::get_pure_path_component(
+ StringRef::from_lit("https://example.org/alpha?q=a"))
+ .str());
+
+ assert_stdstring_equal(
+ "/bravo",
+ http2::get_pure_path_component(
+ StringRef::from_lit("https://example.org/bravo?q=a#fragment"))
+ .str());
+
+ assert_stdstring_equal(
+ "",
+ http2::get_pure_path_component(StringRef::from_lit("\x01\x02")).str());
}
void test_http2_construct_push_component(void) {
@@ -1122,11 +1192,12 @@ void test_http2_construct_push_component(void) {
base = StringRef::from_lit("/b/");
uri = StringRef::from_lit("https://example.org/foo");
- CU_ASSERT(0 == http2::construct_push_component(balloc, scheme, authority,
- path, base, uri));
- CU_ASSERT("https" == scheme);
- CU_ASSERT("example.org" == authority);
- CU_ASSERT("/foo" == path);
+ assert_int(0, ==,
+ http2::construct_push_component(balloc, scheme, authority, path,
+ base, uri));
+ assert_stdstring_equal("https", scheme.str());
+ assert_stdstring_equal("example.org", authority.str());
+ assert_stdstring_equal("/foo", path.str());
scheme = StringRef{};
authority = StringRef{};
@@ -1134,11 +1205,12 @@ void test_http2_construct_push_component(void) {
uri = StringRef::from_lit("/foo/bar?q=a");
- CU_ASSERT(0 == http2::construct_push_component(balloc, scheme, authority,
- path, base, uri));
- CU_ASSERT("" == scheme);
- CU_ASSERT("" == authority);
- CU_ASSERT("/foo/bar?q=a" == path);
+ assert_int(0, ==,
+ http2::construct_push_component(balloc, scheme, authority, path,
+ base, uri));
+ assert_stdstring_equal("", scheme.str());
+ assert_stdstring_equal("", authority.str());
+ assert_stdstring_equal("/foo/bar?q=a", path.str());
scheme = StringRef{};
authority = StringRef{};
@@ -1146,11 +1218,12 @@ void test_http2_construct_push_component(void) {
uri = StringRef::from_lit("foo/../bar?q=a");
- CU_ASSERT(0 == http2::construct_push_component(balloc, scheme, authority,
- path, base, uri));
- CU_ASSERT("" == scheme);
- CU_ASSERT("" == authority);
- CU_ASSERT("/b/bar?q=a" == path);
+ assert_int(0, ==,
+ http2::construct_push_component(balloc, scheme, authority, path,
+ base, uri));
+ assert_stdstring_equal("", scheme.str());
+ assert_stdstring_equal("", authority.str());
+ assert_stdstring_equal("/b/bar?q=a", path.str());
scheme = StringRef{};
authority = StringRef{};
@@ -1158,91 +1231,97 @@ void test_http2_construct_push_component(void) {
uri = StringRef{};
- CU_ASSERT(-1 == http2::construct_push_component(balloc, scheme, authority,
- path, base, uri));
+ assert_int(-1, ==,
+ http2::construct_push_component(balloc, scheme, authority, path,
+ base, uri));
scheme = StringRef{};
authority = StringRef{};
path = StringRef{};
uri = StringRef::from_lit("?q=a");
- CU_ASSERT(0 == http2::construct_push_component(balloc, scheme, authority,
- path, base, uri));
- CU_ASSERT("" == scheme);
- CU_ASSERT("" == authority);
- CU_ASSERT("/b/?q=a" == path);
+ assert_int(0, ==,
+ http2::construct_push_component(balloc, scheme, authority, path,
+ base, uri));
+ assert_stdstring_equal("", scheme.str());
+ assert_stdstring_equal("", authority.str());
+ assert_stdstring_equal("/b/?q=a", path.str());
}
void test_http2_contains_trailers(void) {
- CU_ASSERT(!http2::contains_trailers(StringRef::from_lit("")));
- CU_ASSERT(http2::contains_trailers(StringRef::from_lit("trailers")));
+ assert_false(http2::contains_trailers(StringRef::from_lit("")));
+ assert_true(http2::contains_trailers(StringRef::from_lit("trailers")));
// Match must be case-insensitive.
- CU_ASSERT(http2::contains_trailers(StringRef::from_lit("TRAILERS")));
- CU_ASSERT(!http2::contains_trailers(StringRef::from_lit("trailer")));
- CU_ASSERT(!http2::contains_trailers(StringRef::from_lit("trailers 3")));
- CU_ASSERT(http2::contains_trailers(StringRef::from_lit("trailers,")));
- CU_ASSERT(http2::contains_trailers(StringRef::from_lit("trailers,foo")));
- CU_ASSERT(http2::contains_trailers(StringRef::from_lit("foo,trailers")));
- CU_ASSERT(http2::contains_trailers(StringRef::from_lit("foo,trailers,bar")));
- CU_ASSERT(
+ assert_true(http2::contains_trailers(StringRef::from_lit("TRAILERS")));
+ assert_false(http2::contains_trailers(StringRef::from_lit("trailer")));
+ assert_false(http2::contains_trailers(StringRef::from_lit("trailers 3")));
+ assert_true(http2::contains_trailers(StringRef::from_lit("trailers,")));
+ assert_true(http2::contains_trailers(StringRef::from_lit("trailers,foo")));
+ assert_true(http2::contains_trailers(StringRef::from_lit("foo,trailers")));
+ assert_true(
+ http2::contains_trailers(StringRef::from_lit("foo,trailers,bar")));
+ assert_true(
http2::contains_trailers(StringRef::from_lit("foo, trailers ,bar")));
- CU_ASSERT(http2::contains_trailers(StringRef::from_lit(",trailers")));
+ assert_true(http2::contains_trailers(StringRef::from_lit(",trailers")));
}
void test_http2_check_transfer_encoding(void) {
- CU_ASSERT(http2::check_transfer_encoding(StringRef::from_lit("chunked")));
- CU_ASSERT(http2::check_transfer_encoding(StringRef::from_lit("foo,chunked")));
- CU_ASSERT(
+ assert_true(http2::check_transfer_encoding(StringRef::from_lit("chunked")));
+ assert_true(
+ http2::check_transfer_encoding(StringRef::from_lit("foo,chunked")));
+ assert_true(
http2::check_transfer_encoding(StringRef::from_lit("foo, chunked")));
- CU_ASSERT(
+ assert_true(
http2::check_transfer_encoding(StringRef::from_lit("foo , chunked")));
- CU_ASSERT(
+ assert_true(
http2::check_transfer_encoding(StringRef::from_lit("chunked;foo=bar")));
- CU_ASSERT(
+ assert_true(
http2::check_transfer_encoding(StringRef::from_lit("chunked ; foo=bar")));
- CU_ASSERT(http2::check_transfer_encoding(
+ assert_true(http2::check_transfer_encoding(
StringRef::from_lit(R"(chunked;foo="bar")")));
- CU_ASSERT(http2::check_transfer_encoding(
+ assert_true(http2::check_transfer_encoding(
StringRef::from_lit(R"(chunked;foo="\bar\"";FOO=BAR)")));
- CU_ASSERT(
+ assert_true(
http2::check_transfer_encoding(StringRef::from_lit(R"(chunked;foo="")")));
- CU_ASSERT(http2::check_transfer_encoding(
+ assert_true(http2::check_transfer_encoding(
StringRef::from_lit(R"(chunked;foo="bar" , gzip)")));
- CU_ASSERT(!http2::check_transfer_encoding(StringRef{}));
- CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit(",chunked")));
- CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit("chunked,")));
- CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit("chunked, ")));
- CU_ASSERT(
- !http2::check_transfer_encoding(StringRef::from_lit("foo,,chunked")));
- CU_ASSERT(
- !http2::check_transfer_encoding(StringRef::from_lit("chunked;foo")));
- CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit("chunked;")));
- CU_ASSERT(
- !http2::check_transfer_encoding(StringRef::from_lit("chunked;foo=bar;")));
- CU_ASSERT(
- !http2::check_transfer_encoding(StringRef::from_lit("chunked;?=bar")));
- CU_ASSERT(
- !http2::check_transfer_encoding(StringRef::from_lit("chunked;=bar")));
- CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit("chunked;;")));
- CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit("chunked?")));
- CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit(",")));
- CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit(" ")));
- CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit(";")));
- CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit("\"")));
- CU_ASSERT(!http2::check_transfer_encoding(
+ assert_false(http2::check_transfer_encoding(StringRef{}));
+ assert_false(http2::check_transfer_encoding(StringRef::from_lit(",chunked")));
+ assert_false(http2::check_transfer_encoding(StringRef::from_lit("chunked,")));
+ assert_false(
+ http2::check_transfer_encoding(StringRef::from_lit("chunked, ")));
+ assert_false(
+ http2::check_transfer_encoding(StringRef::from_lit("foo,,chunked")));
+ assert_false(
+ http2::check_transfer_encoding(StringRef::from_lit("chunked;foo")));
+ assert_false(http2::check_transfer_encoding(StringRef::from_lit("chunked;")));
+ assert_false(
+ http2::check_transfer_encoding(StringRef::from_lit("chunked;foo=bar;")));
+ assert_false(
+ http2::check_transfer_encoding(StringRef::from_lit("chunked;?=bar")));
+ assert_false(
+ http2::check_transfer_encoding(StringRef::from_lit("chunked;=bar")));
+ assert_false(
+ http2::check_transfer_encoding(StringRef::from_lit("chunked;;")));
+ assert_false(http2::check_transfer_encoding(StringRef::from_lit("chunked?")));
+ assert_false(http2::check_transfer_encoding(StringRef::from_lit(",")));
+ assert_false(http2::check_transfer_encoding(StringRef::from_lit(" ")));
+ assert_false(http2::check_transfer_encoding(StringRef::from_lit(";")));
+ assert_false(http2::check_transfer_encoding(StringRef::from_lit("\"")));
+ assert_false(http2::check_transfer_encoding(
StringRef::from_lit(R"(chunked;foo="bar)")));
- CU_ASSERT(!http2::check_transfer_encoding(
+ assert_false(http2::check_transfer_encoding(
StringRef::from_lit(R"(chunked;foo="bar\)")));
- CU_ASSERT(
- !http2::check_transfer_encoding(StringRef::from_lit(R"(chunked;foo="bar\)"
- "\x0a"
- R"(")")));
- CU_ASSERT(
- !http2::check_transfer_encoding(StringRef::from_lit(R"(chunked;foo=")"
- "\x0a"
- R"(")")));
- CU_ASSERT(!http2::check_transfer_encoding(
+ assert_false(
+ http2::check_transfer_encoding(StringRef::from_lit(R"(chunked;foo="bar\)"
+ "\x0a"
+ R"(")")));
+ assert_false(
+ http2::check_transfer_encoding(StringRef::from_lit(R"(chunked;foo=")"
+ "\x0a"
+ R"(")")));
+ assert_false(http2::check_transfer_encoding(
StringRef::from_lit(R"(chunked;foo="bar",,gzip)")));
}
diff --git a/src/http2_test.h b/src/http2_test.h
index 382470d..75fd707 100644
--- a/src/http2_test.h
+++ b/src/http2_test.h
@@ -29,25 +29,31 @@
# include <config.h>
#endif // HAVE_CONFIG_H
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
namespace shrpx {
-void test_http2_add_header(void);
-void test_http2_get_header(void);
-void test_http2_copy_headers_to_nva(void);
-void test_http2_build_http1_headers_from_headers(void);
-void test_http2_lws(void);
-void test_http2_rewrite_location_uri(void);
-void test_http2_parse_http_status_code(void);
-void test_http2_index_header(void);
-void test_http2_lookup_token(void);
-void test_http2_parse_link_header(void);
-void test_http2_path_join(void);
-void test_http2_normalize_path(void);
-void test_http2_rewrite_clean_path(void);
-void test_http2_get_pure_path_component(void);
-void test_http2_construct_push_component(void);
-void test_http2_contains_trailers(void);
-void test_http2_check_transfer_encoding(void);
+extern const MunitSuite http2_suite;
+
+munit_void_test_decl(test_http2_add_header);
+munit_void_test_decl(test_http2_get_header);
+munit_void_test_decl(test_http2_copy_headers_to_nva);
+munit_void_test_decl(test_http2_build_http1_headers_from_headers);
+munit_void_test_decl(test_http2_lws);
+munit_void_test_decl(test_http2_rewrite_location_uri);
+munit_void_test_decl(test_http2_parse_http_status_code);
+munit_void_test_decl(test_http2_index_header);
+munit_void_test_decl(test_http2_lookup_token);
+munit_void_test_decl(test_http2_parse_link_header);
+munit_void_test_decl(test_http2_path_join);
+munit_void_test_decl(test_http2_normalize_path);
+munit_void_test_decl(test_http2_rewrite_clean_path);
+munit_void_test_decl(test_http2_get_pure_path_component);
+munit_void_test_decl(test_http2_construct_push_component);
+munit_void_test_decl(test_http2_contains_trailers);
+munit_void_test_decl(test_http2_check_transfer_encoding);
} // namespace shrpx
diff --git a/src/inflatehd.cc b/src/inflatehd.cc
index f484042..537b4fa 100644
--- a/src/inflatehd.cc
+++ b/src/inflatehd.cc
@@ -41,6 +41,7 @@
#include <jansson.h>
+#define NGHTTP2_NO_SSIZE_T
#include <nghttp2/nghttp2.h>
#include "template.h"
@@ -93,7 +94,6 @@ static void to_json(nghttp2_hd_inflater *inflater, json_t *headers,
}
static int inflate_hd(json_t *obj, nghttp2_hd_inflater *inflater, int seq) {
- ssize_t rv;
nghttp2_nv nv;
int inflate_flags;
size_t old_settings_table_size =
@@ -120,8 +120,8 @@ static int inflate_hd(json_t *obj, nghttp2_hd_inflater *inflater, int seq) {
seq);
return -1;
}
- rv = nghttp2_hd_inflate_change_table_size(inflater,
- json_integer_value(table_size));
+ auto rv = nghttp2_hd_inflate_change_table_size(
+ inflater, json_integer_value(table_size));
if (rv != 0) {
fprintf(stderr,
"nghttp2_hd_change_table_size() failed with error %s at %d\n",
@@ -147,7 +147,8 @@ static int inflate_hd(json_t *obj, nghttp2_hd_inflater *inflater, int seq) {
auto p = buf.data();
for (;;) {
inflate_flags = 0;
- rv = nghttp2_hd_inflate_hd(inflater, &nv, &inflate_flags, p, buflen, 1);
+ auto rv =
+ nghttp2_hd_inflate_hd3(inflater, &nv, &inflate_flags, p, buflen, 1);
if (rv < 0) {
fprintf(stderr, "inflate failed with error code %zd at %d\n", rv, seq);
exit(EXIT_FAILURE);
diff --git a/src/libevent_util.cc b/src/libevent_util.cc
deleted file mode 100644
index 3b60b6d..0000000
--- a/src/libevent_util.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * nghttp2 - HTTP/2 C Library
- *
- * Copyright (c) 2014 Tatsuhiro Tsujikawa
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include "libevent_util.h"
-
-#include <cstring>
-#include <algorithm>
-
-namespace nghttp2 {
-
-namespace util {
-
-EvbufferBuffer::EvbufferBuffer()
- : evbuffer_(nullptr),
- bucket_(nullptr),
- buf_(nullptr),
- bufmax_(0),
- buflen_(0),
- limit_(0),
- writelen_(0) {}
-
-EvbufferBuffer::EvbufferBuffer(evbuffer *evbuffer, uint8_t *buf, size_t bufmax,
- ssize_t limit)
- : evbuffer_(evbuffer),
- bucket_(limit == -1 ? nullptr : evbuffer_new()),
- buf_(buf),
- bufmax_(bufmax),
- buflen_(0),
- limit_(limit),
- writelen_(0) {}
-
-void EvbufferBuffer::reset(evbuffer *evbuffer, uint8_t *buf, size_t bufmax,
- ssize_t limit) {
- evbuffer_ = evbuffer;
- buf_ = buf;
- if (limit != -1 && !bucket_) {
- bucket_ = evbuffer_new();
- }
- bufmax_ = bufmax;
- buflen_ = 0;
- limit_ = limit;
- writelen_ = 0;
-}
-
-EvbufferBuffer::~EvbufferBuffer() {
- if (bucket_) {
- evbuffer_free(bucket_);
- }
-}
-
-int EvbufferBuffer::write_buffer() {
- for (auto pos = buf_, end = buf_ + buflen_; pos < end;) {
- // To avoid merging chunks in evbuffer, we first add to temporal
- // buffer bucket_ and then move its chain to evbuffer_.
- auto nwrite = std::min(end - pos, limit_);
- auto rv = evbuffer_add(bucket_, pos, nwrite);
- if (rv == -1) {
- return -1;
- }
- rv = evbuffer_add_buffer(evbuffer_, bucket_);
- if (rv == -1) {
- return -1;
- }
- pos += nwrite;
- }
- return 0;
-}
-
-int EvbufferBuffer::flush() {
- int rv;
- if (buflen_ > 0) {
- if (limit_ == -1) {
- rv = evbuffer_add(evbuffer_, buf_, buflen_);
- } else {
- rv = write_buffer();
- }
- if (rv == -1) {
- return -1;
- }
- writelen_ += buflen_;
- buflen_ = 0;
- }
- return 0;
-}
-
-int EvbufferBuffer::add(const uint8_t *data, size_t datalen) {
- int rv;
- if (buflen_ + datalen > bufmax_) {
- if (buflen_ > 0) {
- if (limit_ == -1) {
- rv = evbuffer_add(evbuffer_, buf_, buflen_);
- } else {
- rv = write_buffer();
- }
- if (rv == -1) {
- return -1;
- }
- writelen_ += buflen_;
- buflen_ = 0;
- }
- if (datalen > bufmax_) {
- if (limit_ == -1) {
- rv = evbuffer_add(evbuffer_, data, datalen);
- } else {
- rv = write_buffer();
- }
- if (rv == -1) {
- return -1;
- }
- writelen_ += buflen_;
- return 0;
- }
- }
- memcpy(buf_ + buflen_, data, datalen);
- buflen_ += datalen;
- return 0;
-}
-
-size_t EvbufferBuffer::get_buflen() const { return buflen_; }
-
-size_t EvbufferBuffer::get_writelen() const { return writelen_; }
-
-void bev_enable_unless(bufferevent *bev, int events) {
- if ((bufferevent_get_enabled(bev) & events) == events) {
- return;
- }
-
- bufferevent_enable(bev, events);
-}
-
-void bev_disable_unless(bufferevent *bev, int events) {
- if ((bufferevent_get_enabled(bev) & events) == 0) {
- return;
- }
-
- bufferevent_disable(bev, events);
-}
-
-} // namespace util
-
-} // namespace nghttp2
diff --git a/src/libevent_util.h b/src/libevent_util.h
deleted file mode 100644
index 1d1ee91..0000000
--- a/src/libevent_util.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * nghttp2 - HTTP/2 C Library
- *
- * Copyright (c) 2014 Tatsuhiro Tsujikawa
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#ifndef LIBEVENT_UTIL_H
-#define LIBEVENT_UTIL_H
-
-#include "nghttp2_config.h"
-
-#include <event2/buffer.h>
-#include <event2/bufferevent.h>
-
-namespace nghttp2 {
-
-namespace util {
-
-class EvbufferBuffer {
-public:
- EvbufferBuffer();
- // If |limit| is not -1, at most min(limit, bufmax) size bytes are
- // added to evbuffer_.
- EvbufferBuffer(evbuffer *evbuffer, uint8_t *buf, size_t bufmax,
- ssize_t limit = -1);
- ~EvbufferBuffer();
- void reset(evbuffer *evbuffer, uint8_t *buf, size_t bufmax,
- ssize_t limit = -1);
- int flush();
- int add(const uint8_t *data, size_t datalen);
- size_t get_buflen() const;
- int write_buffer();
- // Returns the number of written bytes to evbuffer_ so far. reset()
- // resets this value to 0.
- size_t get_writelen() const;
-
-private:
- evbuffer *evbuffer_;
- evbuffer *bucket_;
- uint8_t *buf_;
- size_t bufmax_;
- size_t buflen_;
- ssize_t limit_;
- size_t writelen_;
-};
-
-// These functions are provided to reduce epoll_ctl syscall. Avoid
-// calling bufferevent_enable/disable() unless it is required by
-// sniffing current enabled events.
-void bev_enable_unless(bufferevent *bev, int events);
-void bev_disable_unless(bufferevent *bev, int events);
-
-} // namespace util
-
-} // namespace nghttp2
-
-#endif // LIBEVENT_UTIL_H
diff --git a/src/memchunk_test.cc b/src/memchunk_test.cc
index 236d9ea..1c57c02 100644
--- a/src/memchunk_test.cc
+++ b/src/memchunk_test.cc
@@ -24,7 +24,7 @@
*/
#include "memchunk_test.h"
-#include <CUnit/CUnit.h>
+#include "munitxx.h"
#include <nghttp2/nghttp2.h>
@@ -33,52 +33,72 @@
namespace nghttp2 {
+namespace {
+const MunitTest tests[]{
+ munit_void_test(test_pool_recycle),
+ munit_void_test(test_memchunks_append),
+ munit_void_test(test_memchunks_drain),
+ munit_void_test(test_memchunks_riovec),
+ munit_void_test(test_memchunks_recycle),
+ munit_void_test(test_memchunks_reset),
+ munit_void_test(test_peek_memchunks_append),
+ munit_void_test(test_peek_memchunks_disable_peek_drain),
+ munit_void_test(test_peek_memchunks_disable_peek_no_drain),
+ munit_void_test(test_peek_memchunks_reset),
+ munit_test_end(),
+};
+} // namespace
+
+const MunitSuite memchunk_suite{
+ "/memchunk", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
void test_pool_recycle(void) {
MemchunkPool pool;
- CU_ASSERT(!pool.pool);
- CU_ASSERT(0 == pool.poolsize);
- CU_ASSERT(nullptr == pool.freelist);
+ assert_null(pool.pool);
+ assert_size(0, ==, pool.poolsize);
+ assert_null(pool.freelist);
auto m1 = pool.get();
- CU_ASSERT(m1 == pool.pool);
- CU_ASSERT(MemchunkPool::value_type::size == pool.poolsize);
- CU_ASSERT(nullptr == pool.freelist);
+ assert_ptr_equal(m1, pool.pool);
+ assert_size(MemchunkPool::value_type::size, ==, pool.poolsize);
+ assert_null(pool.freelist);
auto m2 = pool.get();
- CU_ASSERT(m2 == pool.pool);
- CU_ASSERT(2 * MemchunkPool::value_type::size == pool.poolsize);
- CU_ASSERT(nullptr == pool.freelist);
- CU_ASSERT(m1 == m2->knext);
- CU_ASSERT(nullptr == m1->knext);
+ assert_ptr_equal(m2, pool.pool);
+ assert_size(2 * MemchunkPool::value_type::size, ==, pool.poolsize);
+ assert_null(pool.freelist);
+ assert_ptr_equal(m1, m2->knext);
+ assert_null(m1->knext);
auto m3 = pool.get();
- CU_ASSERT(m3 == pool.pool);
- CU_ASSERT(3 * MemchunkPool::value_type::size == pool.poolsize);
- CU_ASSERT(nullptr == pool.freelist);
+ assert_ptr_equal(m3, pool.pool);
+ assert_size(3 * MemchunkPool::value_type::size, ==, pool.poolsize);
+ assert_null(pool.freelist);
pool.recycle(m3);
- CU_ASSERT(m3 == pool.pool);
- CU_ASSERT(3 * MemchunkPool::value_type::size == pool.poolsize);
- CU_ASSERT(m3 == pool.freelist);
+ assert_ptr_equal(m3, pool.pool);
+ assert_size(3 * MemchunkPool::value_type::size, ==, pool.poolsize);
+ assert_ptr_equal(m3, pool.freelist);
auto m4 = pool.get();
- CU_ASSERT(m3 == m4);
- CU_ASSERT(m4 == pool.pool);
- CU_ASSERT(3 * MemchunkPool::value_type::size == pool.poolsize);
- CU_ASSERT(nullptr == pool.freelist);
+ assert_ptr_equal(m3, m4);
+ assert_ptr_equal(m4, pool.pool);
+ assert_size(3 * MemchunkPool::value_type::size, ==, pool.poolsize);
+ assert_null(pool.freelist);
pool.recycle(m2);
pool.recycle(m1);
- CU_ASSERT(m1 == pool.freelist);
- CU_ASSERT(m2 == m1->next);
- CU_ASSERT(nullptr == m2->next);
+ assert_ptr_equal(m1, pool.freelist);
+ assert_ptr_equal(m2, m1->next);
+ assert_null(m2->next);
}
using Memchunk16 = Memchunk<16>;
@@ -94,37 +114,37 @@ void test_memchunks_append(void) {
auto m = chunks.tail;
- CU_ASSERT(3 == m->len());
- CU_ASSERT(13 == m->left());
+ assert_size(3, ==, m->len());
+ assert_size(13, ==, m->left());
chunks.append("3456789abcdef@");
- CU_ASSERT(16 == m->len());
- CU_ASSERT(0 == m->left());
+ assert_size(16, ==, m->len());
+ assert_size(0, ==, m->left());
m = chunks.tail;
- CU_ASSERT(1 == m->len());
- CU_ASSERT(15 == m->left());
- CU_ASSERT(17 == chunks.rleft());
+ assert_size(1, ==, m->len());
+ assert_size(15, ==, m->left());
+ assert_size(17, ==, chunks.rleft());
char buf[16];
size_t nread;
nread = chunks.remove(buf, 8);
- CU_ASSERT(8 == nread);
- CU_ASSERT(0 == memcmp("01234567", buf, nread));
- CU_ASSERT(9 == chunks.rleft());
+ assert_size(8, ==, nread);
+ assert_memory_equal(nread, "01234567", buf);
+ assert_size(9, ==, chunks.rleft());
nread = chunks.remove(buf, sizeof(buf));
- CU_ASSERT(9 == nread);
- CU_ASSERT(0 == memcmp("89abcdef@", buf, nread));
- CU_ASSERT(0 == chunks.rleft());
- CU_ASSERT(nullptr == chunks.head);
- CU_ASSERT(nullptr == chunks.tail);
- CU_ASSERT(32 == pool.poolsize);
+ assert_size(9, ==, nread);
+ assert_memory_equal(nread, "89abcdef@", buf);
+ assert_size(0, ==, chunks.rleft());
+ assert_null(chunks.head);
+ assert_null(chunks.tail);
+ assert_size(32, ==, pool.poolsize);
}
void test_memchunks_drain(void) {
@@ -137,14 +157,14 @@ void test_memchunks_drain(void) {
nread = chunks.drain(3);
- CU_ASSERT(3 == nread);
+ assert_size(3, ==, nread);
char buf[16];
nread = chunks.remove(buf, sizeof(buf));
- CU_ASSERT(7 == nread);
- CU_ASSERT(0 == memcmp("3456789", buf, nread));
+ assert_size(7, ==, nread);
+ assert_memory_equal(nread, "3456789", buf);
}
void test_memchunks_riovec(void) {
@@ -160,24 +180,24 @@ void test_memchunks_riovec(void) {
auto m = chunks.head;
- CU_ASSERT(2 == iovcnt);
- CU_ASSERT(m->buf.data() == iov[0].iov_base);
- CU_ASSERT(m->len() == iov[0].iov_len);
+ assert_int(2, ==, iovcnt);
+ assert_ptr_equal(m->buf.data(), iov[0].iov_base);
+ assert_size(m->len(), ==, iov[0].iov_len);
m = m->next;
- CU_ASSERT(m->buf.data() == iov[1].iov_base);
- CU_ASSERT(m->len() == iov[1].iov_len);
+ assert_ptr_equal(m->buf.data(), iov[1].iov_base);
+ assert_size(m->len(), ==, iov[1].iov_len);
chunks.drain(2 * 16);
iovcnt = chunks.riovec(iov.data(), iov.size());
- CU_ASSERT(1 == iovcnt);
+ assert_int(1, ==, iovcnt);
m = chunks.head;
- CU_ASSERT(m->buf.data() == iov[0].iov_base);
- CU_ASSERT(m->len() == iov[0].iov_len);
+ assert_ptr_equal(m->buf.data(), iov[0].iov_base);
+ assert_size(m->len(), ==, iov[0].iov_len);
}
void test_memchunks_recycle(void) {
@@ -187,14 +207,14 @@ void test_memchunks_recycle(void) {
std::array<char, 32> buf{};
chunks.append(buf.data(), buf.size());
}
- CU_ASSERT(32 == pool.poolsize);
- CU_ASSERT(nullptr != pool.freelist);
+ assert_size(32, ==, pool.poolsize);
+ assert_not_null(pool.freelist);
auto m = pool.freelist;
m = m->next;
- CU_ASSERT(nullptr != m);
- CU_ASSERT(nullptr == m->next);
+ assert_not_null(m);
+ assert_null(m->next);
}
void test_memchunks_reset(void) {
@@ -205,19 +225,19 @@ void test_memchunks_reset(void) {
chunks.append(b.data(), b.size());
- CU_ASSERT(32 == chunks.rleft());
+ assert_size(32, ==, chunks.rleft());
chunks.reset();
- CU_ASSERT(0 == chunks.rleft());
- CU_ASSERT(nullptr == chunks.head);
- CU_ASSERT(nullptr == chunks.tail);
+ assert_size(0, ==, chunks.rleft());
+ assert_null(chunks.head);
+ assert_null(chunks.tail);
auto m = pool.freelist;
- CU_ASSERT(nullptr != m);
- CU_ASSERT(nullptr != m->next);
- CU_ASSERT(nullptr == m->next->next);
+ assert_not_null(m);
+ assert_not_null(m->next);
+ assert_null(m->next->next);
}
void test_peek_memchunks_append(void) {
@@ -232,27 +252,27 @@ void test_peek_memchunks_append(void) {
pchunks.append(b.data(), b.size());
- CU_ASSERT(32 == pchunks.rleft());
- CU_ASSERT(32 == pchunks.rleft_buffered());
+ assert_size(32, ==, pchunks.rleft());
+ assert_size(32, ==, pchunks.rleft_buffered());
- CU_ASSERT(0 == pchunks.remove(nullptr, 0));
+ assert_size(0, ==, pchunks.remove(nullptr, 0));
- CU_ASSERT(32 == pchunks.rleft());
- CU_ASSERT(32 == pchunks.rleft_buffered());
+ assert_size(32, ==, pchunks.rleft());
+ assert_size(32, ==, pchunks.rleft_buffered());
- CU_ASSERT(12 == pchunks.remove(d.data(), 12));
+ assert_size(12, ==, pchunks.remove(d.data(), 12));
- CU_ASSERT(std::equal(std::begin(b), std::begin(b) + 12, std::begin(d)));
+ assert_true(std::equal(std::begin(b), std::begin(b) + 12, std::begin(d)));
- CU_ASSERT(20 == pchunks.rleft());
- CU_ASSERT(32 == pchunks.rleft_buffered());
+ assert_size(20, ==, pchunks.rleft());
+ assert_size(32, ==, pchunks.rleft_buffered());
- CU_ASSERT(20 == pchunks.remove(d.data(), d.size()));
+ assert_size(20, ==, pchunks.remove(d.data(), d.size()));
- CU_ASSERT(std::equal(std::begin(b) + 12, std::end(b), std::begin(d)));
+ assert_true(std::equal(std::begin(b) + 12, std::end(b), std::begin(d)));
- CU_ASSERT(0 == pchunks.rleft());
- CU_ASSERT(32 == pchunks.rleft_buffered());
+ assert_size(0, ==, pchunks.rleft());
+ assert_size(32, ==, pchunks.rleft_buffered());
}
void test_peek_memchunks_disable_peek_drain(void) {
@@ -267,20 +287,20 @@ void test_peek_memchunks_disable_peek_drain(void) {
pchunks.append(b.data(), b.size());
- CU_ASSERT(12 == pchunks.remove(d.data(), 12));
+ assert_size(12, ==, pchunks.remove(d.data(), 12));
pchunks.disable_peek(true);
- CU_ASSERT(!pchunks.peeking);
- CU_ASSERT(20 == pchunks.rleft());
- CU_ASSERT(20 == pchunks.rleft_buffered());
+ assert_false(pchunks.peeking);
+ assert_size(20, ==, pchunks.rleft());
+ assert_size(20, ==, pchunks.rleft_buffered());
- CU_ASSERT(20 == pchunks.remove(d.data(), d.size()));
+ assert_size(20, ==, pchunks.remove(d.data(), d.size()));
- CU_ASSERT(std::equal(std::begin(b) + 12, std::end(b), std::begin(d)));
+ assert_true(std::equal(std::begin(b) + 12, std::end(b), std::begin(d)));
- CU_ASSERT(0 == pchunks.rleft());
- CU_ASSERT(0 == pchunks.rleft_buffered());
+ assert_size(0, ==, pchunks.rleft());
+ assert_size(0, ==, pchunks.rleft_buffered());
}
void test_peek_memchunks_disable_peek_no_drain(void) {
@@ -295,20 +315,20 @@ void test_peek_memchunks_disable_peek_no_drain(void) {
pchunks.append(b.data(), b.size());
- CU_ASSERT(12 == pchunks.remove(d.data(), 12));
+ assert_size(12, ==, pchunks.remove(d.data(), 12));
pchunks.disable_peek(false);
- CU_ASSERT(!pchunks.peeking);
- CU_ASSERT(32 == pchunks.rleft());
- CU_ASSERT(32 == pchunks.rleft_buffered());
+ assert_false(pchunks.peeking);
+ assert_size(32, ==, pchunks.rleft());
+ assert_size(32, ==, pchunks.rleft_buffered());
- CU_ASSERT(32 == pchunks.remove(d.data(), d.size()));
+ assert_size(32, ==, pchunks.remove(d.data(), d.size()));
- CU_ASSERT(std::equal(std::begin(b), std::end(b), std::begin(d)));
+ assert_true(std::equal(std::begin(b), std::end(b), std::begin(d)));
- CU_ASSERT(0 == pchunks.rleft());
- CU_ASSERT(0 == pchunks.rleft_buffered());
+ assert_size(0, ==, pchunks.rleft());
+ assert_size(0, ==, pchunks.rleft_buffered());
}
void test_peek_memchunks_reset(void) {
@@ -323,18 +343,18 @@ void test_peek_memchunks_reset(void) {
pchunks.append(b.data(), b.size());
- CU_ASSERT(12 == pchunks.remove(d.data(), 12));
+ assert_size(12, ==, pchunks.remove(d.data(), 12));
pchunks.disable_peek(true);
pchunks.reset();
- CU_ASSERT(0 == pchunks.rleft());
- CU_ASSERT(0 == pchunks.rleft_buffered());
+ assert_size(0, ==, pchunks.rleft());
+ assert_size(0, ==, pchunks.rleft_buffered());
- CU_ASSERT(nullptr == pchunks.cur);
- CU_ASSERT(nullptr == pchunks.cur_pos);
- CU_ASSERT(nullptr == pchunks.cur_last);
- CU_ASSERT(pchunks.peeking);
+ assert_null(pchunks.cur);
+ assert_null(pchunks.cur_pos);
+ assert_null(pchunks.cur_last);
+ assert_true(pchunks.peeking);
}
} // namespace nghttp2
diff --git a/src/memchunk_test.h b/src/memchunk_test.h
index 7d677e7..a3fe028 100644
--- a/src/memchunk_test.h
+++ b/src/memchunk_test.h
@@ -29,18 +29,24 @@
# include <config.h>
#endif // HAVE_CONFIG_H
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
namespace nghttp2 {
-void test_pool_recycle(void);
-void test_memchunks_append(void);
-void test_memchunks_drain(void);
-void test_memchunks_riovec(void);
-void test_memchunks_recycle(void);
-void test_memchunks_reset(void);
-void test_peek_memchunks_append(void);
-void test_peek_memchunks_disable_peek_drain(void);
-void test_peek_memchunks_disable_peek_no_drain(void);
-void test_peek_memchunks_reset(void);
+extern const MunitSuite memchunk_suite;
+
+munit_void_test_decl(test_pool_recycle);
+munit_void_test_decl(test_memchunks_append);
+munit_void_test_decl(test_memchunks_drain);
+munit_void_test_decl(test_memchunks_riovec);
+munit_void_test_decl(test_memchunks_recycle);
+munit_void_test_decl(test_memchunks_reset);
+munit_void_test_decl(test_peek_memchunks_append);
+munit_void_test_decl(test_peek_memchunks_disable_peek_drain);
+munit_void_test_decl(test_peek_memchunks_disable_peek_no_drain);
+munit_void_test_decl(test_peek_memchunks_reset);
} // namespace nghttp2
diff --git a/src/nghttp.cc b/src/nghttp.cc
index 41a88c6..f670320 100644
--- a/src/nghttp.cc
+++ b/src/nghttp.cc
@@ -157,7 +157,7 @@ std::string strip_fragment(const char *raw_uri) {
} // namespace
Request::Request(const std::string &uri, const http_parser_url &u,
- const nghttp2_data_provider *data_prd, int64_t data_length,
+ const nghttp2_data_provider2 *data_prd, int64_t data_length,
const nghttp2_priority_spec &pri_spec, int level)
: uri(uri),
u(u),
@@ -370,11 +370,11 @@ void continue_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
auto req = static_cast<Request *>(w->data);
int error;
- error = nghttp2_submit_data(client->session, NGHTTP2_FLAG_END_STREAM,
- req->stream_id, req->data_prd);
+ error = nghttp2_submit_data2(client->session, NGHTTP2_FLAG_END_STREAM,
+ req->stream_id, req->data_prd);
if (error) {
- std::cerr << "[ERROR] nghttp2_submit_data() returned error: "
+ std::cerr << "[ERROR] nghttp2_submit_data2() returned error: "
<< nghttp2_strerror(error) << std::endl;
nghttp2_submit_rst_stream(client->session, NGHTTP2_FLAG_NONE,
req->stream_id, NGHTTP2_INTERNAL_ERROR);
@@ -525,13 +525,13 @@ int submit_request(HttpClient *client, const Headers &headers, Request *req) {
nva.data(), nva.size(), req);
} else {
stream_id =
- nghttp2_submit_request(client->session, &req->pri_spec, nva.data(),
- nva.size(), req->data_prd, req);
+ nghttp2_submit_request2(client->session, &req->pri_spec, nva.data(),
+ nva.size(), req->data_prd, req);
}
if (stream_id < 0) {
std::cerr << "[ERROR] nghttp2_submit_"
- << (expect_continue ? "headers" : "request")
+ << (expect_continue ? "headers" : "request2")
<< "() returned error: " << nghttp2_strerror(stream_id)
<< std::endl;
return -1;
@@ -953,14 +953,14 @@ size_t populate_settings(nghttp2_settings_entry *iv) {
} // namespace
int HttpClient::on_upgrade_connect() {
- ssize_t rv;
+ nghttp2_ssize rv;
record_connect_end_time();
assert(!reqvec.empty());
std::array<nghttp2_settings_entry, 16> iv;
size_t niv = populate_settings(iv.data());
assert(settings_payload.size() >= 8 * niv);
- rv = nghttp2_pack_settings_payload(settings_payload.data(),
- settings_payload.size(), iv.data(), niv);
+ rv = nghttp2_pack_settings_payload2(settings_payload.data(),
+ settings_payload.size(), iv.data(), niv);
if (rv < 0) {
return -1;
}
@@ -1250,9 +1250,9 @@ int HttpClient::on_read(const uint8_t *data, size_t len) {
util::hexdump(stdout, data, len);
}
- auto rv = nghttp2_session_mem_recv(session, data, len);
+ auto rv = nghttp2_session_mem_recv2(session, data, len);
if (rv < 0) {
- std::cerr << "[ERROR] nghttp2_session_mem_recv() returned error: "
+ std::cerr << "[ERROR] nghttp2_session_mem_recv2() returned error: "
<< nghttp2_strerror(rv) << std::endl;
return -1;
}
@@ -1276,9 +1276,9 @@ int HttpClient::on_write() {
}
const uint8_t *data;
- auto len = nghttp2_session_mem_send(session, &data);
+ auto len = nghttp2_session_mem_send2(session, &data);
if (len < 0) {
- std::cerr << "[ERROR] nghttp2_session_send() returned error: "
+ std::cerr << "[ERROR] nghttp2_session_send2() returned error: "
<< nghttp2_strerror(len) << std::endl;
return -1;
}
@@ -1449,7 +1449,7 @@ void HttpClient::update_hostport() {
}
bool HttpClient::add_request(const std::string &uri,
- const nghttp2_data_provider *data_prd,
+ const nghttp2_data_provider2 *data_prd,
int64_t data_length,
const nghttp2_priority_spec &pri_spec, int level) {
http_parser_url u{};
@@ -1768,9 +1768,9 @@ int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
} // namespace
namespace {
-ssize_t select_padding_callback(nghttp2_session *session,
- const nghttp2_frame *frame, size_t max_payload,
- void *user_data) {
+nghttp2_ssize select_padding_callback(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ size_t max_payload, void *user_data) {
return std::min(max_payload, frame->hd.length + config.padding);
}
} // namespace
@@ -2241,7 +2241,7 @@ namespace {
int communicate(
const std::string &scheme, const std::string &host, uint16_t port,
std::vector<
- std::tuple<std::string, nghttp2_data_provider *, int64_t, int32_t>>
+ std::tuple<std::string, nghttp2_data_provider2 *, int64_t, int32_t>>
requests,
const nghttp2_session_callbacks *callbacks) {
int result = 0;
@@ -2311,6 +2311,17 @@ int communicate(
auto proto_list = util::get_default_alpn();
SSL_CTX_set_alpn_protos(ssl_ctx, proto_list.data(), proto_list.size());
+
+#if defined(NGHTTP2_OPENSSL_IS_BORINGSSL) && defined(HAVE_LIBBROTLI)
+ if (!SSL_CTX_add_cert_compression_alg(
+ ssl_ctx, nghttp2::tls::CERTIFICATE_COMPRESSION_ALGO_BROTLI,
+ nghttp2::tls::cert_compress, nghttp2::tls::cert_decompress)) {
+ std::cerr << "[ERROR] SSL_CTX_add_cert_compression_alg failed."
+ << std::endl;
+ result = -1;
+ goto fin;
+ }
+#endif // NGHTTP2_OPENSSL_IS_BORINGSSL && HAVE_LIBBROTLI
}
{
HttpClient client{callbacks, loop, ssl_ctx};
@@ -2391,9 +2402,10 @@ fin:
} // namespace
namespace {
-ssize_t file_read_callback(nghttp2_session *session, int32_t stream_id,
- uint8_t *buf, size_t length, uint32_t *data_flags,
- nghttp2_data_source *source, void *user_data) {
+nghttp2_ssize file_read_callback(nghttp2_session *session, int32_t stream_id,
+ uint8_t *buf, size_t length,
+ uint32_t *data_flags,
+ nghttp2_data_source *source, void *user_data) {
int rv;
auto req = static_cast<Request *>(
nghttp2_session_get_stream_user_data(session, stream_id));
@@ -2429,14 +2441,14 @@ ssize_t file_read_callback(nghttp2_session *session, int32_t stream_id,
}
}
- return nread;
+ return static_cast<nghttp2_ssize>(nread);
}
if (req->data_offset > req->data_length || nread == 0) {
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
}
- return nread;
+ return static_cast<nghttp2_ssize>(nread);
}
} // namespace
@@ -2480,7 +2492,7 @@ int run(char **uris, int n) {
callbacks, on_frame_not_send_callback);
if (config.padding) {
- nghttp2_session_callbacks_set_select_padding_callback(
+ nghttp2_session_callbacks_set_select_padding_callback2(
callbacks, select_padding_callback);
}
@@ -2489,7 +2501,7 @@ int run(char **uris, int n) {
uint16_t prev_port = 0;
int failures = 0;
int data_fd = -1;
- nghttp2_data_provider data_prd;
+ nghttp2_data_provider2 data_prd;
struct stat data_stat;
if (!config.datafile.empty()) {
@@ -2557,7 +2569,7 @@ int run(char **uris, int n) {
data_prd.read_callback = file_read_callback;
}
std::vector<
- std::tuple<std::string, nghttp2_data_provider *, int64_t, int32_t>>
+ std::tuple<std::string, nghttp2_data_provider2 *, int64_t, int32_t>>
requests;
size_t next_weight_idx = 0;
diff --git a/src/nghttp.h b/src/nghttp.h
index a880414..5b339e8 100644
--- a/src/nghttp.h
+++ b/src/nghttp.h
@@ -45,6 +45,7 @@
#include <ev.h>
+#define NGHTTP2_NO_SSIZE_T
#include <nghttp2/nghttp2.h>
#include "llhttp.h"
@@ -77,7 +78,7 @@ struct Config {
int64_t encoder_header_table_size;
size_t padding;
size_t max_concurrent_streams;
- ssize_t peer_max_concurrent_streams;
+ size_t peer_max_concurrent_streams;
int multiply;
// milliseconds
ev_tstamp timeout;
@@ -137,7 +138,7 @@ struct ContinueTimer {
struct Request {
// For pushed request, |uri| is empty and |u| is zero-cleared.
Request(const std::string &uri, const http_parser_url &u,
- const nghttp2_data_provider *data_prd, int64_t data_length,
+ const nghttp2_data_provider2 *data_prd, int64_t data_length,
const nghttp2_priority_spec &pri_spec, int level = 0);
~Request();
@@ -180,7 +181,7 @@ struct Request {
int64_t response_len;
nghttp2_gzip *inflater;
std::unique_ptr<HtmlParser> html_parser;
- const nghttp2_data_provider *data_prd;
+ const nghttp2_data_provider2 *data_prd;
size_t header_buffer_size;
int32_t stream_id;
int status;
@@ -246,7 +247,7 @@ struct HttpClient {
bool all_requests_processed() const;
void update_hostport();
bool add_request(const std::string &uri,
- const nghttp2_data_provider *data_prd, int64_t data_length,
+ const nghttp2_data_provider2 *data_prd, int64_t data_length,
const nghttp2_priority_spec &pri_spec, int level = 0);
void record_start_time();
diff --git a/src/nghttp2_gzip_test.c b/src/nghttp2_gzip_test.c
index de19d5d..9a36db0 100644
--- a/src/nghttp2_gzip_test.c
+++ b/src/nghttp2_gzip_test.c
@@ -27,26 +27,35 @@
#include <stdio.h>
#include <assert.h>
-#include <CUnit/CUnit.h>
+#include "munit.h"
#include <zlib.h>
#include "nghttp2_gzip.h"
+static const MunitTest tests[] = {
+ munit_void_test(test_nghttp2_gzip_inflate),
+ munit_test_end(),
+};
+
+const MunitSuite gzip_suite = {
+ "/gzip", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
static size_t deflate_data(uint8_t *out, size_t outlen, const uint8_t *in,
size_t inlen) {
int rv;
z_stream zst = {0};
rv = deflateInit(&zst, Z_DEFAULT_COMPRESSION);
- CU_ASSERT(rv == Z_OK);
+ assert_int(Z_OK, ==, rv);
zst.avail_in = (unsigned int)inlen;
zst.next_in = (uint8_t *)in;
zst.avail_out = (unsigned int)outlen;
zst.next_out = out;
rv = deflate(&zst, Z_SYNC_FLUSH);
- CU_ASSERT(rv == Z_OK);
+ assert_int(Z_OK, ==, rv);
deflateEnd(&zst);
@@ -71,41 +80,44 @@ void test_nghttp2_gzip_inflate(void) {
inlen = deflate_data(in, inlen, (const uint8_t *)input, sizeof(input) - 1);
- CU_ASSERT(0 == nghttp2_gzip_inflate_new(&inflater));
+ assert_int(0, ==, nghttp2_gzip_inflate_new(&inflater));
/* First 16 bytes */
inptr = in;
inproclen = inlen;
outproclen = 16;
- CU_ASSERT(
- 0 == nghttp2_gzip_inflate(inflater, out, &outproclen, inptr, &inproclen));
- CU_ASSERT(16 == outproclen);
- CU_ASSERT(inproclen > 0);
- CU_ASSERT(0 == memcmp(inputptr, out, outproclen));
+ assert_int(
+ 0, ==,
+ nghttp2_gzip_inflate(inflater, out, &outproclen, inptr, &inproclen));
+ assert_size(16, ==, outproclen);
+ assert_size(0, <, inproclen);
+ assert_memory_equal(outproclen, inputptr, out);
/* Next 32 bytes */
inptr += inproclen;
inlen -= inproclen;
inproclen = inlen;
inputptr += outproclen;
outproclen = 32;
- CU_ASSERT(
- 0 == nghttp2_gzip_inflate(inflater, out, &outproclen, inptr, &inproclen));
- CU_ASSERT(32 == outproclen);
- CU_ASSERT(inproclen > 0);
- CU_ASSERT(0 == memcmp(inputptr, out, outproclen));
+ assert_int(
+ 0, ==,
+ nghttp2_gzip_inflate(inflater, out, &outproclen, inptr, &inproclen));
+ assert_size(32, ==, outproclen);
+ assert_size(0, <, inproclen);
+ assert_memory_equal(outproclen, inputptr, out);
/* Rest */
inptr += inproclen;
inlen -= inproclen;
inproclen = inlen;
inputptr += outproclen;
outproclen = sizeof(out);
- CU_ASSERT(
- 0 == nghttp2_gzip_inflate(inflater, out, &outproclen, inptr, &inproclen));
- CU_ASSERT(sizeof(input) - 49 == outproclen);
- CU_ASSERT(inproclen > 0);
- CU_ASSERT(0 == memcmp(inputptr, out, outproclen));
+ assert_int(
+ 0, ==,
+ nghttp2_gzip_inflate(inflater, out, &outproclen, inptr, &inproclen));
+ assert_size(sizeof(input) - 49, ==, outproclen);
+ assert_size(0, <, inproclen);
+ assert_memory_equal(outproclen, inputptr, out);
inlen -= inproclen;
- CU_ASSERT(0 == inlen);
+ assert_size(0, ==, inlen);
nghttp2_gzip_inflate_del(inflater);
}
diff --git a/src/nghttp2_gzip_test.h b/src/nghttp2_gzip_test.h
index 8d554f7..fa6938b 100644
--- a/src/nghttp2_gzip_test.h
+++ b/src/nghttp2_gzip_test.h
@@ -33,7 +33,13 @@
extern "C" {
#endif
-void test_nghttp2_gzip_inflate(void);
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
+extern const MunitSuite gzip_suite;
+
+munit_void_test_decl(test_nghttp2_gzip_inflate);
#ifdef __cplusplus
}
diff --git a/src/shrpx-unittest.cc b/src/shrpx-unittest.cc
index f089adf..ec707e5 100644
--- a/src/shrpx-unittest.cc
+++ b/src/shrpx-unittest.cc
@@ -26,9 +26,8 @@
# include <config.h>
#endif // HAVE_CONFIG_H
-#include <stdio.h>
-#include <string.h>
-#include <CUnit/Basic.h>
+#include "munit.h"
+
// include test cases' include files here
#include "shrpx_tls_test.h"
#include "shrpx_downstream_test.h"
@@ -47,200 +46,21 @@
#include "shrpx_router_test.h"
#include "shrpx_log.h"
-static int init_suite1(void) { return 0; }
-
-static int clean_suite1(void) { return 0; }
-
int main(int argc, char *argv[]) {
- CU_pSuite pSuite = nullptr;
- unsigned int num_tests_failed;
-
shrpx::create_config();
- // initialize the CUnit test registry
- if (CUE_SUCCESS != CU_initialize_registry())
- return CU_get_error();
-
- // add a suite to the registry
- pSuite = CU_add_suite("shrpx_TestSuite", init_suite1, clean_suite1);
- if (nullptr == pSuite) {
- CU_cleanup_registry();
- return CU_get_error();
- }
-
- // add the tests to the suite
- if (!CU_add_test(pSuite, "tls_create_lookup_tree",
- shrpx::test_shrpx_tls_create_lookup_tree) ||
- !CU_add_test(pSuite, "tls_cert_lookup_tree_add_ssl_ctx",
- shrpx::test_shrpx_tls_cert_lookup_tree_add_ssl_ctx) ||
- !CU_add_test(pSuite, "tls_tls_hostname_match",
- shrpx::test_shrpx_tls_tls_hostname_match) ||
- !CU_add_test(pSuite, "tls_tls_verify_numeric_hostname",
- shrpx::test_shrpx_tls_verify_numeric_hostname) ||
- !CU_add_test(pSuite, "tls_tls_verify_dns_hostname",
- shrpx::test_shrpx_tls_verify_dns_hostname) ||
- !CU_add_test(pSuite, "http2_add_header", shrpx::test_http2_add_header) ||
- !CU_add_test(pSuite, "http2_get_header", shrpx::test_http2_get_header) ||
- !CU_add_test(pSuite, "http2_copy_headers_to_nva",
- shrpx::test_http2_copy_headers_to_nva) ||
- !CU_add_test(pSuite, "http2_build_http1_headers_from_headers",
- shrpx::test_http2_build_http1_headers_from_headers) ||
- !CU_add_test(pSuite, "http2_lws", shrpx::test_http2_lws) ||
- !CU_add_test(pSuite, "http2_rewrite_location_uri",
- shrpx::test_http2_rewrite_location_uri) ||
- !CU_add_test(pSuite, "http2_parse_http_status_code",
- shrpx::test_http2_parse_http_status_code) ||
- !CU_add_test(pSuite, "http2_index_header",
- shrpx::test_http2_index_header) ||
- !CU_add_test(pSuite, "http2_lookup_token",
- shrpx::test_http2_lookup_token) ||
- !CU_add_test(pSuite, "http2_parse_link_header",
- shrpx::test_http2_parse_link_header) ||
- !CU_add_test(pSuite, "http2_path_join", shrpx::test_http2_path_join) ||
- !CU_add_test(pSuite, "http2_normalize_path",
- shrpx::test_http2_normalize_path) ||
- !CU_add_test(pSuite, "http2_rewrite_clean_path",
- shrpx::test_http2_rewrite_clean_path) ||
- !CU_add_test(pSuite, "http2_get_pure_path_component",
- shrpx::test_http2_get_pure_path_component) ||
- !CU_add_test(pSuite, "http2_construct_push_component",
- shrpx::test_http2_construct_push_component) ||
- !CU_add_test(pSuite, "http2_contains_trailers",
- shrpx::test_http2_contains_trailers) ||
- !CU_add_test(pSuite, "http2_check_transfer_encoding",
- shrpx::test_http2_check_transfer_encoding) ||
- !CU_add_test(pSuite, "downstream_field_store_append_last_header",
- shrpx::test_downstream_field_store_append_last_header) ||
- !CU_add_test(pSuite, "downstream_field_store_header",
- shrpx::test_downstream_field_store_header) ||
- !CU_add_test(pSuite, "downstream_crumble_request_cookie",
- shrpx::test_downstream_crumble_request_cookie) ||
- !CU_add_test(pSuite, "downstream_assemble_request_cookie",
- shrpx::test_downstream_assemble_request_cookie) ||
- !CU_add_test(pSuite, "downstream_rewrite_location_response_header",
- shrpx::test_downstream_rewrite_location_response_header) ||
- !CU_add_test(pSuite, "downstream_supports_non_final_response",
- shrpx::test_downstream_supports_non_final_response) ||
- !CU_add_test(pSuite, "downstream_find_affinity_cookie",
- shrpx::test_downstream_find_affinity_cookie) ||
- !CU_add_test(pSuite, "config_parse_header",
- shrpx::test_shrpx_config_parse_header) ||
- !CU_add_test(pSuite, "config_parse_log_format",
- shrpx::test_shrpx_config_parse_log_format) ||
- !CU_add_test(pSuite, "config_read_tls_ticket_key_file",
- shrpx::test_shrpx_config_read_tls_ticket_key_file) ||
- !CU_add_test(pSuite, "config_read_tls_ticket_key_file_aes_256",
- shrpx::test_shrpx_config_read_tls_ticket_key_file_aes_256) ||
- !CU_add_test(pSuite, "worker_match_downstream_addr_group",
- shrpx::test_shrpx_worker_match_downstream_addr_group) ||
- !CU_add_test(pSuite, "http_create_forwarded",
- shrpx::test_shrpx_http_create_forwarded) ||
- !CU_add_test(pSuite, "http_create_via_header_value",
- shrpx::test_shrpx_http_create_via_header_value) ||
- !CU_add_test(pSuite, "http_create_affinity_cookie",
- shrpx::test_shrpx_http_create_affinity_cookie) ||
- !CU_add_test(pSuite, "http_create_atlsvc_header_field_value",
- shrpx::test_shrpx_http_create_altsvc_header_value) ||
- !CU_add_test(pSuite, "http_check_http_scheme",
- shrpx::test_shrpx_http_check_http_scheme) ||
- !CU_add_test(pSuite, "router_match", shrpx::test_shrpx_router_match) ||
- !CU_add_test(pSuite, "router_match_wildcard",
- shrpx::test_shrpx_router_match_wildcard) ||
- !CU_add_test(pSuite, "router_match_prefix",
- shrpx::test_shrpx_router_match_prefix) ||
- !CU_add_test(pSuite, "util_streq", shrpx::test_util_streq) ||
- !CU_add_test(pSuite, "util_strieq", shrpx::test_util_strieq) ||
- !CU_add_test(pSuite, "util_inp_strlower",
- shrpx::test_util_inp_strlower) ||
- !CU_add_test(pSuite, "util_to_base64", shrpx::test_util_to_base64) ||
- !CU_add_test(pSuite, "util_to_token68", shrpx::test_util_to_token68) ||
- !CU_add_test(pSuite, "util_percent_encode_token",
- shrpx::test_util_percent_encode_token) ||
- !CU_add_test(pSuite, "util_percent_decode",
- shrpx::test_util_percent_decode) ||
- !CU_add_test(pSuite, "util_quote_string",
- shrpx::test_util_quote_string) ||
- !CU_add_test(pSuite, "util_utox", shrpx::test_util_utox) ||
- !CU_add_test(pSuite, "util_http_date", shrpx::test_util_http_date) ||
- !CU_add_test(pSuite, "util_select_h2", shrpx::test_util_select_h2) ||
- !CU_add_test(pSuite, "util_ipv6_numeric_addr",
- shrpx::test_util_ipv6_numeric_addr) ||
- !CU_add_test(pSuite, "util_utos", shrpx::test_util_utos) ||
- !CU_add_test(pSuite, "util_make_string_ref_uint",
- shrpx::test_util_make_string_ref_uint) ||
- !CU_add_test(pSuite, "util_utos_unit", shrpx::test_util_utos_unit) ||
- !CU_add_test(pSuite, "util_utos_funit", shrpx::test_util_utos_funit) ||
- !CU_add_test(pSuite, "util_parse_uint_with_unit",
- shrpx::test_util_parse_uint_with_unit) ||
- !CU_add_test(pSuite, "util_parse_uint", shrpx::test_util_parse_uint) ||
- !CU_add_test(pSuite, "util_parse_duration_with_unit",
- shrpx::test_util_parse_duration_with_unit) ||
- !CU_add_test(pSuite, "util_duration_str",
- shrpx::test_util_duration_str) ||
- !CU_add_test(pSuite, "util_format_duration",
- shrpx::test_util_format_duration) ||
- !CU_add_test(pSuite, "util_starts_with", shrpx::test_util_starts_with) ||
- !CU_add_test(pSuite, "util_ends_with", shrpx::test_util_ends_with) ||
- !CU_add_test(pSuite, "util_parse_http_date",
- shrpx::test_util_parse_http_date) ||
- !CU_add_test(pSuite, "util_localtime_date",
- shrpx::test_util_localtime_date) ||
- !CU_add_test(pSuite, "util_get_uint64", shrpx::test_util_get_uint64) ||
- !CU_add_test(pSuite, "util_parse_config_str_list",
- shrpx::test_util_parse_config_str_list) ||
- !CU_add_test(pSuite, "util_make_http_hostport",
- shrpx::test_util_make_http_hostport) ||
- !CU_add_test(pSuite, "util_make_hostport",
- shrpx::test_util_make_hostport) ||
- !CU_add_test(pSuite, "util_strifind", shrpx::test_util_strifind) ||
- !CU_add_test(pSuite, "util_random_alpha_digit",
- shrpx::test_util_random_alpha_digit) ||
- !CU_add_test(pSuite, "util_format_hex", shrpx::test_util_format_hex) ||
- !CU_add_test(pSuite, "util_is_hex_string",
- shrpx::test_util_is_hex_string) ||
- !CU_add_test(pSuite, "util_decode_hex", shrpx::test_util_decode_hex) ||
- !CU_add_test(pSuite, "util_extract_host",
- shrpx::test_util_extract_host) ||
- !CU_add_test(pSuite, "util_split_hostport",
- shrpx::test_util_split_hostport) ||
- !CU_add_test(pSuite, "util_split_str", shrpx::test_util_split_str) ||
- !CU_add_test(pSuite, "util_rstrip", shrpx::test_util_rstrip) ||
- !CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate) ||
- !CU_add_test(pSuite, "buffer_write", nghttp2::test_buffer_write) ||
- !CU_add_test(pSuite, "pool_recycle", nghttp2::test_pool_recycle) ||
- !CU_add_test(pSuite, "memchunk_append", nghttp2::test_memchunks_append) ||
- !CU_add_test(pSuite, "memchunk_drain", nghttp2::test_memchunks_drain) ||
- !CU_add_test(pSuite, "memchunk_riovec", nghttp2::test_memchunks_riovec) ||
- !CU_add_test(pSuite, "memchunk_recycle",
- nghttp2::test_memchunks_recycle) ||
- !CU_add_test(pSuite, "memchunk_reset", nghttp2::test_memchunks_reset) ||
- !CU_add_test(pSuite, "peek_memchunk_append",
- nghttp2::test_peek_memchunks_append) ||
- !CU_add_test(pSuite, "peek_memchunk_disable_peek_drain",
- nghttp2::test_peek_memchunks_disable_peek_drain) ||
- !CU_add_test(pSuite, "peek_memchunk_disable_peek_no_drain",
- nghttp2::test_peek_memchunks_disable_peek_no_drain) ||
- !CU_add_test(pSuite, "peek_memchunk_reset",
- nghttp2::test_peek_memchunks_reset) ||
- !CU_add_test(pSuite, "template_immutable_string",
- nghttp2::test_template_immutable_string) ||
- !CU_add_test(pSuite, "template_string_ref",
- nghttp2::test_template_string_ref) ||
- !CU_add_test(pSuite, "base64_encode", nghttp2::test_base64_encode) ||
- !CU_add_test(pSuite, "base64_decode", nghttp2::test_base64_decode)) {
- CU_cleanup_registry();
- return CU_get_error();
- }
+ const MunitSuite suites[] = {
+ shrpx::tls_suite, shrpx::downstream_suite,
+ shrpx::config_suite, shrpx::worker_suite,
+ shrpx::http_suite, shrpx::router_suite,
+ shrpx::http2_suite, shrpx::util_suite,
+ gzip_suite, buffer_suite,
+ memchunk_suite, template_suite,
+ base64_suite, {NULL, NULL, NULL, 0, MUNIT_SUITE_OPTION_NONE},
+ };
+ const MunitSuite suite = {
+ "", NULL, suites, 1, MUNIT_SUITE_OPTION_NONE,
+ };
- // Run all tests using the CUnit Basic interface
- CU_basic_set_mode(CU_BRM_VERBOSE);
- CU_basic_run_tests();
- num_tests_failed = CU_get_number_of_tests_failed();
- CU_cleanup_registry();
- if (CU_get_error() == CUE_SUCCESS) {
- return num_tests_failed;
- } else {
- printf("CUnit Error: %s\n", CU_get_error_msg());
- return CU_get_error();
- }
+ return munit_suite_main(&suite, NULL, argc, argv);
}
diff --git a/src/shrpx.h b/src/shrpx.h
index d881ef5..e6379bd 100644
--- a/src/shrpx.h
+++ b/src/shrpx.h
@@ -36,6 +36,8 @@
#include <cassert>
+#define NGHTTP2_NO_SSIZE_T
+
#ifndef HAVE__EXIT
# define nghttp2_Exit(status) _exit(status)
#else // HAVE__EXIT
diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc
index d6d0d07..89b3672 100644
--- a/src/shrpx_config.cc
+++ b/src/shrpx_config.cc
@@ -49,6 +49,8 @@
#include <fstream>
#include <unordered_map>
+#include <openssl/evp.h>
+
#include <nghttp2/nghttp2.h>
#include "url-parser/url_parser.h"
@@ -64,6 +66,10 @@
#include "ssl_compat.h"
#include "xsi_strerror.h"
+#ifndef AI_NUMERICSERV
+# define AI_NUMERICSERV 0
+#endif
+
namespace shrpx {
namespace {
@@ -4691,4 +4697,32 @@ int resolve_hostname(Address *addr, const char *hostname, uint16_t port,
return 0;
}
+#ifdef ENABLE_HTTP3
+QUICKeyingMaterial::QUICKeyingMaterial(QUICKeyingMaterial &&other) noexcept
+ : cid_encryption_ctx{std::exchange(other.cid_encryption_ctx, nullptr)},
+ reserved{other.reserved},
+ secret{other.secret},
+ salt{other.salt},
+ cid_encryption_key{other.cid_encryption_key},
+ id{other.id} {}
+
+QUICKeyingMaterial::~QUICKeyingMaterial() noexcept {
+ if (cid_encryption_ctx) {
+ EVP_CIPHER_CTX_free(cid_encryption_ctx);
+ }
+}
+
+QUICKeyingMaterial &
+QUICKeyingMaterial::operator=(QUICKeyingMaterial &&other) noexcept {
+ cid_encryption_ctx = std::exchange(other.cid_encryption_ctx, nullptr);
+ reserved = other.reserved;
+ secret = other.secret;
+ salt = other.salt;
+ cid_encryption_key = other.cid_encryption_key;
+ id = other.id;
+
+ return *this;
+}
+#endif // ENABLE_HTTP3
+
} // namespace shrpx
diff --git a/src/shrpx_config.h b/src/shrpx_config.h
index 7f316eb..335b0f9 100644
--- a/src/shrpx_config.h
+++ b/src/shrpx_config.h
@@ -636,6 +636,11 @@ struct TLSCertificate {
#ifdef ENABLE_HTTP3
struct QUICKeyingMaterial {
+ QUICKeyingMaterial() noexcept = default;
+ QUICKeyingMaterial(QUICKeyingMaterial &&other) noexcept;
+ ~QUICKeyingMaterial() noexcept;
+ QUICKeyingMaterial &operator=(QUICKeyingMaterial &&other) noexcept;
+ EVP_CIPHER_CTX *cid_encryption_ctx;
std::array<uint8_t, SHRPX_QUIC_SECRET_RESERVEDLEN> reserved;
std::array<uint8_t, SHRPX_QUIC_SECRETLEN> secret;
std::array<uint8_t, SHRPX_QUIC_SALTLEN> salt;
diff --git a/src/shrpx_config_test.cc b/src/shrpx_config_test.cc
index a8f0962..068f185 100644
--- a/src/shrpx_config_test.cc
+++ b/src/shrpx_config_test.cc
@@ -30,43 +30,57 @@
#include <cstdlib>
-#include <CUnit/CUnit.h>
+#include "munitxx.h"
#include "shrpx_config.h"
#include "shrpx_log.h"
namespace shrpx {
+namespace {
+const MunitTest tests[]{
+ munit_void_test(test_shrpx_config_parse_header),
+ munit_void_test(test_shrpx_config_parse_log_format),
+ munit_void_test(test_shrpx_config_read_tls_ticket_key_file),
+ munit_void_test(test_shrpx_config_read_tls_ticket_key_file_aes_256),
+ munit_test_end(),
+};
+} // namespace
+
+const MunitSuite config_suite{
+ "/config_suite", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
void test_shrpx_config_parse_header(void) {
BlockAllocator balloc(4096, 4096);
auto p = parse_header(balloc, StringRef::from_lit("a: b"));
- CU_ASSERT("a" == p.name);
- CU_ASSERT("b" == p.value);
+ assert_stdstring_equal("a", p.name.str());
+ assert_stdstring_equal("b", p.value.str());
p = parse_header(balloc, StringRef::from_lit("a: b"));
- CU_ASSERT("a" == p.name);
- CU_ASSERT("b" == p.value);
+ assert_stdstring_equal("a", p.name.str());
+ assert_stdstring_equal("b", p.value.str());
p = parse_header(balloc, StringRef::from_lit(":a: b"));
- CU_ASSERT(p.name.empty());
+ assert_true(p.name.empty());
p = parse_header(balloc, StringRef::from_lit("a: :b"));
- CU_ASSERT("a" == p.name);
- CU_ASSERT(":b" == p.value);
+ assert_stdstring_equal("a", p.name.str());
+ assert_stdstring_equal(":b", p.value.str());
p = parse_header(balloc, StringRef::from_lit(": b"));
- CU_ASSERT(p.name.empty());
+ assert_true(p.name.empty());
p = parse_header(balloc, StringRef::from_lit("alpha: bravo charlie"));
- CU_ASSERT("alpha" == p.name);
- CU_ASSERT("bravo charlie" == p.value);
+ assert_stdstring_equal("alpha", p.name.str());
+ assert_stdstring_equal("bravo charlie", p.value.str());
p = parse_header(balloc, StringRef::from_lit("a,: b"));
- CU_ASSERT(p.name.empty());
+ assert_true(p.name.empty());
p = parse_header(balloc, StringRef::from_lit("a: b\x0a"));
- CU_ASSERT(p.name.empty());
+ assert_true(p.name.empty());
}
void test_shrpx_config_parse_log_format(void) {
@@ -77,100 +91,102 @@ void test_shrpx_config_parse_log_format(void) {
R"($remote_addr - $remote_user [$time_local] )"
R"("$request" $status $body_bytes_sent )"
R"("${http_referer}" $http_host "$http_user_agent")"));
- CU_ASSERT(16 == res.size());
+ assert_size(16, ==, res.size());
- CU_ASSERT(LogFragmentType::REMOTE_ADDR == res[0].type);
+ assert_enum_class(LogFragmentType::REMOTE_ADDR, ==, res[0].type);
- CU_ASSERT(LogFragmentType::LITERAL == res[1].type);
- CU_ASSERT(" - $remote_user [" == res[1].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[1].type);
+ assert_stdstring_equal(" - $remote_user [", res[1].value.str());
- CU_ASSERT(LogFragmentType::TIME_LOCAL == res[2].type);
+ assert_enum_class(LogFragmentType::TIME_LOCAL, ==, res[2].type);
- CU_ASSERT(LogFragmentType::LITERAL == res[3].type);
- CU_ASSERT("] \"" == res[3].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[3].type);
+ assert_stdstring_equal("] \"", res[3].value.str());
- CU_ASSERT(LogFragmentType::REQUEST == res[4].type);
+ assert_enum_class(LogFragmentType::REQUEST, ==, res[4].type);
- CU_ASSERT(LogFragmentType::LITERAL == res[5].type);
- CU_ASSERT("\" " == res[5].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[5].type);
+ assert_stdstring_equal("\" ", res[5].value.str());
- CU_ASSERT(LogFragmentType::STATUS == res[6].type);
+ assert_enum_class(LogFragmentType::STATUS, ==, res[6].type);
- CU_ASSERT(LogFragmentType::LITERAL == res[7].type);
- CU_ASSERT(" " == res[7].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[7].type);
+ assert_stdstring_equal(" ", res[7].value.str());
- CU_ASSERT(LogFragmentType::BODY_BYTES_SENT == res[8].type);
+ assert_enum_class(LogFragmentType::BODY_BYTES_SENT, ==, res[8].type);
- CU_ASSERT(LogFragmentType::LITERAL == res[9].type);
- CU_ASSERT(" \"" == res[9].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[9].type);
+ assert_stdstring_equal(" \"", res[9].value.str());
- CU_ASSERT(LogFragmentType::HTTP == res[10].type);
- CU_ASSERT("referer" == res[10].value);
+ assert_enum_class(LogFragmentType::HTTP, ==, res[10].type);
+ assert_stdstring_equal("referer", res[10].value.str());
- CU_ASSERT(LogFragmentType::LITERAL == res[11].type);
- CU_ASSERT("\" " == res[11].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[11].type);
+ assert_stdstring_equal("\" ", res[11].value.str());
- CU_ASSERT(LogFragmentType::AUTHORITY == res[12].type);
+ assert_enum_class(LogFragmentType::AUTHORITY, ==, res[12].type);
- CU_ASSERT(LogFragmentType::LITERAL == res[13].type);
- CU_ASSERT(" \"" == res[13].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[13].type);
+ assert_stdstring_equal(" \"", res[13].value.str());
- CU_ASSERT(LogFragmentType::HTTP == res[14].type);
- CU_ASSERT("user-agent" == res[14].value);
+ assert_enum_class(LogFragmentType::HTTP, ==, res[14].type);
+ assert_stdstring_equal("user-agent", res[14].value.str());
- CU_ASSERT(LogFragmentType::LITERAL == res[15].type);
- CU_ASSERT("\"" == res[15].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[15].type);
+ assert_stdstring_equal("\"", res[15].value.str());
res = parse_log_format(balloc, StringRef::from_lit("$"));
- CU_ASSERT(1 == res.size());
+ assert_size(1, ==, res.size());
- CU_ASSERT(LogFragmentType::LITERAL == res[0].type);
- CU_ASSERT("$" == res[0].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[0].type);
+ assert_stdstring_equal("$", res[0].value.str());
res = parse_log_format(balloc, StringRef::from_lit("${"));
- CU_ASSERT(1 == res.size());
+ assert_size(1, ==, res.size());
- CU_ASSERT(LogFragmentType::LITERAL == res[0].type);
- CU_ASSERT("${" == res[0].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[0].type);
+ assert_stdstring_equal("${", res[0].value.str());
res = parse_log_format(balloc, StringRef::from_lit("${a"));
- CU_ASSERT(1 == res.size());
+ assert_size(1, ==, res.size());
- CU_ASSERT(LogFragmentType::LITERAL == res[0].type);
- CU_ASSERT("${a" == res[0].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[0].type);
+ assert_stdstring_equal("${a", res[0].value.str());
res = parse_log_format(balloc, StringRef::from_lit("${a "));
- CU_ASSERT(1 == res.size());
+ assert_size(1, ==, res.size());
- CU_ASSERT(LogFragmentType::LITERAL == res[0].type);
- CU_ASSERT("${a " == res[0].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[0].type);
+ assert_stdstring_equal("${a ", res[0].value.str());
res = parse_log_format(balloc, StringRef::from_lit("$$remote_addr"));
- CU_ASSERT(2 == res.size());
+ assert_size(2, ==, res.size());
- CU_ASSERT(LogFragmentType::LITERAL == res[0].type);
- CU_ASSERT("$" == res[0].value);
+ assert_enum_class(LogFragmentType::LITERAL, ==, res[0].type);
+ assert_stdstring_equal("$", res[0].value.str());
- CU_ASSERT(LogFragmentType::REMOTE_ADDR == res[1].type);
- CU_ASSERT("" == res[1].value);
+ assert_enum_class(LogFragmentType::REMOTE_ADDR, ==, res[1].type);
+ assert_stdstring_equal("", res[1].value.str());
}
void test_shrpx_config_read_tls_ticket_key_file(void) {
char file1[] = "/tmp/nghttpx-unittest.XXXXXX";
auto fd1 = mkstemp(file1);
- CU_ASSERT(fd1 != -1);
- CU_ASSERT(48 ==
- write(fd1, "0..............12..............34..............5", 48));
+ assert_int(-1, !=, fd1);
+ assert_ssize(
+ 48, ==,
+ write(fd1, "0..............12..............34..............5", 48));
char file2[] = "/tmp/nghttpx-unittest.XXXXXX";
auto fd2 = mkstemp(file2);
- CU_ASSERT(fd2 != -1);
- CU_ASSERT(48 ==
- write(fd2, "6..............78..............9a..............b", 48));
+ assert_int(-1, !=, fd2);
+ assert_ssize(
+ 48, ==,
+ write(fd2, "6..............78..............9a..............b", 48));
close(fd1);
close(fd2);
@@ -178,44 +194,48 @@ void test_shrpx_config_read_tls_ticket_key_file(void) {
{StringRef{file1}, StringRef{file2}}, EVP_aes_128_cbc(), EVP_sha256());
unlink(file1);
unlink(file2);
- CU_ASSERT(ticket_keys.get() != nullptr);
- CU_ASSERT(2 == ticket_keys->keys.size());
+ assert_not_null(ticket_keys.get());
+ assert_size(2, ==, ticket_keys->keys.size());
auto key = &ticket_keys->keys[0];
- CU_ASSERT(std::equal(std::begin(key->data.name), std::end(key->data.name),
- "0..............1"));
- CU_ASSERT(std::equal(std::begin(key->data.enc_key),
- std::begin(key->data.enc_key) + 16, "2..............3"));
- CU_ASSERT(std::equal(std::begin(key->data.hmac_key),
- std::begin(key->data.hmac_key) + 16,
- "4..............5"));
- CU_ASSERT(16 == key->hmac_keylen);
+ assert_true(std::equal(std::begin(key->data.name), std::end(key->data.name),
+ "0..............1"));
+ assert_true(std::equal(std::begin(key->data.enc_key),
+ std::begin(key->data.enc_key) + 16,
+ "2..............3"));
+ assert_true(std::equal(std::begin(key->data.hmac_key),
+ std::begin(key->data.hmac_key) + 16,
+ "4..............5"));
+ assert_size(16, ==, key->hmac_keylen);
key = &ticket_keys->keys[1];
- CU_ASSERT(std::equal(std::begin(key->data.name), std::end(key->data.name),
- "6..............7"));
- CU_ASSERT(std::equal(std::begin(key->data.enc_key),
- std::begin(key->data.enc_key) + 16, "8..............9"));
- CU_ASSERT(std::equal(std::begin(key->data.hmac_key),
- std::begin(key->data.hmac_key) + 16,
- "a..............b"));
- CU_ASSERT(16 == key->hmac_keylen);
+ assert_true(std::equal(std::begin(key->data.name), std::end(key->data.name),
+ "6..............7"));
+ assert_true(std::equal(std::begin(key->data.enc_key),
+ std::begin(key->data.enc_key) + 16,
+ "8..............9"));
+ assert_true(std::equal(std::begin(key->data.hmac_key),
+ std::begin(key->data.hmac_key) + 16,
+ "a..............b"));
+ assert_size(16, ==, key->hmac_keylen);
}
void test_shrpx_config_read_tls_ticket_key_file_aes_256(void) {
char file1[] = "/tmp/nghttpx-unittest.XXXXXX";
auto fd1 = mkstemp(file1);
- CU_ASSERT(fd1 != -1);
- CU_ASSERT(80 == write(fd1,
- "0..............12..............................34..."
- "...........................5",
- 80));
+ assert_int(-1, !=, fd1);
+ assert_ssize(80, ==,
+ write(fd1,
+ "0..............12..............................34..."
+ "...........................5",
+ 80));
char file2[] = "/tmp/nghttpx-unittest.XXXXXX";
auto fd2 = mkstemp(file2);
- CU_ASSERT(fd2 != -1);
- CU_ASSERT(80 == write(fd2,
- "6..............78..............................9a..."
- "...........................b",
- 80));
+ assert_int(-1, !=, fd2);
+ assert_ssize(80, ==,
+ write(fd2,
+ "6..............78..............................9a..."
+ "...........................b",
+ 80));
close(fd1);
close(fd2);
@@ -223,27 +243,27 @@ void test_shrpx_config_read_tls_ticket_key_file_aes_256(void) {
{StringRef{file1}, StringRef{file2}}, EVP_aes_256_cbc(), EVP_sha256());
unlink(file1);
unlink(file2);
- CU_ASSERT(ticket_keys.get() != nullptr);
- CU_ASSERT(2 == ticket_keys->keys.size());
+ assert_not_null(ticket_keys.get());
+ assert_size(2, ==, ticket_keys->keys.size());
auto key = &ticket_keys->keys[0];
- CU_ASSERT(std::equal(std::begin(key->data.name), std::end(key->data.name),
- "0..............1"));
- CU_ASSERT(std::equal(std::begin(key->data.enc_key),
- std::end(key->data.enc_key),
- "2..............................3"));
- CU_ASSERT(std::equal(std::begin(key->data.hmac_key),
- std::end(key->data.hmac_key),
- "4..............................5"));
+ assert_true(std::equal(std::begin(key->data.name), std::end(key->data.name),
+ "0..............1"));
+ assert_true(std::equal(std::begin(key->data.enc_key),
+ std::end(key->data.enc_key),
+ "2..............................3"));
+ assert_true(std::equal(std::begin(key->data.hmac_key),
+ std::end(key->data.hmac_key),
+ "4..............................5"));
key = &ticket_keys->keys[1];
- CU_ASSERT(std::equal(std::begin(key->data.name), std::end(key->data.name),
- "6..............7"));
- CU_ASSERT(std::equal(std::begin(key->data.enc_key),
- std::end(key->data.enc_key),
- "8..............................9"));
- CU_ASSERT(std::equal(std::begin(key->data.hmac_key),
- std::end(key->data.hmac_key),
- "a..............................b"));
+ assert_true(std::equal(std::begin(key->data.name), std::end(key->data.name),
+ "6..............7"));
+ assert_true(std::equal(std::begin(key->data.enc_key),
+ std::end(key->data.enc_key),
+ "8..............................9"));
+ assert_true(std::equal(std::begin(key->data.hmac_key),
+ std::end(key->data.hmac_key),
+ "a..............................b"));
}
} // namespace shrpx
diff --git a/src/shrpx_config_test.h b/src/shrpx_config_test.h
index a30de41..9863101 100644
--- a/src/shrpx_config_test.h
+++ b/src/shrpx_config_test.h
@@ -29,13 +29,18 @@
# include <config.h>
#endif // HAVE_CONFIG_H
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
namespace shrpx {
-void test_shrpx_config_parse_header(void);
-void test_shrpx_config_parse_log_format(void);
-void test_shrpx_config_read_tls_ticket_key_file(void);
-void test_shrpx_config_read_tls_ticket_key_file_aes_256(void);
-void test_shrpx_config_match_downstream_addr_group(void);
+extern const MunitSuite config_suite;
+
+munit_void_test_decl(test_shrpx_config_parse_header);
+munit_void_test_decl(test_shrpx_config_parse_log_format);
+munit_void_test_decl(test_shrpx_config_read_tls_ticket_key_file);
+munit_void_test_decl(test_shrpx_config_read_tls_ticket_key_file_aes_256);
} // namespace shrpx
diff --git a/src/shrpx_connection.cc b/src/shrpx_connection.cc
index a5ab390..d863284 100644
--- a/src/shrpx_connection.cc
+++ b/src/shrpx_connection.cc
@@ -863,7 +863,7 @@ void Connection::start_tls_write_idle() {
}
}
-ssize_t Connection::write_tls(const void *data, size_t len) {
+nghttp2_ssize Connection::write_tls(const void *data, size_t len) {
// SSL_write requires the same arguments (buf pointer and its
// length) on SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE.
// get_write_limit() may return smaller length than previously
@@ -950,7 +950,7 @@ ssize_t Connection::write_tls(const void *data, size_t len) {
return rv;
}
-ssize_t Connection::read_tls(void *data, size_t len) {
+nghttp2_ssize Connection::read_tls(void *data, size_t len) {
ERR_clear_error();
#if defined(NGHTTP2_GENUINE_OPENSSL) || defined(NGHTTP2_OPENSSL_IS_BORINGSSL)
@@ -1061,7 +1061,7 @@ ssize_t Connection::read_tls(void *data, size_t len) {
return rv;
}
-ssize_t Connection::write_clear(const void *data, size_t len) {
+nghttp2_ssize Connection::write_clear(const void *data, size_t len) {
len = std::min(len, wlimit.avail());
if (len == 0) {
return 0;
@@ -1088,7 +1088,7 @@ ssize_t Connection::write_clear(const void *data, size_t len) {
return nwrite;
}
-ssize_t Connection::writev_clear(struct iovec *iov, int iovcnt) {
+nghttp2_ssize Connection::writev_clear(struct iovec *iov, int iovcnt) {
iovcnt = limit_iovec(iov, iovcnt, wlimit.avail());
if (iovcnt == 0) {
return 0;
@@ -1115,7 +1115,7 @@ ssize_t Connection::writev_clear(struct iovec *iov, int iovcnt) {
return nwrite;
}
-ssize_t Connection::read_clear(void *data, size_t len) {
+nghttp2_ssize Connection::read_clear(void *data, size_t len) {
len = std::min(len, rlimit.avail());
if (len == 0) {
return 0;
@@ -1140,7 +1140,7 @@ ssize_t Connection::read_clear(void *data, size_t len) {
return nread;
}
-ssize_t Connection::read_nolim_clear(void *data, size_t len) {
+nghttp2_ssize Connection::read_nolim_clear(void *data, size_t len) {
ssize_t nread;
while ((nread = read(fd, data, len)) == -1 && errno == EINTR)
;
@@ -1158,7 +1158,7 @@ ssize_t Connection::read_nolim_clear(void *data, size_t len) {
return nread;
}
-ssize_t Connection::peek_clear(void *data, size_t len) {
+nghttp2_ssize Connection::peek_clear(void *data, size_t len) {
ssize_t nread;
while ((nread = recv(fd, data, len, MSG_PEEK)) == -1 && errno == EINTR)
;
diff --git a/src/shrpx_connection.h b/src/shrpx_connection.h
index 10526f7..2db2588 100644
--- a/src/shrpx_connection.h
+++ b/src/shrpx_connection.h
@@ -33,6 +33,8 @@
#include <openssl/ssl.h>
+#include <nghttp2/nghttp2.h>
+
#ifdef ENABLE_HTTP3
# include <ngtcp2/ngtcp2_crypto.h>
#endif // ENABLE_HTTP3
@@ -128,8 +130,8 @@ struct Connection {
// underlying connection blocks), return 0. SHRPX_ERR_EOF is
// returned in case of EOF and no data was read. Otherwise
// SHRPX_ERR_NETWORK is return in case of error.
- ssize_t write_tls(const void *data, size_t len);
- ssize_t read_tls(void *data, size_t len);
+ nghttp2_ssize write_tls(const void *data, size_t len);
+ nghttp2_ssize read_tls(void *data, size_t len);
size_t get_tls_write_limit();
// Updates the number of bytes written in warm up period.
@@ -138,13 +140,13 @@ struct Connection {
// determine fallback to short record size mode.
void start_tls_write_idle();
- ssize_t write_clear(const void *data, size_t len);
- ssize_t writev_clear(struct iovec *iov, int iovcnt);
- ssize_t read_clear(void *data, size_t len);
+ nghttp2_ssize write_clear(const void *data, size_t len);
+ nghttp2_ssize writev_clear(struct iovec *iov, int iovcnt);
+ nghttp2_ssize read_clear(void *data, size_t len);
// Read at most |len| bytes of data from socket without rate limit.
- ssize_t read_nolim_clear(void *data, size_t len);
+ nghttp2_ssize read_nolim_clear(void *data, size_t len);
// Peek at most |len| bytes of data from socket without rate limit.
- ssize_t peek_clear(void *data, size_t len);
+ nghttp2_ssize peek_clear(void *data, size_t len);
void handle_tls_pending_read();
diff --git a/src/shrpx_connection_handler.cc b/src/shrpx_connection_handler.cc
index 330e832..af4b8fc 100644
--- a/src/shrpx_connection_handler.cc
+++ b/src/shrpx_connection_handler.cc
@@ -739,40 +739,31 @@ void ConnectionHandler::handle_ocsp_complete() {
// that case we get nullptr.
auto quic_ssl_ctx = quic_all_ssl_ctx_[ocsp_.next];
if (quic_ssl_ctx) {
-# ifndef NGHTTP2_OPENSSL_IS_BORINGSSL
auto quic_tls_ctx_data = static_cast<tls::TLSContextData *>(
SSL_CTX_get_app_data(quic_ssl_ctx));
-# ifdef HAVE_ATOMIC_STD_SHARED_PTR
+# ifdef HAVE_ATOMIC_STD_SHARED_PTR
std::atomic_store_explicit(
&quic_tls_ctx_data->ocsp_data,
std::make_shared<std::vector<uint8_t>>(ocsp_.resp),
std::memory_order_release);
-# else // !HAVE_ATOMIC_STD_SHARED_PTR
+# else // !HAVE_ATOMIC_STD_SHARED_PTR
std::lock_guard<std::mutex> g(quic_tls_ctx_data->mu);
quic_tls_ctx_data->ocsp_data =
std::make_shared<std::vector<uint8_t>>(ocsp_.resp);
-# endif // !HAVE_ATOMIC_STD_SHARED_PTR
-# else // NGHTTP2_OPENSSL_IS_BORINGSSL
- SSL_CTX_set_ocsp_response(quic_ssl_ctx, ocsp_.resp.data(),
- ocsp_.resp.size());
-# endif // NGHTTP2_OPENSSL_IS_BORINGSSL
+# endif // !HAVE_ATOMIC_STD_SHARED_PTR
}
#endif // ENABLE_HTTP3
-#ifndef NGHTTP2_OPENSSL_IS_BORINGSSL
-# ifdef HAVE_ATOMIC_STD_SHARED_PTR
+#ifdef HAVE_ATOMIC_STD_SHARED_PTR
std::atomic_store_explicit(
&tls_ctx_data->ocsp_data,
std::make_shared<std::vector<uint8_t>>(std::move(ocsp_.resp)),
std::memory_order_release);
-# else // !HAVE_ATOMIC_STD_SHARED_PTR
+#else // !HAVE_ATOMIC_STD_SHARED_PTR
std::lock_guard<std::mutex> g(tls_ctx_data->mu);
tls_ctx_data->ocsp_data =
std::make_shared<std::vector<uint8_t>>(std::move(ocsp_.resp));
-# endif // !HAVE_ATOMIC_STD_SHARED_PTR
-#else // NGHTTP2_OPENSSL_IS_BORINGSSL
- SSL_CTX_set_ocsp_response(ssl_ctx, ocsp_.resp.data(), ocsp_.resp.size());
-#endif // NGHTTP2_OPENSSL_IS_BORINGSSL
+#endif // !HAVE_ATOMIC_STD_SHARED_PTR
}
++ocsp_.next;
@@ -1288,7 +1279,7 @@ int ConnectionHandler::quic_ipc_read() {
if (decrypt_quic_connection_id(decrypted_dcid.data(),
vc.dcid + SHRPX_QUIC_CID_PREFIX_OFFSET,
- qkm.cid_encryption_key.data()) != 0) {
+ qkm.cid_encryption_ctx) != 0) {
return -1;
}
diff --git a/src/shrpx_downstream_test.cc b/src/shrpx_downstream_test.cc
index 6100b18..46db9b7 100644
--- a/src/shrpx_downstream_test.cc
+++ b/src/shrpx_downstream_test.cc
@@ -26,12 +26,29 @@
#include <iostream>
-#include <CUnit/CUnit.h>
+#include "munitxx.h"
#include "shrpx_downstream.h"
namespace shrpx {
+namespace {
+const MunitTest tests[]{
+ munit_void_test(test_downstream_field_store_append_last_header),
+ munit_void_test(test_downstream_field_store_header),
+ munit_void_test(test_downstream_crumble_request_cookie),
+ munit_void_test(test_downstream_assemble_request_cookie),
+ munit_void_test(test_downstream_rewrite_location_response_header),
+ munit_void_test(test_downstream_supports_non_final_response),
+ munit_void_test(test_downstream_find_affinity_cookie),
+ munit_test_end(),
+};
+} // namespace
+
+const MunitSuite downstream_suite{
+ "/downstream", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
void test_downstream_field_store_append_last_header(void) {
BlockAllocator balloc(16, 16);
FieldStore fs(balloc, 0);
@@ -57,7 +74,7 @@ void test_downstream_field_store_append_last_header(void) {
HeaderRefs{{StringRef::from_lit("alphabravogolf0123456789"),
StringRef::from_lit("CharliedeltAecho0123456789")},
{StringRef::from_lit("echo"), StringRef::from_lit("foxtrot")}};
- CU_ASSERT(ans == fs.headers());
+ assert_true(ans == fs.headers());
}
void test_downstream_field_store_header(void) {
@@ -72,14 +89,14 @@ void test_downstream_field_store_header(void) {
http2::HD_CONTENT_LENGTH);
// By token
- CU_ASSERT(HeaderRef(StringRef{":authority"}, StringRef{"1"}) ==
- *fs.header(http2::HD__AUTHORITY));
- CU_ASSERT(nullptr == fs.header(http2::HD__METHOD));
+ assert_true(HeaderRef(StringRef{":authority"}, StringRef{"1"}) ==
+ *fs.header(http2::HD__AUTHORITY));
+ assert_null(fs.header(http2::HD__METHOD));
// By name
- CU_ASSERT(HeaderRef(StringRef{"alpha"}, StringRef{"0"}) ==
- *fs.header(StringRef::from_lit("alpha")));
- CU_ASSERT(nullptr == fs.header(StringRef::from_lit("bravo")));
+ assert_true(HeaderRef(StringRef{"alpha"}, StringRef{"0"}) ==
+ *fs.header(StringRef::from_lit("alpha")));
+ assert_null(fs.header(StringRef::from_lit("bravo")));
}
void test_downstream_crumble_request_cookie(void) {
@@ -103,8 +120,8 @@ void test_downstream_crumble_request_cookie(void) {
auto num_cookies = d.count_crumble_request_cookie();
- CU_ASSERT(5 == nva.size());
- CU_ASSERT(5 == num_cookies);
+ assert_size(5, ==, nva.size());
+ assert_size(5, ==, num_cookies);
HeaderRefs cookies;
std::transform(std::begin(nva), std::end(nva), std::back_inserter(cookies),
@@ -121,10 +138,10 @@ void test_downstream_crumble_request_cookie(void) {
{StringRef::from_lit("cookie"), StringRef::from_lit("delta")},
{StringRef::from_lit("cookie"), StringRef::from_lit("echo")}};
- CU_ASSERT(ans == cookies);
- CU_ASSERT(cookies[0].no_index);
- CU_ASSERT(cookies[1].no_index);
- CU_ASSERT(cookies[2].no_index);
+ assert_true(ans == cookies);
+ assert_true(cookies[0].no_index);
+ assert_true(cookies[1].no_index);
+ assert_true(cookies[2].no_index);
}
void test_downstream_assemble_request_cookie(void) {
@@ -147,7 +164,8 @@ void test_downstream_assemble_request_cookie(void) {
req.fs.add_header_token(StringRef::from_lit("cookie"),
StringRef::from_lit("delta;;"), false,
http2::HD_COOKIE);
- CU_ASSERT("alpha; bravo; charlie; delta" == d.assemble_request_cookie());
+ assert_stdstring_equal("alpha; bravo; charlie; delta",
+ d.assemble_request_cookie().str());
}
void test_downstream_rewrite_location_response_header(void) {
@@ -161,7 +179,7 @@ void test_downstream_rewrite_location_response_header(void) {
false, http2::HD_LOCATION);
d.rewrite_location_response_header(StringRef::from_lit("https"));
auto location = resp.fs.header(http2::HD_LOCATION);
- CU_ASSERT("https://localhost:8443/" == (*location).value);
+ assert_stdstring_equal("https://localhost:8443/", (*location).value.str());
}
void test_downstream_supports_non_final_response(void) {
@@ -171,27 +189,27 @@ void test_downstream_supports_non_final_response(void) {
req.http_major = 3;
req.http_minor = 0;
- CU_ASSERT(d.supports_non_final_response());
+ assert_true(d.supports_non_final_response());
req.http_major = 2;
req.http_minor = 0;
- CU_ASSERT(d.supports_non_final_response());
+ assert_true(d.supports_non_final_response());
req.http_major = 1;
req.http_minor = 1;
- CU_ASSERT(d.supports_non_final_response());
+ assert_true(d.supports_non_final_response());
req.http_major = 1;
req.http_minor = 0;
- CU_ASSERT(!d.supports_non_final_response());
+ assert_false(d.supports_non_final_response());
req.http_major = 0;
req.http_minor = 9;
- CU_ASSERT(!d.supports_non_final_response());
+ assert_false(d.supports_non_final_response());
}
void test_downstream_find_affinity_cookie(void) {
@@ -217,15 +235,15 @@ void test_downstream_find_affinity_cookie(void) {
aff = d.find_affinity_cookie(StringRef::from_lit("lb"));
- CU_ASSERT(0xdeadbeef == aff);
+ assert_uint32(0xdeadbeef, ==, aff);
aff = d.find_affinity_cookie(StringRef::from_lit("LB"));
- CU_ASSERT(0xf1f2f3f4 == aff);
+ assert_uint32(0xf1f2f3f4, ==, aff);
aff = d.find_affinity_cookie(StringRef::from_lit("short"));
- CU_ASSERT(0 == aff);
+ assert_uint32(0, ==, aff);
}
} // namespace shrpx
diff --git a/src/shrpx_downstream_test.h b/src/shrpx_downstream_test.h
index ef06ea3..07adbca 100644
--- a/src/shrpx_downstream_test.h
+++ b/src/shrpx_downstream_test.h
@@ -29,15 +29,21 @@
# include <config.h>
#endif // HAVE_CONFIG_H
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
namespace shrpx {
-void test_downstream_field_store_append_last_header(void);
-void test_downstream_field_store_header(void);
-void test_downstream_crumble_request_cookie(void);
-void test_downstream_assemble_request_cookie(void);
-void test_downstream_rewrite_location_response_header(void);
-void test_downstream_supports_non_final_response(void);
-void test_downstream_find_affinity_cookie(void);
+extern const MunitSuite downstream_suite;
+
+munit_void_test_decl(test_downstream_field_store_append_last_header);
+munit_void_test_decl(test_downstream_field_store_header);
+munit_void_test_decl(test_downstream_crumble_request_cookie);
+munit_void_test_decl(test_downstream_assemble_request_cookie);
+munit_void_test_decl(test_downstream_rewrite_location_response_header);
+munit_void_test_decl(test_downstream_supports_non_final_response);
+munit_void_test_decl(test_downstream_find_affinity_cookie);
} // namespace shrpx
diff --git a/src/shrpx_http.cc b/src/shrpx_http.cc
index ad32dc9..4750500 100644
--- a/src/shrpx_http.cc
+++ b/src/shrpx_http.cc
@@ -167,9 +167,9 @@ std::string colorizeHeaders(const char *hdrs) {
return nhdrs;
}
-ssize_t select_padding_callback(nghttp2_session *session,
- const nghttp2_frame *frame, size_t max_payload,
- void *user_data) {
+nghttp2_ssize select_padding_callback(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ size_t max_payload, void *user_data) {
return std::min(max_payload, frame->hd.length + get_config()->padding);
}
diff --git a/src/shrpx_http.h b/src/shrpx_http.h
index 18935d8..774686c 100644
--- a/src/shrpx_http.h
+++ b/src/shrpx_http.h
@@ -63,9 +63,9 @@ StringRef create_forwarded(BlockAllocator &balloc, int params,
// Adds ANSI color codes to HTTP headers |hdrs|.
std::string colorizeHeaders(const char *hdrs);
-ssize_t select_padding_callback(nghttp2_session *session,
- const nghttp2_frame *frame, size_t max_payload,
- void *user_data);
+nghttp2_ssize select_padding_callback(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ size_t max_payload, void *user_data);
// Creates set-cookie-string for cookie based affinity. If |path| is
// not empty, "; <path>" is added. If |secure| is true, "; Secure" is
diff --git a/src/shrpx_http2_downstream_connection.cc b/src/shrpx_http2_downstream_connection.cc
index ee48799..a6c9d53 100644
--- a/src/shrpx_http2_downstream_connection.cc
+++ b/src/shrpx_http2_downstream_connection.cc
@@ -162,10 +162,11 @@ int Http2DownstreamConnection::submit_rst_stream(Downstream *downstream,
}
namespace {
-ssize_t http2_data_read_callback(nghttp2_session *session, int32_t stream_id,
- uint8_t *buf, size_t length,
- uint32_t *data_flags,
- nghttp2_data_source *source, void *user_data) {
+nghttp2_ssize http2_data_read_callback(nghttp2_session *session,
+ int32_t stream_id, uint8_t *buf,
+ size_t length, uint32_t *data_flags,
+ nghttp2_data_source *source,
+ void *user_data) {
int rv;
auto sd = static_cast<StreamData *>(
nghttp2_session_get_stream_user_data(session, stream_id));
@@ -476,8 +477,8 @@ int Http2DownstreamConnection::push_request_headers() {
auto transfer_encoding = req.fs.header(http2::HD_TRANSFER_ENCODING);
- nghttp2_data_provider *data_prdptr = nullptr;
- nghttp2_data_provider data_prd;
+ nghttp2_data_provider2 *data_prdptr = nullptr;
+ nghttp2_data_provider2 data_prd;
// Add body as long as transfer-encoding is given even if
// req.fs.content_length == 0 to forward trailer fields.
diff --git a/src/shrpx_http2_session.cc b/src/shrpx_http2_session.cc
index f58ed2f..dccdae4 100644
--- a/src/shrpx_http2_session.cc
+++ b/src/shrpx_http2_session.cc
@@ -755,15 +755,15 @@ void Http2Session::remove_stream_data(StreamData *sd) {
int Http2Session::submit_request(Http2DownstreamConnection *dconn,
const nghttp2_nv *nva, size_t nvlen,
- const nghttp2_data_provider *data_prd) {
+ const nghttp2_data_provider2 *data_prd) {
assert(state_ == Http2SessionState::CONNECTED);
auto sd = std::make_unique<StreamData>();
sd->dlnext = sd->dlprev = nullptr;
// TODO Specify nullptr to pri_spec for now
- auto stream_id =
- nghttp2_submit_request(session_, nullptr, nva, nvlen, data_prd, sd.get());
+ auto stream_id = nghttp2_submit_request2(session_, nullptr, nva, nvlen,
+ data_prd, sd.get());
if (stream_id < 0) {
- SSLOG(FATAL, this) << "nghttp2_submit_request() failed: "
+ SSLOG(FATAL, this) << "nghttp2_submit_request2() failed: "
<< nghttp2_strerror(stream_id);
return -1;
}
@@ -1653,7 +1653,7 @@ nghttp2_session_callbacks *create_http2_downstream_callbacks() {
send_data_callback);
if (get_config()->padding) {
- nghttp2_session_callbacks_set_select_padding_callback(
+ nghttp2_session_callbacks_set_select_padding_callback2(
callbacks, http::select_padding_callback);
}
@@ -1754,11 +1754,9 @@ int Http2Session::on_read(const uint8_t *data, size_t datalen) {
int Http2Session::on_write() { return on_write_(*this); }
int Http2Session::downstream_read(const uint8_t *data, size_t datalen) {
- ssize_t rv;
-
- rv = nghttp2_session_mem_recv(session_, data, datalen);
+ auto rv = nghttp2_session_mem_recv2(session_, data, datalen);
if (rv < 0) {
- SSLOG(ERROR, this) << "nghttp2_session_mem_recv() returned error: "
+ SSLOG(ERROR, this) << "nghttp2_session_mem_recv2() returned error: "
<< nghttp2_strerror(rv);
return -1;
}
@@ -1778,9 +1776,9 @@ int Http2Session::downstream_read(const uint8_t *data, size_t datalen) {
int Http2Session::downstream_write() {
for (;;) {
const uint8_t *data;
- auto datalen = nghttp2_session_mem_send(session_, &data);
+ auto datalen = nghttp2_session_mem_send2(session_, &data);
if (datalen < 0) {
- SSLOG(ERROR, this) << "nghttp2_session_mem_send() returned error: "
+ SSLOG(ERROR, this) << "nghttp2_session_mem_send2() returned error: "
<< nghttp2_strerror(datalen);
return -1;
}
diff --git a/src/shrpx_http2_session.h b/src/shrpx_http2_session.h
index 31b2545..1a67a5f 100644
--- a/src/shrpx_http2_session.h
+++ b/src/shrpx_http2_session.h
@@ -116,7 +116,7 @@ public:
void remove_stream_data(StreamData *sd);
int submit_request(Http2DownstreamConnection *dconn, const nghttp2_nv *nva,
- size_t nvlen, const nghttp2_data_provider *data_prd);
+ size_t nvlen, const nghttp2_data_provider2 *data_prd);
int submit_rst_stream(int32_t stream_id, uint32_t error_code);
diff --git a/src/shrpx_http2_upstream.cc b/src/shrpx_http2_upstream.cc
index c9f8a8c..2cb5436 100644
--- a/src/shrpx_http2_upstream.cc
+++ b/src/shrpx_http2_upstream.cc
@@ -717,7 +717,7 @@ int on_frame_send_callback(nghttp2_session *session, const nghttp2_frame *frame,
upstream, handler->get_mcpool(), promised_stream_id);
auto &req = promised_downstream->request();
- // As long as we use nghttp2_session_mem_send(), setting stream
+ // As long as we use nghttp2_session_mem_send2(), setting stream
// user data here should not fail. This is because this callback
// is called just after frame was serialized. So no worries about
// hanging Downstream.
@@ -995,7 +995,7 @@ nghttp2_session_callbacks *create_http2_upstream_callbacks() {
auto config = get_config();
if (config->padding) {
- nghttp2_session_callbacks_set_select_padding_callback(
+ nghttp2_session_callbacks_set_select_padding_callback2(
callbacks, http::select_padding_callback);
}
@@ -1145,21 +1145,20 @@ Http2Upstream::~Http2Upstream() {
}
int Http2Upstream::on_read() {
- ssize_t rv = 0;
auto rb = handler_->get_rb();
auto rlimit = handler_->get_rlimit();
if (rb->rleft()) {
- rv = nghttp2_session_mem_recv(session_, rb->pos(), rb->rleft());
+ auto rv = nghttp2_session_mem_recv2(session_, rb->pos(), rb->rleft());
if (rv < 0) {
if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
- ULOG(ERROR, this) << "nghttp2_session_mem_recv() returned error: "
+ ULOG(ERROR, this) << "nghttp2_session_mem_recv2() returned error: "
<< nghttp2_strerror(rv);
}
return -1;
}
- // nghttp2_session_mem_recv should consume all input bytes on
+ // nghttp2_session_mem_recv2 should consume all input bytes on
// success.
assert(static_cast<size_t>(rv) == rb->rleft());
rb->reset();
@@ -1221,10 +1220,10 @@ int Http2Upstream::on_write() {
}
const uint8_t *data;
- auto datalen = nghttp2_session_mem_send(session_, &data);
+ auto datalen = nghttp2_session_mem_send2(session_, &data);
if (datalen < 0) {
- ULOG(ERROR, this) << "nghttp2_session_mem_send() returned error: "
+ ULOG(ERROR, this) << "nghttp2_session_mem_send2() returned error: "
<< nghttp2_strerror(datalen);
return -1;
}
@@ -1436,11 +1435,11 @@ int Http2Upstream::terminate_session(uint32_t error_code) {
}
namespace {
-ssize_t downstream_data_read_callback(nghttp2_session *session,
- int32_t stream_id, uint8_t *buf,
- size_t length, uint32_t *data_flags,
- nghttp2_data_source *source,
- void *user_data) {
+nghttp2_ssize downstream_data_read_callback(nghttp2_session *session,
+ int32_t stream_id, uint8_t *buf,
+ size_t length, uint32_t *data_flags,
+ nghttp2_data_source *source,
+ void *user_data) {
int rv;
auto downstream = static_cast<Downstream *>(source->ptr);
auto body = downstream->get_response_buf();
@@ -1508,7 +1507,7 @@ int Http2Upstream::send_reply(Downstream *downstream, const uint8_t *body,
size_t bodylen) {
int rv;
- nghttp2_data_provider data_prd, *data_prd_ptr = nullptr;
+ nghttp2_data_provider2 data_prd, *data_prd_ptr = nullptr;
if (bodylen) {
data_prd.source.ptr = downstream;
@@ -1555,10 +1554,10 @@ int Http2Upstream::send_reply(Downstream *downstream, const uint8_t *body,
nva.push_back(http2::make_nv_nocopy(p.name, p.value));
}
- rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
- nva.data(), nva.size(), data_prd_ptr);
+ rv = nghttp2_submit_response2(session_, downstream->get_stream_id(),
+ nva.data(), nva.size(), data_prd_ptr);
if (nghttp2_is_fatal(rv)) {
- ULOG(FATAL, this) << "nghttp2_submit_response() failed: "
+ ULOG(FATAL, this) << "nghttp2_submit_response2() failed: "
<< nghttp2_strerror(rv);
return -1;
}
@@ -1589,7 +1588,7 @@ int Http2Upstream::error_reply(Downstream *downstream,
body->append(html);
downstream->set_response_state(DownstreamState::MSG_COMPLETE);
- nghttp2_data_provider data_prd;
+ nghttp2_data_provider2 data_prd;
data_prd.source.ptr = downstream;
data_prd.read_callback = downstream_data_read_callback;
@@ -1607,10 +1606,10 @@ int Http2Upstream::error_reply(Downstream *downstream,
http2::make_nv_ls_nocopy("content-length", content_length),
http2::make_nv_ls_nocopy("date", date)}};
- rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
- nva.data(), nva.size(), &data_prd);
+ rv = nghttp2_submit_response2(session_, downstream->get_stream_id(),
+ nva.data(), nva.size(), &data_prd);
if (rv < NGHTTP2_ERR_FATAL) {
- ULOG(FATAL, this) << "nghttp2_submit_response() failed: "
+ ULOG(FATAL, this) << "nghttp2_submit_response2() failed: "
<< nghttp2_strerror(rv);
return -1;
}
@@ -1876,11 +1875,11 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
}
}
- nghttp2_data_provider data_prd;
+ nghttp2_data_provider2 data_prd;
data_prd.source.ptr = downstream;
data_prd.read_callback = downstream_data_read_callback;
- nghttp2_data_provider *data_prdptr;
+ nghttp2_data_provider2 *data_prdptr;
if (downstream->expect_response_body() ||
downstream->expect_response_trailer()) {
@@ -1889,10 +1888,10 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
data_prdptr = nullptr;
}
- rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
- nva.data(), nva.size(), data_prdptr);
+ rv = nghttp2_submit_response2(session_, downstream->get_stream_id(),
+ nva.data(), nva.size(), data_prdptr);
if (rv != 0) {
- ULOG(FATAL, this) << "nghttp2_submit_response() failed";
+ ULOG(FATAL, this) << "nghttp2_submit_response2() failed";
return -1;
}
diff --git a/src/shrpx_http3_upstream.cc b/src/shrpx_http3_upstream.cc
index f8ae1ce..b8667a3 100644
--- a/src/shrpx_http3_upstream.cc
+++ b/src/shrpx_http3_upstream.cc
@@ -213,7 +213,7 @@ int get_new_connection_id(ngtcp2_conn *conn, ngtcp2_cid *cid, uint8_t *token,
auto &qkm = qkms->keying_materials.front();
if (generate_quic_connection_id(*cid, cidlen, worker->get_cid_prefix(),
- qkm.id, qkm.cid_encryption_key.data()) != 0) {
+ qkm.id, qkm.cid_encryption_ctx) != 0) {
return NGTCP2_ERR_CALLBACK_FAILURE;
}
@@ -611,7 +611,7 @@ int Http3Upstream::init(const UpstreamAddr *faddr, const Address &remote_addr,
if (generate_quic_connection_id(scid, SHRPX_QUIC_SCIDLEN,
worker->get_cid_prefix(), qkm.id,
- qkm.cid_encryption_key.data()) != 0) {
+ qkm.cid_encryption_ctx) != 0) {
return -1;
}
@@ -635,7 +635,6 @@ int Http3Upstream::init(const UpstreamAddr *faddr, const Address &remote_addr,
settings.cc_algo = quicconf.upstream.congestion_controller;
settings.max_window = http3conf.upstream.max_connection_window_size;
settings.max_stream_window = http3conf.upstream.max_window_size;
- settings.max_tx_udp_payload_size = SHRPX_QUIC_MAX_UDP_PAYLOAD_SIZE;
settings.rand_ctx.native_handle = &worker->get_randgen();
settings.token = token;
settings.tokenlen = tokenlen;
@@ -783,7 +782,9 @@ int Http3Upstream::write_streams() {
auto path_max_udp_payload_size =
ngtcp2_conn_get_path_max_tx_udp_payload_size(conn_);
#endif // UDP_SEGMENT
- auto max_pktcnt = ngtcp2_conn_get_send_quantum(conn_) / max_udp_payload_size;
+ auto max_pktcnt =
+ std::max(ngtcp2_conn_get_send_quantum(conn_) / max_udp_payload_size,
+ static_cast<size_t>(1));
ngtcp2_pkt_info pi, prev_pi;
uint8_t *bufpos = tx_.data.get();
ngtcp2_path_storage ps, prev_ps;
diff --git a/src/shrpx_http_test.cc b/src/shrpx_http_test.cc
index 3ace870..f753ec8 100644
--- a/src/shrpx_http_test.cc
+++ b/src/shrpx_http_test.cc
@@ -30,7 +30,7 @@
#include <cstdlib>
-#include <CUnit/CUnit.h>
+#include "munitxx.h"
#include "shrpx_http.h"
#include "shrpx_config.h"
@@ -38,43 +38,65 @@
namespace shrpx {
+namespace {
+const MunitTest tests[]{
+ munit_void_test(test_shrpx_http_create_forwarded),
+ munit_void_test(test_shrpx_http_create_via_header_value),
+ munit_void_test(test_shrpx_http_create_affinity_cookie),
+ munit_void_test(test_shrpx_http_create_altsvc_header_value),
+ munit_void_test(test_shrpx_http_check_http_scheme),
+ munit_test_end(),
+};
+} // namespace
+
+const MunitSuite http_suite{
+ "/http", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
void test_shrpx_http_create_forwarded(void) {
BlockAllocator balloc(1024, 1024);
- CU_ASSERT("by=\"example.com:3000\";for=\"[::1]\";host=\"www.example.com\";"
- "proto=https" ==
- http::create_forwarded(balloc,
- FORWARDED_BY | FORWARDED_FOR |
- FORWARDED_HOST | FORWARDED_PROTO,
- StringRef::from_lit("example.com:3000"),
- StringRef::from_lit("[::1]"),
- StringRef::from_lit("www.example.com"),
- StringRef::from_lit("https")));
-
- CU_ASSERT("for=192.168.0.1" ==
- http::create_forwarded(
- balloc, FORWARDED_FOR, StringRef::from_lit("alpha"),
- StringRef::from_lit("192.168.0.1"),
- StringRef::from_lit("bravo"), StringRef::from_lit("charlie")));
-
- CU_ASSERT("by=_hidden;for=\"[::1]\"" ==
- http::create_forwarded(
- balloc, FORWARDED_BY | FORWARDED_FOR,
- StringRef::from_lit("_hidden"), StringRef::from_lit("[::1]"),
- StringRef::from_lit(""), StringRef::from_lit("")));
-
- CU_ASSERT("by=\"[::1]\";for=_hidden" ==
- http::create_forwarded(
- balloc, FORWARDED_BY | FORWARDED_FOR,
- StringRef::from_lit("[::1]"), StringRef::from_lit("_hidden"),
- StringRef::from_lit(""), StringRef::from_lit("")));
-
- CU_ASSERT("" ==
- http::create_forwarded(
- balloc,
- FORWARDED_BY | FORWARDED_FOR | FORWARDED_HOST | FORWARDED_PROTO,
- StringRef::from_lit(""), StringRef::from_lit(""),
- StringRef::from_lit(""), StringRef::from_lit("")));
+ assert_stdstring_equal(
+ "by=\"example.com:3000\";for=\"[::1]\";host=\"www.example.com\";"
+ "proto=https",
+ http::create_forwarded(
+ balloc,
+ FORWARDED_BY | FORWARDED_FOR | FORWARDED_HOST | FORWARDED_PROTO,
+ StringRef::from_lit("example.com:3000"), StringRef::from_lit("[::1]"),
+ StringRef::from_lit("www.example.com"), StringRef::from_lit("https"))
+ .str());
+
+ assert_stdstring_equal(
+ "for=192.168.0.1",
+ http::create_forwarded(
+ balloc, FORWARDED_FOR, StringRef::from_lit("alpha"),
+ StringRef::from_lit("192.168.0.1"), StringRef::from_lit("bravo"),
+ StringRef::from_lit("charlie"))
+ .str());
+
+ assert_stdstring_equal(
+ "by=_hidden;for=\"[::1]\"",
+ http::create_forwarded(balloc, FORWARDED_BY | FORWARDED_FOR,
+ StringRef::from_lit("_hidden"),
+ StringRef::from_lit("[::1]"),
+ StringRef::from_lit(""), StringRef::from_lit(""))
+ .str());
+
+ assert_stdstring_equal(
+ "by=\"[::1]\";for=_hidden",
+ http::create_forwarded(balloc, FORWARDED_BY | FORWARDED_FOR,
+ StringRef::from_lit("[::1]"),
+ StringRef::from_lit("_hidden"),
+ StringRef::from_lit(""), StringRef::from_lit(""))
+ .str());
+
+ assert_stdstring_equal(
+ "", http::create_forwarded(
+ balloc,
+ FORWARDED_BY | FORWARDED_FOR | FORWARDED_HOST | FORWARDED_PROTO,
+ StringRef::from_lit(""), StringRef::from_lit(""),
+ StringRef::from_lit(""), StringRef::from_lit(""))
+ .str());
}
void test_shrpx_http_create_via_header_value(void) {
@@ -82,13 +104,13 @@ void test_shrpx_http_create_via_header_value(void) {
auto end = http::create_via_header_value(std::begin(buf), 1, 1);
- CU_ASSERT(("1.1 nghttpx" == StringRef{std::begin(buf), end}));
+ assert_stdstring_equal("1.1 nghttpx", (std::string{std::begin(buf), end}));
std::fill(std::begin(buf), std::end(buf), '\0');
end = http::create_via_header_value(std::begin(buf), 2, 0);
- CU_ASSERT(("2 nghttpx" == StringRef{std::begin(buf), end}));
+ assert_stdstring_equal("2 nghttpx", (std::string{std::begin(buf), end}));
}
void test_shrpx_http_create_affinity_cookie(void) {
@@ -98,24 +120,24 @@ void test_shrpx_http_create_affinity_cookie(void) {
c = http::create_affinity_cookie(balloc, StringRef::from_lit("cookie-val"),
0xf1e2d3c4u, StringRef{}, false);
- CU_ASSERT("cookie-val=f1e2d3c4" == c);
+ assert_stdstring_equal("cookie-val=f1e2d3c4", c.str());
c = http::create_affinity_cookie(balloc, StringRef::from_lit("alpha"),
0x00000000u, StringRef{}, true);
- CU_ASSERT("alpha=00000000; Secure" == c);
+ assert_stdstring_equal("alpha=00000000; Secure", c.str());
c = http::create_affinity_cookie(balloc, StringRef::from_lit("bravo"),
0x01111111u, StringRef::from_lit("bar"),
false);
- CU_ASSERT("bravo=01111111; Path=bar" == c);
+ assert_stdstring_equal("bravo=01111111; Path=bar", c.str());
c = http::create_affinity_cookie(balloc, StringRef::from_lit("charlie"),
0x01111111u, StringRef::from_lit("bar"),
true);
- CU_ASSERT("charlie=01111111; Path=bar; Secure" == c);
+ assert_stdstring_equal("charlie=01111111; Path=bar; Secure", c.str());
}
void test_shrpx_http_create_altsvc_header_value(void) {
@@ -130,8 +152,9 @@ void test_shrpx_http_create_altsvc_header_value(void) {
},
};
- CU_ASSERT(R"(h3="127.0.0.1:443"; ma=3600)" ==
- http::create_altsvc_header_value(balloc, altsvcs));
+ assert_stdstring_equal(
+ R"(h3="127.0.0.1:443"; ma=3600)",
+ http::create_altsvc_header_value(balloc, altsvcs).str());
}
{
@@ -149,20 +172,21 @@ void test_shrpx_http_create_altsvc_header_value(void) {
},
};
- CU_ASSERT(R"(h3=":443"; ma=3600, h3%25="\"foo\":4433")" ==
- http::create_altsvc_header_value(balloc, altsvcs));
+ assert_stdstring_equal(
+ R"(h3=":443"; ma=3600, h3%25="\"foo\":4433")",
+ http::create_altsvc_header_value(balloc, altsvcs).str());
}
}
void test_shrpx_http_check_http_scheme(void) {
- CU_ASSERT(http::check_http_scheme(StringRef::from_lit("https"), true));
- CU_ASSERT(!http::check_http_scheme(StringRef::from_lit("https"), false));
- CU_ASSERT(!http::check_http_scheme(StringRef::from_lit("http"), true));
- CU_ASSERT(http::check_http_scheme(StringRef::from_lit("http"), false));
- CU_ASSERT(!http::check_http_scheme(StringRef::from_lit("foo"), true));
- CU_ASSERT(!http::check_http_scheme(StringRef::from_lit("foo"), false));
- CU_ASSERT(!http::check_http_scheme(StringRef{}, true));
- CU_ASSERT(!http::check_http_scheme(StringRef{}, false));
+ assert_true(http::check_http_scheme(StringRef::from_lit("https"), true));
+ assert_false(http::check_http_scheme(StringRef::from_lit("https"), false));
+ assert_false(http::check_http_scheme(StringRef::from_lit("http"), true));
+ assert_true(http::check_http_scheme(StringRef::from_lit("http"), false));
+ assert_false(http::check_http_scheme(StringRef::from_lit("foo"), true));
+ assert_false(http::check_http_scheme(StringRef::from_lit("foo"), false));
+ assert_false(http::check_http_scheme(StringRef{}, true));
+ assert_false(http::check_http_scheme(StringRef{}, false));
}
} // namespace shrpx
diff --git a/src/shrpx_http_test.h b/src/shrpx_http_test.h
index d50ab53..2abdc20 100644
--- a/src/shrpx_http_test.h
+++ b/src/shrpx_http_test.h
@@ -29,13 +29,19 @@
# include <config.h>
#endif // HAVE_CONFIG_H
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
namespace shrpx {
-void test_shrpx_http_create_forwarded(void);
-void test_shrpx_http_create_via_header_value(void);
-void test_shrpx_http_create_affinity_cookie(void);
-void test_shrpx_http_create_altsvc_header_value(void);
-void test_shrpx_http_check_http_scheme(void);
+extern const MunitSuite http_suite;
+
+munit_void_test_decl(test_shrpx_http_create_forwarded);
+munit_void_test_decl(test_shrpx_http_create_via_header_value);
+munit_void_test_decl(test_shrpx_http_create_affinity_cookie);
+munit_void_test_decl(test_shrpx_http_create_altsvc_header_value);
+munit_void_test_decl(test_shrpx_http_check_http_scheme);
} // namespace shrpx
diff --git a/src/shrpx_live_check.cc b/src/shrpx_live_check.cc
index 9b932cd..8e8d316 100644
--- a/src/shrpx_live_check.cc
+++ b/src/shrpx_live_check.cc
@@ -580,18 +580,16 @@ int LiveCheck::write_clear() {
}
int LiveCheck::on_read(const uint8_t *data, size_t len) {
- ssize_t rv;
-
- rv = nghttp2_session_mem_recv(session_, data, len);
+ auto rv = nghttp2_session_mem_recv2(session_, data, len);
if (rv < 0) {
- LOG(ERROR) << "nghttp2_session_mem_recv() returned error: "
+ LOG(ERROR) << "nghttp2_session_mem_recv2() returned error: "
<< nghttp2_strerror(rv);
return -1;
}
if (settings_ack_received_ && !session_closing_) {
session_closing_ = true;
- rv = nghttp2_session_terminate_session(session_, NGHTTP2_NO_ERROR);
+ auto rv = nghttp2_session_terminate_session(session_, NGHTTP2_NO_ERROR);
if (rv != 0) {
return -1;
}
@@ -619,10 +617,10 @@ int LiveCheck::on_read(const uint8_t *data, size_t len) {
int LiveCheck::on_write() {
for (;;) {
const uint8_t *data;
- auto datalen = nghttp2_session_mem_send(session_, &data);
+ auto datalen = nghttp2_session_mem_send2(session_, &data);
if (datalen < 0) {
- LOG(ERROR) << "nghttp2_session_mem_send() returned error: "
+ LOG(ERROR) << "nghttp2_session_mem_send2() returned error: "
<< nghttp2_strerror(datalen);
return -1;
}
diff --git a/src/shrpx_mruby.cc b/src/shrpx_mruby.cc
index b5c6ed3..4d412ef 100644
--- a/src/shrpx_mruby.cc
+++ b/src/shrpx_mruby.cc
@@ -151,12 +151,12 @@ RProc *compile(mrb_state *mrb, const StringRef &filename) {
}
auto infile_d = defer(fclose, infile);
- auto mrbc = mrbc_context_new(mrb);
+ auto mrbc = mrb_ccontext_new(mrb);
if (mrbc == nullptr) {
LOG(ERROR) << "mrb_context_new failed";
return nullptr;
}
- auto mrbc_d = defer(mrbc_context_free, mrb, mrbc);
+ auto mrbc_d = defer(mrb_ccontext_free, mrb, mrbc);
auto parser = mrb_parse_file(mrb, infile, nullptr);
if (parser == nullptr) {
diff --git a/src/shrpx_quic.cc b/src/shrpx_quic.cc
index 2d4de59..a6d4dfa 100644
--- a/src/shrpx_quic.cc
+++ b/src/shrpx_quic.cc
@@ -175,7 +175,7 @@ int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa,
int generate_quic_retry_connection_id(ngtcp2_cid &cid, size_t cidlen,
const uint8_t *server_id, uint8_t km_id,
- const uint8_t *key) {
+ EVP_CIPHER_CTX *ctx) {
assert(cidlen == SHRPX_QUIC_SCIDLEN);
if (RAND_bytes(cid.data, cidlen) != 1) {
@@ -190,12 +190,12 @@ int generate_quic_retry_connection_id(ngtcp2_cid &cid, size_t cidlen,
std::copy_n(server_id, SHRPX_QUIC_SERVER_IDLEN, p);
- return encrypt_quic_connection_id(p, p, key);
+ return encrypt_quic_connection_id(p, p, ctx);
}
int generate_quic_connection_id(ngtcp2_cid &cid, size_t cidlen,
const uint8_t *cid_prefix, uint8_t km_id,
- const uint8_t *key) {
+ EVP_CIPHER_CTX *ctx) {
assert(cidlen == SHRPX_QUIC_SCIDLEN);
if (RAND_bytes(cid.data, cidlen) != 1) {
@@ -210,20 +210,11 @@ int generate_quic_connection_id(ngtcp2_cid &cid, size_t cidlen,
std::copy_n(cid_prefix, SHRPX_QUIC_CID_PREFIXLEN, p);
- return encrypt_quic_connection_id(p, p, key);
+ return encrypt_quic_connection_id(p, p, ctx);
}
int encrypt_quic_connection_id(uint8_t *dest, const uint8_t *src,
- const uint8_t *key) {
- auto ctx = EVP_CIPHER_CTX_new();
- auto d = defer(EVP_CIPHER_CTX_free, ctx);
-
- if (!EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), nullptr, key, nullptr)) {
- return -1;
- }
-
- EVP_CIPHER_CTX_set_padding(ctx, 0);
-
+ EVP_CIPHER_CTX *ctx) {
int len;
if (!EVP_EncryptUpdate(ctx, dest, &len, src, SHRPX_QUIC_DECRYPTED_DCIDLEN) ||
@@ -235,20 +226,11 @@ int encrypt_quic_connection_id(uint8_t *dest, const uint8_t *src,
}
int decrypt_quic_connection_id(uint8_t *dest, const uint8_t *src,
- const uint8_t *key) {
- auto ctx = EVP_CIPHER_CTX_new();
- auto d = defer(EVP_CIPHER_CTX_free, ctx);
-
- if (!EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), nullptr, key, nullptr)) {
- return -1;
- }
-
- EVP_CIPHER_CTX_set_padding(ctx, 0);
-
+ EVP_CIPHER_CTX *ctx) {
int len;
- if (!EVP_DecryptUpdate(ctx, dest, &len, src, SHRPX_QUIC_DECRYPTED_DCIDLEN) ||
- !EVP_DecryptFinal_ex(ctx, dest + len, &len)) {
+ if (!EVP_EncryptUpdate(ctx, dest, &len, src, SHRPX_QUIC_DECRYPTED_DCIDLEN) ||
+ !EVP_EncryptFinal_ex(ctx, dest + len, &len)) {
return -1;
}
diff --git a/src/shrpx_quic.h b/src/shrpx_quic.h
index b2f6087..88388e9 100644
--- a/src/shrpx_quic.h
+++ b/src/shrpx_quic.h
@@ -31,6 +31,8 @@
#include <functional>
+#include <openssl/evp.h>
+
#include <ngtcp2/ngtcp2.h>
#include "network.h"
@@ -70,7 +72,6 @@ constexpr size_t SHRPX_QUIC_CID_PREFIXLEN = 8;
constexpr size_t SHRPX_QUIC_CID_PREFIX_OFFSET = 1;
constexpr size_t SHRPX_QUIC_DECRYPTED_DCIDLEN = 16;
constexpr size_t SHRPX_QUIC_CID_ENCRYPTION_KEYLEN = 16;
-constexpr size_t SHRPX_QUIC_MAX_UDP_PAYLOAD_SIZE = 1472;
constexpr size_t SHRPX_QUIC_CONN_CLOSE_PKTLEN = 256;
constexpr size_t SHRPX_QUIC_STATELESS_RESET_BURST = 100;
constexpr size_t SHRPX_QUIC_SECRET_RESERVEDLEN = 4;
@@ -87,17 +88,17 @@ int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa,
int generate_quic_retry_connection_id(ngtcp2_cid &cid, size_t cidlen,
const uint8_t *server_id, uint8_t km_id,
- const uint8_t *key);
+ EVP_CIPHER_CTX *ctx);
int generate_quic_connection_id(ngtcp2_cid &cid, size_t cidlen,
const uint8_t *cid_prefix, uint8_t km_id,
- const uint8_t *key);
+ EVP_CIPHER_CTX *ctx);
int encrypt_quic_connection_id(uint8_t *dest, const uint8_t *src,
- const uint8_t *key);
+ EVP_CIPHER_CTX *ctx);
int decrypt_quic_connection_id(uint8_t *dest, const uint8_t *src,
- const uint8_t *key);
+ EVP_CIPHER_CTX *ctx);
int generate_quic_hashed_connection_id(ngtcp2_cid &dest,
const Address &remote_addr,
diff --git a/src/shrpx_quic_connection_handler.cc b/src/shrpx_quic_connection_handler.cc
index 6287971..13f710b 100644
--- a/src/shrpx_quic_connection_handler.cc
+++ b/src/shrpx_quic_connection_handler.cc
@@ -134,7 +134,7 @@ int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr,
if (decrypt_quic_connection_id(decrypted_dcid.data(),
vc.dcid + SHRPX_QUIC_CID_PREFIX_OFFSET,
- qkm->cid_encryption_key.data()) != 0) {
+ qkm->cid_encryption_ctx) != 0) {
return 0;
}
@@ -186,7 +186,7 @@ int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr,
if (decrypt_quic_connection_id(decrypted_dcid.data(),
vc.dcid + SHRPX_QUIC_CID_PREFIX_OFFSET,
- qkm->cid_encryption_key.data()) != 0) {
+ qkm->cid_encryption_ctx) != 0) {
return 0;
}
}
@@ -480,7 +480,7 @@ int QUICConnectionHandler::send_retry(
if (generate_quic_retry_connection_id(retry_scid, SHRPX_QUIC_SCIDLEN,
quicconf.server_id.data(), qkm.id,
- qkm.cid_encryption_key.data()) != 0) {
+ qkm.cid_encryption_ctx) != 0) {
return -1;
}
diff --git a/src/shrpx_router_test.cc b/src/shrpx_router_test.cc
index 21c2f51..a9625a0 100644
--- a/src/shrpx_router_test.cc
+++ b/src/shrpx_router_test.cc
@@ -24,12 +24,25 @@
*/
#include "shrpx_router_test.h"
-#include <CUnit/CUnit.h>
+#include "munitxx.h"
#include "shrpx_router.h"
namespace shrpx {
+namespace {
+const MunitTest tests[]{
+ munit_void_test(test_shrpx_router_match),
+ munit_void_test(test_shrpx_router_match_wildcard),
+ munit_void_test(test_shrpx_router_match_prefix),
+ munit_test_end(),
+};
+} // namespace
+
+const MunitSuite router_suite{
+ "/router", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
struct Pattern {
StringRef pattern;
size_t idx;
@@ -61,42 +74,42 @@ void test_shrpx_router_match(void) {
idx = router.match(StringRef::from_lit("nghttp2.org"),
StringRef::from_lit("/"));
- CU_ASSERT(0 == idx);
+ assert_ssize(0, ==, idx);
idx = router.match(StringRef::from_lit("nghttp2.org"),
StringRef::from_lit("/alpha"));
- CU_ASSERT(1 == idx);
+ assert_ssize(1, ==, idx);
idx = router.match(StringRef::from_lit("nghttp2.org"),
StringRef::from_lit("/alpha/"));
- CU_ASSERT(2 == idx);
+ assert_ssize(2, ==, idx);
idx = router.match(StringRef::from_lit("nghttp2.org"),
StringRef::from_lit("/alpha/charlie"));
- CU_ASSERT(2 == idx);
+ assert_ssize(2, ==, idx);
idx = router.match(StringRef::from_lit("nghttp2.org"),
StringRef::from_lit("/alpha/bravo/"));
- CU_ASSERT(3 == idx);
+ assert_ssize(3, ==, idx);
// matches pattern when last '/' is missing in path
idx = router.match(StringRef::from_lit("nghttp2.org"),
StringRef::from_lit("/alpha/bravo"));
- CU_ASSERT(3 == idx);
+ assert_ssize(3, ==, idx);
idx = router.match(StringRef::from_lit("www2.nghttp2.org"),
StringRef::from_lit("/alpha"));
- CU_ASSERT(8 == idx);
+ assert_ssize(8, ==, idx);
idx = router.match(StringRef{}, StringRef::from_lit("/alpha"));
- CU_ASSERT(5 == idx);
+ assert_ssize(5, ==, idx);
}
void test_shrpx_router_match_wildcard(void) {
@@ -115,32 +128,41 @@ void test_shrpx_router_match_wildcard(void) {
router.add_route(p.pattern, p.idx, p.wildcard);
}
- CU_ASSERT(0 == router.match(StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/")));
+ assert_ssize(0, ==,
+ router.match(StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/")));
- CU_ASSERT(1 == router.match(StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/a")));
+ assert_ssize(1, ==,
+ router.match(StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/a")));
- CU_ASSERT(1 == router.match(StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/charlie")));
+ assert_ssize(1, ==,
+ router.match(StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/charlie")));
- CU_ASSERT(2 == router.match(StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/alpha")));
+ assert_ssize(2, ==,
+ router.match(StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/alpha")));
- CU_ASSERT(2 == router.match(StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/alpha/")));
+ assert_ssize(2, ==,
+ router.match(StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/alpha/")));
- CU_ASSERT(3 == router.match(StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/alpha/b")));
+ assert_ssize(3, ==,
+ router.match(StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/alpha/b")));
- CU_ASSERT(4 == router.match(StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/bravo")));
+ assert_ssize(4, ==,
+ router.match(StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/bravo")));
- CU_ASSERT(5 == router.match(StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/bravocharlie")));
+ assert_ssize(5, ==,
+ router.match(StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/bravocharlie")));
- CU_ASSERT(5 == router.match(StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/bravo/")));
+ assert_ssize(5, ==,
+ router.match(StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/bravo/")));
}
void test_shrpx_router_match_prefix(void) {
@@ -166,19 +188,19 @@ void test_shrpx_router_match_prefix(void) {
idx = router.match_prefix(&nread, &node,
StringRef::from_lit("gro.2ptthgn.gmi.ahpla.ovarb"));
- CU_ASSERT(0 == idx);
- CU_ASSERT(12 == nread);
+ assert_ssize(0, ==, idx);
+ assert_size(12, ==, nread);
idx = router.match_prefix(&nread, &node,
StringRef::from_lit("gmi.ahpla.ovarb"));
- CU_ASSERT(2 == idx);
- CU_ASSERT(4 == nread);
+ assert_ssize(2, ==, idx);
+ assert_size(4, ==, nread);
idx = router.match_prefix(&nread, &node, StringRef::from_lit("ahpla.ovarb"));
- CU_ASSERT(3 == idx);
- CU_ASSERT(6 == nread);
+ assert_ssize(3, ==, idx);
+ assert_ssize(6, ==, nread);
}
} // namespace shrpx
diff --git a/src/shrpx_router_test.h b/src/shrpx_router_test.h
index d39cb87..04d4c45 100644
--- a/src/shrpx_router_test.h
+++ b/src/shrpx_router_test.h
@@ -29,11 +29,17 @@
# include <config.h>
#endif // HAVE_CONFIG_H
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
namespace shrpx {
-void test_shrpx_router_match(void);
-void test_shrpx_router_match_wildcard(void);
-void test_shrpx_router_match_prefix(void);
+extern const MunitSuite router_suite;
+
+munit_void_test_decl(test_shrpx_router_match);
+munit_void_test_decl(test_shrpx_router_match_wildcard);
+munit_void_test_decl(test_shrpx_router_match_prefix);
} // namespace shrpx
diff --git a/src/shrpx_tls.cc b/src/shrpx_tls.cc
index aa0c9f2..10bbbf2 100644
--- a/src/shrpx_tls.cc
+++ b/src/shrpx_tls.cc
@@ -72,6 +72,11 @@
# endif // HAVE_LIBNGTCP2_CRYPTO_BORINGSSL
#endif // ENABLE_HTTP3
+#ifdef HAVE_LIBBROTLI
+# include <brotli/encode.h>
+# include <brotli/decode.h>
+#endif // HAVE_LIBBROTLI
+
#include "shrpx_log.h"
#include "shrpx_client_handler.h"
#include "shrpx_config.h"
@@ -158,6 +163,35 @@ int ssl_pem_passwd_cb(char *buf, int size, int rwflag, void *user_data) {
} // namespace
namespace {
+std::shared_ptr<std::vector<uint8_t>>
+get_ocsp_data(TLSContextData *tls_ctx_data) {
+#ifdef HAVE_ATOMIC_STD_SHARED_PTR
+ return std::atomic_load_explicit(&tls_ctx_data->ocsp_data,
+ std::memory_order_acquire);
+#else // !HAVE_ATOMIC_STD_SHARED_PTR
+ std::lock_guard<std::mutex> g(tls_ctx_data->mu);
+ return tls_ctx_data->ocsp_data;
+#endif // !HAVE_ATOMIC_STD_SHARED_PTR
+}
+} // namespace
+
+namespace {
+void set_ocsp_response(SSL *ssl) {
+#ifdef NGHTTP2_OPENSSL_IS_BORINGSSL
+ auto tls_ctx_data =
+ static_cast<TLSContextData *>(SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl)));
+ auto data = get_ocsp_data(tls_ctx_data);
+
+ if (!data) {
+ return;
+ }
+
+ SSL_set_ocsp_response(ssl, data->data(), data->size());
+#endif // NGHTTP2_OPENSSL_IS_BORINGSSL
+}
+} // namespace
+
+namespace {
// *al is set to SSL_AD_UNRECOGNIZED_NAME by openssl, so we don't have
// to set it explicitly.
int servername_callback(SSL *ssl, int *al, void *arg) {
@@ -167,12 +201,16 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
auto rawhost = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
if (rawhost == nullptr) {
+ set_ocsp_response(ssl);
+
return SSL_TLSEXT_ERR_NOACK;
}
auto len = strlen(rawhost);
// NI_MAXHOST includes terminal NULL.
if (len == 0 || len + 1 > NI_MAXHOST) {
+ set_ocsp_response(ssl);
+
return SSL_TLSEXT_ERR_NOACK;
}
@@ -194,6 +232,8 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
auto idx = cert_tree->lookup(hostname);
if (idx == -1) {
+ set_ocsp_response(ssl);
+
return SSL_TLSEXT_ERR_NOACK;
}
@@ -290,25 +330,14 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
SSL_set_SSL_CTX(ssl, ssl_ctx_list[0]);
+ set_ocsp_response(ssl);
+
return SSL_TLSEXT_ERR_OK;
}
} // namespace
#ifndef NGHTTP2_OPENSSL_IS_BORINGSSL
namespace {
-std::shared_ptr<std::vector<uint8_t>>
-get_ocsp_data(TLSContextData *tls_ctx_data) {
-# ifdef HAVE_ATOMIC_STD_SHARED_PTR
- return std::atomic_load_explicit(&tls_ctx_data->ocsp_data,
- std::memory_order_acquire);
-# else // !HAVE_ATOMIC_STD_SHARED_PTR
- std::lock_guard<std::mutex> g(tls_ctx_data->mu);
- return tls_ctx_data->ocsp_data;
-# endif // !HAVE_ATOMIC_STD_SHARED_PTR
-}
-} // namespace
-
-namespace {
int ocsp_resp_cb(SSL *ssl, void *arg) {
auto ssl_ctx = SSL_get_SSL_CTX(ssl);
auto tls_ctx_data =
@@ -817,6 +846,83 @@ unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity_out,
} // namespace
#endif // !OPENSSL_NO_PSK
+#if defined(NGHTTP2_OPENSSL_IS_BORINGSSL) && defined(HAVE_LIBBROTLI)
+namespace {
+int cert_compress(SSL *ssl, CBB *out, const uint8_t *in, size_t in_len) {
+ uint8_t *dest;
+
+ size_t compressed_size = BrotliEncoderMaxCompressedSize(in_len);
+ if (compressed_size == 0) {
+ LOG(ERROR) << "BrotliEncoderMaxCompressedSize failed";
+
+ return 0;
+ }
+
+ if (LOG_ENABLED(INFO)) {
+ LOG(INFO) << "Maximum compressed size is " << compressed_size
+ << " bytes against input " << in_len << " bytes";
+ }
+
+ if (!CBB_reserve(out, &dest, compressed_size)) {
+ LOG(ERROR) << "CBB_reserve failed";
+
+ return 0;
+ }
+
+ if (BrotliEncoderCompress(BROTLI_MAX_QUALITY, BROTLI_DEFAULT_WINDOW,
+ BROTLI_MODE_GENERIC, in_len, in, &compressed_size,
+ dest) != BROTLI_TRUE) {
+ LOG(ERROR) << "BrotliEncoderCompress failed";
+
+ return 0;
+ }
+
+ if (LOG_ENABLED(INFO)) {
+ LOG(INFO) << "BrotliEncoderCompress succeeded, produced " << compressed_size
+ << " bytes, " << (in_len - compressed_size) * 100 / in_len
+ << "% reduction";
+ }
+
+ if (!CBB_did_write(out, compressed_size)) {
+ LOG(ERROR) << "CBB_did_write failed";
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int cert_decompress(SSL *ssl, CRYPTO_BUFFER **out, size_t uncompressed_len,
+ const uint8_t *in, size_t in_len) {
+ uint8_t *dest;
+ auto buf = CRYPTO_BUFFER_alloc(&dest, uncompressed_len);
+ auto len = uncompressed_len;
+
+ if (BrotliDecoderDecompress(in_len, in, &len, dest) !=
+ BROTLI_DECODER_RESULT_SUCCESS) {
+ LOG(ERROR) << "BrotliDecoderDecompress failed";
+
+ CRYPTO_BUFFER_free(buf);
+
+ return 0;
+ }
+
+ if (uncompressed_len != len) {
+ LOG(ERROR) << "Unexpected uncompressed length: expected "
+ << uncompressed_len << " bytes, actual " << len << " bytes";
+
+ CRYPTO_BUFFER_free(buf);
+
+ return 0;
+ }
+
+ *out = buf;
+
+ return 1;
+}
+} // namespace
+#endif // NGHTTP2_OPENSSL_IS_BORINGSSL && HAVE_LIBBROTLI
+
struct TLSProtocol {
StringRef name;
long int mask;
@@ -1110,6 +1216,15 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
SSL_CTX_set_psk_server_callback(ssl_ctx, psk_server_cb);
#endif // !LIBRESSL_NO_PSK
+#if defined(NGHTTP2_OPENSSL_IS_BORINGSSL) && defined(HAVE_LIBBROTLI)
+ if (!SSL_CTX_add_cert_compression_alg(
+ ssl_ctx, nghttp2::tls::CERTIFICATE_COMPRESSION_ALGO_BROTLI,
+ cert_compress, cert_decompress)) {
+ LOG(FATAL) << "SSL_CTX_add_cert_compression_alg failed";
+ DIE();
+ }
+#endif // NGHTTP2_OPENSSL_IS_BORINGSSL && HAVE_LIBBROTLI
+
return ssl_ctx;
}
@@ -1369,6 +1484,15 @@ SSL_CTX *create_quic_ssl_context(const char *private_key_file,
SSL_CTX_set_psk_server_callback(ssl_ctx, psk_server_cb);
# endif // !LIBRESSL_NO_PSK
+# if defined(NGHTTP2_OPENSSL_IS_BORINGSSL) && defined(HAVE_LIBBROTLI)
+ if (!SSL_CTX_add_cert_compression_alg(
+ ssl_ctx, nghttp2::tls::CERTIFICATE_COMPRESSION_ALGO_BROTLI,
+ cert_compress, cert_decompress)) {
+ LOG(FATAL) << "SSL_CTX_add_cert_compression_alg failed";
+ DIE();
+ }
+# endif // NGHTTP2_OPENSSL_IS_BORINGSSL && HAVE_LIBBROTLI
+
return ssl_ctx;
}
#endif // ENABLE_HTTP3
@@ -1478,6 +1602,15 @@ SSL_CTX *create_ssl_client_context(
SSL_CTX_set_psk_client_callback(ssl_ctx, psk_client_cb);
#endif // !OPENSSL_NO_PSK
+#if defined(NGHTTP2_OPENSSL_IS_BORINGSSL) && defined(HAVE_LIBBROTLI)
+ if (!SSL_CTX_add_cert_compression_alg(
+ ssl_ctx, nghttp2::tls::CERTIFICATE_COMPRESSION_ALGO_BROTLI,
+ cert_compress, cert_decompress)) {
+ LOG(FATAL) << "SSL_CTX_add_cert_compression_alg failed";
+ DIE();
+ }
+#endif // NGHTTP2_OPENSSL_IS_BORINGSSL && HAVE_LIBBROTLI
+
return ssl_ctx;
}
diff --git a/src/shrpx_tls_test.cc b/src/shrpx_tls_test.cc
index 02fb168..04d16da 100644
--- a/src/shrpx_tls_test.cc
+++ b/src/shrpx_tls_test.cc
@@ -24,7 +24,7 @@
*/
#include "shrpx_tls_test.h"
-#include <CUnit/CUnit.h>
+#include "munitxx.h"
#include "shrpx_tls.h"
#include "shrpx_log.h"
@@ -35,6 +35,21 @@ using namespace nghttp2;
namespace shrpx {
+namespace {
+const MunitTest tests[]{
+ munit_void_test(test_shrpx_tls_create_lookup_tree),
+ munit_void_test(test_shrpx_tls_cert_lookup_tree_add_ssl_ctx),
+ munit_void_test(test_shrpx_tls_tls_hostname_match),
+ munit_void_test(test_shrpx_tls_verify_numeric_hostname),
+ munit_void_test(test_shrpx_tls_verify_dns_hostname),
+ munit_test_end(),
+};
+} // namespace
+
+const MunitSuite tls_suite{
+ "/tls", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
void test_shrpx_tls_create_lookup_tree(void) {
auto tree = std::make_unique<tls::CertLookupTree>();
@@ -58,24 +73,24 @@ void test_shrpx_tls_create_lookup_tree(void) {
tree->dump();
- CU_ASSERT(0 == tree->lookup(hostnames[0]));
- CU_ASSERT(1 == tree->lookup(hostnames[1]));
- CU_ASSERT(2 == tree->lookup(StringRef::from_lit("2www.example.org")));
- CU_ASSERT(-1 == tree->lookup(StringRef::from_lit("www2.example.org")));
- CU_ASSERT(3 == tree->lookup(StringRef::from_lit("xy1.host.domain")));
+ assert_ssize(0, ==, tree->lookup(hostnames[0]));
+ assert_ssize(1, ==, tree->lookup(hostnames[1]));
+ assert_ssize(2, ==, tree->lookup(StringRef::from_lit("2www.example.org")));
+ assert_ssize(-1, ==, tree->lookup(StringRef::from_lit("www2.example.org")));
+ assert_ssize(3, ==, tree->lookup(StringRef::from_lit("xy1.host.domain")));
// Does not match *yy.host.domain, because * must match at least 1
// character.
- CU_ASSERT(-1 == tree->lookup(StringRef::from_lit("yy.host.domain")));
- CU_ASSERT(4 == tree->lookup(StringRef::from_lit("xyy.host.domain")));
- CU_ASSERT(-1 == tree->lookup(StringRef{}));
- CU_ASSERT(5 == tree->lookup(hostnames[5]));
- CU_ASSERT(6 == tree->lookup(hostnames[6]));
+ assert_ssize(-1, ==, tree->lookup(StringRef::from_lit("yy.host.domain")));
+ assert_ssize(4, ==, tree->lookup(StringRef::from_lit("xyy.host.domain")));
+ assert_ssize(-1, ==, tree->lookup(StringRef{}));
+ assert_ssize(5, ==, tree->lookup(hostnames[5]));
+ assert_ssize(6, ==, tree->lookup(hostnames[6]));
static constexpr char h6[] = "pdylay.sourceforge.net";
for (int i = 0; i < 7; ++i) {
- CU_ASSERT(-1 == tree->lookup(StringRef{h6 + i, str_size(h6) - i}));
+ assert_ssize(-1, ==, tree->lookup(StringRef{h6 + i, str_size(h6) - i}));
}
- CU_ASSERT(8 == tree->lookup(StringRef::from_lit("x.foo.bar")));
- CU_ASSERT(9 == tree->lookup(hostnames[9]));
+ assert_ssize(8, ==, tree->lookup(StringRef::from_lit("x.foo.bar")));
+ assert_ssize(9, ==, tree->lookup(hostnames[9]));
constexpr StringRef names[] = {
StringRef::from_lit("rab"), // 1
@@ -90,7 +105,7 @@ void test_shrpx_tls_create_lookup_tree(void) {
tree->add_cert(names[idx], idx);
}
for (size_t i = 0; i < num; ++i) {
- CU_ASSERT((ssize_t)i == tree->lookup(names[i]));
+ assert_ssize((ssize_t)i, ==, tree->lookup(names[i]));
}
}
@@ -128,7 +143,7 @@ void test_shrpx_tls_cert_lookup_tree_add_ssl_ctx(void) {
SSL_CTX_set_app_data(nghttp2_ssl_ctx, nghttp2_tls_ctx_data.get());
rv = SSL_CTX_use_certificate_chain_file(nghttp2_ssl_ctx, nghttp2_certfile);
- CU_ASSERT(1 == rv);
+ assert_int(1, ==, rv);
static constexpr char examples_certfile[] =
NGHTTP2_SRC_DIR "/test.example.com.pem";
@@ -139,7 +154,7 @@ void test_shrpx_tls_cert_lookup_tree_add_ssl_ctx(void) {
SSL_CTX_set_app_data(examples_ssl_ctx, examples_tls_ctx_data.get());
rv = SSL_CTX_use_certificate_chain_file(examples_ssl_ctx, examples_certfile);
- CU_ASSERT(1 == rv);
+ assert_int(1, ==, rv);
tls::CertLookupTree tree;
std::vector<std::vector<SSL_CTX *>> indexed_ssl_ctx;
@@ -147,18 +162,19 @@ void test_shrpx_tls_cert_lookup_tree_add_ssl_ctx(void) {
rv = tls::cert_lookup_tree_add_ssl_ctx(&tree, indexed_ssl_ctx,
nghttp2_ssl_ctx);
- CU_ASSERT(0 == rv);
+ assert_int(0, ==, rv);
rv = tls::cert_lookup_tree_add_ssl_ctx(&tree, indexed_ssl_ctx,
examples_ssl_ctx);
- CU_ASSERT(0 == rv);
+ assert_int(0, ==, rv);
- CU_ASSERT(-1 == tree.lookup(StringRef::from_lit("not-used.nghttp2.org")));
- CU_ASSERT(0 == tree.lookup(StringRef::from_lit("test.nghttp2.org")));
- CU_ASSERT(1 == tree.lookup(StringRef::from_lit("w.test.nghttp2.org")));
- CU_ASSERT(2 == tree.lookup(StringRef::from_lit("www.test.nghttp2.org")));
- CU_ASSERT(3 == tree.lookup(StringRef::from_lit("test.example.com")));
+ assert_ssize(-1, ==,
+ tree.lookup(StringRef::from_lit("not-used.nghttp2.org")));
+ assert_ssize(0, ==, tree.lookup(StringRef::from_lit("test.nghttp2.org")));
+ assert_ssize(1, ==, tree.lookup(StringRef::from_lit("w.test.nghttp2.org")));
+ assert_ssize(2, ==, tree.lookup(StringRef::from_lit("www.test.nghttp2.org")));
+ assert_ssize(3, ==, tree.lookup(StringRef::from_lit("test.example.com")));
}
template <size_t N, size_t M>
@@ -168,30 +184,32 @@ bool tls_hostname_match_wrapper(const char (&pattern)[N],
}
void test_shrpx_tls_tls_hostname_match(void) {
- CU_ASSERT(tls_hostname_match_wrapper("example.com", "example.com"));
- CU_ASSERT(tls_hostname_match_wrapper("example.com", "EXAMPLE.com"));
+ assert_true(tls_hostname_match_wrapper("example.com", "example.com"));
+ assert_true(tls_hostname_match_wrapper("example.com", "EXAMPLE.com"));
// check wildcard
- CU_ASSERT(tls_hostname_match_wrapper("*.example.com", "www.example.com"));
- CU_ASSERT(tls_hostname_match_wrapper("*w.example.com", "www.example.com"));
- CU_ASSERT(tls_hostname_match_wrapper("www*.example.com", "www1.example.com"));
- CU_ASSERT(
+ assert_true(tls_hostname_match_wrapper("*.example.com", "www.example.com"));
+ assert_true(tls_hostname_match_wrapper("*w.example.com", "www.example.com"));
+ assert_true(
+ tls_hostname_match_wrapper("www*.example.com", "www1.example.com"));
+ assert_true(
tls_hostname_match_wrapper("www*.example.com", "WWW12.EXAMPLE.com"));
// at least 2 dots are required after '*'
- CU_ASSERT(!tls_hostname_match_wrapper("*.com", "example.com"));
- CU_ASSERT(!tls_hostname_match_wrapper("*", "example.com"));
+ assert_false(tls_hostname_match_wrapper("*.com", "example.com"));
+ assert_false(tls_hostname_match_wrapper("*", "example.com"));
// '*' must be in left most label
- CU_ASSERT(
- !tls_hostname_match_wrapper("blog.*.example.com", "blog.my.example.com"));
+ assert_false(
+ tls_hostname_match_wrapper("blog.*.example.com", "blog.my.example.com"));
// prefix is wrong
- CU_ASSERT(
- !tls_hostname_match_wrapper("client*.example.com", "server.example.com"));
+ assert_false(
+ tls_hostname_match_wrapper("client*.example.com", "server.example.com"));
// '*' must match at least one character
- CU_ASSERT(!tls_hostname_match_wrapper("www*.example.com", "www.example.com"));
+ assert_false(
+ tls_hostname_match_wrapper("www*.example.com", "www.example.com"));
- CU_ASSERT(!tls_hostname_match_wrapper("example.com", "nghttp2.org"));
- CU_ASSERT(!tls_hostname_match_wrapper("www.example.com", "example.com"));
- CU_ASSERT(!tls_hostname_match_wrapper("example.com", "www.example.com"));
+ assert_false(tls_hostname_match_wrapper("example.com", "nghttp2.org"));
+ assert_false(tls_hostname_match_wrapper("www.example.com", "example.com"));
+ assert_false(tls_hostname_match_wrapper("example.com", "www.example.com"));
}
static X509 *load_cert(const char *path) {
@@ -207,14 +225,17 @@ static Address parse_addr(const char *ipaddr) {
addrinfo hints{};
hints.ai_family = AF_UNSPEC;
- hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
+ hints.ai_flags = AI_NUMERICHOST;
+#ifdef AI_NUMERICSERV
+ hints.ai_flags |= AI_NUMERICSERV;
+#endif
addrinfo *res = nullptr;
auto rv = getaddrinfo(ipaddr, "443", &hints, &res);
- CU_ASSERT(0 == rv);
- CU_ASSERT(nullptr != res);
+ assert_int(0, ==, rv);
+ assert_not_null(res);
Address addr;
addr.len = res->ai_addrlen;
@@ -234,7 +255,7 @@ void test_shrpx_tls_verify_numeric_hostname(void) {
auto rv =
tls::verify_numeric_hostname(cert, StringRef::from_lit(ipaddr), &addr);
- CU_ASSERT(0 == rv);
+ assert_int(0, ==, rv);
X509_free(cert);
}
@@ -247,7 +268,7 @@ void test_shrpx_tls_verify_numeric_hostname(void) {
auto rv =
tls::verify_numeric_hostname(cert, StringRef::from_lit(ipaddr), &addr);
- CU_ASSERT(0 == rv);
+ assert_int(0, ==, rv);
X509_free(cert);
}
@@ -260,7 +281,7 @@ void test_shrpx_tls_verify_numeric_hostname(void) {
auto rv =
tls::verify_numeric_hostname(cert, StringRef::from_lit(ipaddr), &addr);
- CU_ASSERT(-1 == rv);
+ assert_int(-1, ==, rv);
X509_free(cert);
}
@@ -273,7 +294,7 @@ void test_shrpx_tls_verify_numeric_hostname(void) {
auto rv =
tls::verify_numeric_hostname(cert, StringRef::from_lit(ipaddr), &addr);
- CU_ASSERT(-1 == rv);
+ assert_int(-1, ==, rv);
X509_free(cert);
}
@@ -286,7 +307,7 @@ void test_shrpx_tls_verify_numeric_hostname(void) {
auto rv =
tls::verify_numeric_hostname(cert, StringRef::from_lit(ipaddr), &addr);
- CU_ASSERT(0 == rv);
+ assert_int(0, ==, rv);
X509_free(cert);
}
@@ -299,7 +320,7 @@ void test_shrpx_tls_verify_dns_hostname(void) {
auto rv = tls::verify_dns_hostname(
cert, StringRef::from_lit("nghttp2.example.com"));
- CU_ASSERT(0 == rv);
+ assert_int(0, ==, rv);
X509_free(cert);
}
@@ -310,7 +331,7 @@ void test_shrpx_tls_verify_dns_hostname(void) {
auto rv = tls::verify_dns_hostname(
cert, StringRef::from_lit("www.nghttp2.example.com"));
- CU_ASSERT(0 == rv);
+ assert_int(0, ==, rv);
X509_free(cert);
}
@@ -320,7 +341,7 @@ void test_shrpx_tls_verify_dns_hostname(void) {
auto cert = load_cert(NGHTTP2_SRC_DIR "/testdata/verify_hostname.crt");
auto rv = tls::verify_dns_hostname(cert, StringRef::from_lit("localhost"));
- CU_ASSERT(-1 == rv);
+ assert_int(-1, ==, rv);
X509_free(cert);
}
@@ -330,7 +351,7 @@ void test_shrpx_tls_verify_dns_hostname(void) {
auto cert = load_cert(NGHTTP2_SRC_DIR "/testdata/nosan.crt");
auto rv = tls::verify_dns_hostname(cert, StringRef::from_lit("localhost"));
- CU_ASSERT(0 == rv);
+ assert_int(0, ==, rv);
X509_free(cert);
}
diff --git a/src/shrpx_tls_test.h b/src/shrpx_tls_test.h
index 7edc742..3334b23 100644
--- a/src/shrpx_tls_test.h
+++ b/src/shrpx_tls_test.h
@@ -29,13 +29,19 @@
# include <config.h>
#endif // HAVE_CONFIG_H
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
namespace shrpx {
-void test_shrpx_tls_create_lookup_tree(void);
-void test_shrpx_tls_cert_lookup_tree_add_ssl_ctx(void);
-void test_shrpx_tls_tls_hostname_match(void);
-void test_shrpx_tls_verify_numeric_hostname(void);
-void test_shrpx_tls_verify_dns_hostname(void);
+extern const MunitSuite tls_suite;
+
+munit_void_test_decl(test_shrpx_tls_create_lookup_tree);
+munit_void_test_decl(test_shrpx_tls_cert_lookup_tree_add_ssl_ctx);
+munit_void_test_decl(test_shrpx_tls_tls_hostname_match);
+munit_void_test_decl(test_shrpx_tls_verify_numeric_hostname);
+munit_void_test_decl(test_shrpx_tls_verify_dns_hostname);
} // namespace shrpx
diff --git a/src/shrpx_worker.cc b/src/shrpx_worker.cc
index 4c069db..e7d6740 100644
--- a/src/shrpx_worker.cc
+++ b/src/shrpx_worker.cc
@@ -731,6 +731,119 @@ int Worker::setup_quic_server_socket() {
return 0;
}
+# ifdef HAVE_LIBBPF
+namespace {
+// https://github.com/kokke/tiny-AES-c
+//
+// License is Public Domain.
+// Commit hash: 12e7744b4919e9d55de75b7ab566326a1c8e7a67
+
+// The number of columns comprising a state in AES. This is a constant
+// in AES. Value=4
+# define Nb 4
+
+# define Nk 4 // The number of 32 bit words in a key.
+# define Nr 10 // The number of rounds in AES Cipher.
+
+// The lookup-tables are marked const so they can be placed in
+// read-only storage instead of RAM The numbers below can be computed
+// dynamically trading ROM for RAM - This can be useful in (embedded)
+// bootloader applications, where ROM is often limited.
+const uint8_t sbox[256] = {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
+ 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
+ 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
+ 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
+ 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
+ 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
+ 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
+ 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
+ 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
+ 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
+ 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
+ 0xb0, 0x54, 0xbb, 0x16};
+
+# define getSBoxValue(num) (sbox[(num)])
+
+// The round constant word array, Rcon[i], contains the values given
+// by x to the power (i-1) being powers of x (x is denoted as {02}) in
+// the field GF(2^8)
+const uint8_t Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10,
+ 0x20, 0x40, 0x80, 0x1b, 0x36};
+
+// This function produces Nb(Nr+1) round keys. The round keys are used
+// in each round to decrypt the states.
+void KeyExpansion(uint8_t *RoundKey, const uint8_t *Key) {
+ unsigned i, j, k;
+ uint8_t tempa[4]; // Used for the column/row operations
+
+ // The first round key is the key itself.
+ for (i = 0; i < Nk; ++i) {
+ RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
+ RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
+ RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
+ RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
+ }
+
+ // All other round keys are found from the previous round keys.
+ for (i = Nk; i < Nb * (Nr + 1); ++i) {
+ {
+ k = (i - 1) * 4;
+ tempa[0] = RoundKey[k + 0];
+ tempa[1] = RoundKey[k + 1];
+ tempa[2] = RoundKey[k + 2];
+ tempa[3] = RoundKey[k + 3];
+ }
+
+ if (i % Nk == 0) {
+ // This function shifts the 4 bytes in a word to the left once.
+ // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
+
+ // Function RotWord()
+ {
+ const uint8_t u8tmp = tempa[0];
+ tempa[0] = tempa[1];
+ tempa[1] = tempa[2];
+ tempa[2] = tempa[3];
+ tempa[3] = u8tmp;
+ }
+
+ // SubWord() is a function that takes a four-byte input word and
+ // applies the S-box to each of the four bytes to produce an
+ // output word.
+
+ // Function Subword()
+ {
+ tempa[0] = getSBoxValue(tempa[0]);
+ tempa[1] = getSBoxValue(tempa[1]);
+ tempa[2] = getSBoxValue(tempa[2]);
+ tempa[3] = getSBoxValue(tempa[3]);
+ }
+
+ tempa[0] = tempa[0] ^ Rcon[i / Nk];
+ }
+ j = i * 4;
+ k = (i - Nk) * 4;
+ RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
+ RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
+ RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
+ RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
+ }
+}
+} // namespace
+# endif // HAVE_LIBBPF
+
int Worker::create_quic_server_socket(UpstreamAddr &faddr) {
std::array<char, STRERROR_BUFSIZE> errbuf;
int fd = -1;
@@ -989,30 +1102,29 @@ int Worker::create_quic_server_socket(UpstreamAddr &faddr) {
return -1;
}
- constexpr uint32_t key_high_idx = 1;
- constexpr uint32_t key_low_idx = 2;
-
auto &qkms = conn_handler_->get_quic_keying_materials();
auto &qkm = qkms->keying_materials.front();
- rv = bpf_map__update_elem(sk_info, &key_high_idx, sizeof(key_high_idx),
- qkm.cid_encryption_key.data(),
- qkm.cid_encryption_key.size() / 2, BPF_ANY);
- if (rv != 0) {
+ auto aes_key = bpf_object__find_map_by_name(obj, "aes_key");
+ if (!aes_key) {
auto error = errno;
- LOG(FATAL) << "Failed to update key_high_idx sk_info: "
+ LOG(FATAL) << "Failed to get aes_key: "
<< xsi_strerror(error, errbuf.data(), errbuf.size());
close(fd);
return -1;
}
- rv = bpf_map__update_elem(sk_info, &key_low_idx, sizeof(key_low_idx),
- qkm.cid_encryption_key.data() +
- qkm.cid_encryption_key.size() / 2,
- qkm.cid_encryption_key.size() / 2, BPF_ANY);
+ constexpr size_t expanded_aes_keylen = 176;
+ std::array<uint8_t, expanded_aes_keylen> aes_exp_key;
+
+ KeyExpansion(aes_exp_key.data(), qkm.cid_encryption_key.data());
+
+ rv =
+ bpf_map__update_elem(aes_key, &zero, sizeof(zero), aes_exp_key.data(),
+ aes_exp_key.size(), BPF_ANY);
if (rv != 0) {
auto error = errno;
- LOG(FATAL) << "Failed to update key_low_idx sk_info: "
+ LOG(FATAL) << "Failed to update aes_key: "
<< xsi_strerror(error, errbuf.data(), errbuf.size());
close(fd);
return -1;
diff --git a/src/shrpx_worker_process.cc b/src/shrpx_worker_process.cc
index 05eac02..e3f7dae 100644
--- a/src/shrpx_worker_process.cc
+++ b/src/shrpx_worker_process.cc
@@ -583,6 +583,16 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
LOG(ERROR) << "Failed to generate QUIC Connection ID encryption key";
return -1;
}
+
+ qkm.cid_encryption_ctx = EVP_CIPHER_CTX_new();
+ if (!EVP_EncryptInit_ex(qkm.cid_encryption_ctx, EVP_aes_128_ecb(), nullptr,
+ qkm.cid_encryption_key.data(), nullptr)) {
+ LOG(ERROR)
+ << "Failed to initialize QUIC Connection ID encryption context";
+ return -1;
+ }
+
+ EVP_CIPHER_CTX_set_padding(qkm.cid_encryption_ctx, 0);
}
conn_handler->set_quic_keying_materials(std::move(qkms));
diff --git a/src/shrpx_worker_test.cc b/src/shrpx_worker_test.cc
index 7c5c329..4b4b7a6 100644
--- a/src/shrpx_worker_test.cc
+++ b/src/shrpx_worker_test.cc
@@ -30,7 +30,7 @@
#include <cstdlib>
-#include <CUnit/CUnit.h>
+#include "munitxx.h"
#include "shrpx_worker.h"
#include "shrpx_connect_blocker.h"
@@ -38,6 +38,17 @@
namespace shrpx {
+namespace {
+const MunitTest tests[]{
+ munit_void_test(test_shrpx_worker_match_downstream_addr_group),
+ munit_test_end(),
+};
+} // namespace
+
+const MunitSuite worker_suite{
+ "/worker", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
void test_shrpx_worker_match_downstream_addr_group(void) {
auto groups = std::vector<std::shared_ptr<DownstreamAddrGroup>>();
for (auto &s : {"nghttp2.org/", "nghttp2.org/alpha/bravo/",
@@ -62,131 +73,155 @@ void test_shrpx_worker_match_downstream_addr_group(void) {
router.add_route(StringRef{g->pattern}, i);
}
- CU_ASSERT(0 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/"), groups, 255, balloc));
+ assert_size(0, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/"), groups, 255, balloc));
// port is removed
- CU_ASSERT(0 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("nghttp2.org:8080"),
- StringRef::from_lit("/"), groups, 255, balloc));
+ assert_size(0, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("nghttp2.org:8080"),
+ StringRef::from_lit("/"), groups, 255, balloc));
// host is case-insensitive
- CU_ASSERT(4 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("WWW.nghttp2.org"),
- StringRef::from_lit("/alpha"), groups, 255, balloc));
+ assert_size(4, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("WWW.nghttp2.org"),
+ StringRef::from_lit("/alpha"), groups, 255, balloc));
- CU_ASSERT(1 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/alpha/bravo/"), groups, 255,
- balloc));
+ assert_size(1, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/alpha/bravo/"), groups, 255, balloc));
// /alpha/bravo also matches /alpha/bravo/
- CU_ASSERT(1 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/alpha/bravo"), groups, 255, balloc));
+ assert_size(1, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/alpha/bravo"), groups, 255, balloc));
// path part is case-sensitive
- CU_ASSERT(0 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/Alpha/bravo"), groups, 255, balloc));
-
- CU_ASSERT(1 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/alpha/bravo/charlie"), groups, 255,
- balloc));
-
- CU_ASSERT(2 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/alpha/charlie"), groups, 255,
- balloc));
+ assert_size(0, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/Alpha/bravo"), groups, 255, balloc));
+
+ assert_size(1, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/alpha/bravo/charlie"), groups, 255,
+ balloc));
+
+ assert_size(2, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/alpha/charlie"), groups, 255, balloc));
// pattern which does not end with '/' must match its entirely. So
// this matches to group 0, not group 2.
- CU_ASSERT(0 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/alpha/charlie/"), groups, 255,
- balloc));
-
- CU_ASSERT(255 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("example.org"),
- StringRef::from_lit("/"), groups, 255, balloc));
-
- CU_ASSERT(255 == match_downstream_addr_group(
- routerconf, StringRef::from_lit(""),
- StringRef::from_lit("/"), groups, 255, balloc));
-
- CU_ASSERT(255 == match_downstream_addr_group(
- routerconf, StringRef::from_lit(""),
- StringRef::from_lit("alpha"), groups, 255, balloc));
-
- CU_ASSERT(255 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("foo/bar"),
- StringRef::from_lit("/"), groups, 255, balloc));
+ assert_size(0, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/alpha/charlie/"), groups, 255, balloc));
+
+ assert_size(255, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("example.org"),
+ StringRef::from_lit("/"), groups, 255, balloc));
+
+ assert_size(255, ==,
+ match_downstream_addr_group(routerconf, StringRef::from_lit(""),
+ StringRef::from_lit("/"), groups, 255,
+ balloc));
+
+ assert_size(255, ==,
+ match_downstream_addr_group(routerconf, StringRef::from_lit(""),
+ StringRef::from_lit("alpha"), groups,
+ 255, balloc));
+
+ assert_size(255, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("foo/bar"),
+ StringRef::from_lit("/"), groups, 255, balloc));
// If path is StringRef::from_lit("*", only match with host + "/").
- CU_ASSERT(0 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("*"), groups, 255, balloc));
-
- CU_ASSERT(5 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("[::1]"),
- StringRef::from_lit("/"), groups, 255, balloc));
- CU_ASSERT(5 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("[::1]:8080"),
- StringRef::from_lit("/"), groups, 255, balloc));
- CU_ASSERT(255 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("[::1"),
- StringRef::from_lit("/"), groups, 255, balloc));
- CU_ASSERT(255 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("[::1]8000"),
- StringRef::from_lit("/"), groups, 255, balloc));
+ assert_size(0, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("*"), groups, 255, balloc));
+
+ assert_size(5, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("[::1]"),
+ StringRef::from_lit("/"), groups, 255, balloc));
+ assert_size(5, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("[::1]:8080"),
+ StringRef::from_lit("/"), groups, 255, balloc));
+ assert_size(255, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("[::1"),
+ StringRef::from_lit("/"), groups, 255, balloc));
+ assert_size(255, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("[::1]8000"),
+ StringRef::from_lit("/"), groups, 255, balloc));
// Check the case where adding route extends tree
- CU_ASSERT(6 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/alpha/bravo/delta"), groups, 255,
- balloc));
-
- CU_ASSERT(1 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/alpha/bravo/delta/"), groups, 255,
- balloc));
+ assert_size(6, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/alpha/bravo/delta"), groups, 255,
+ balloc));
+
+ assert_size(1, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/alpha/bravo/delta/"), groups, 255,
+ balloc));
// Check the case where query is done in a single node
- CU_ASSERT(7 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("example.com"),
- StringRef::from_lit("/alpha/bravo"), groups, 255, balloc));
+ assert_size(7, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("example.com"),
+ StringRef::from_lit("/alpha/bravo"), groups, 255, balloc));
- CU_ASSERT(255 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("example.com"),
- StringRef::from_lit("/alpha/bravo/"), groups, 255,
- balloc));
+ assert_size(255, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("example.com"),
+ StringRef::from_lit("/alpha/bravo/"), groups, 255, balloc));
- CU_ASSERT(255 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("example.com"),
- StringRef::from_lit("/alpha"), groups, 255, balloc));
+ assert_size(255, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("example.com"),
+ StringRef::from_lit("/alpha"), groups, 255, balloc));
// Check the case where quey is done in a single node
- CU_ASSERT(8 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("192.168.0.1"),
- StringRef::from_lit("/alpha"), groups, 255, balloc));
-
- CU_ASSERT(8 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("192.168.0.1"),
- StringRef::from_lit("/alpha/"), groups, 255, balloc));
-
- CU_ASSERT(8 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("192.168.0.1"),
- StringRef::from_lit("/alpha/bravo"), groups, 255, balloc));
-
- CU_ASSERT(255 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("192.168.0.1"),
- StringRef::from_lit("/alph"), groups, 255, balloc));
-
- CU_ASSERT(255 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("192.168.0.1"),
- StringRef::from_lit("/"), groups, 255, balloc));
+ assert_size(8, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("192.168.0.1"),
+ StringRef::from_lit("/alpha"), groups, 255, balloc));
+
+ assert_size(8, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("192.168.0.1"),
+ StringRef::from_lit("/alpha/"), groups, 255, balloc));
+
+ assert_size(8, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("192.168.0.1"),
+ StringRef::from_lit("/alpha/bravo"), groups, 255, balloc));
+
+ assert_size(255, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("192.168.0.1"),
+ StringRef::from_lit("/alph"), groups, 255, balloc));
+
+ assert_size(255, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("192.168.0.1"),
+ StringRef::from_lit("/"), groups, 255, balloc));
// Test for wildcard hosts
auto g1 = std::make_shared<DownstreamAddrGroup>();
@@ -214,34 +249,40 @@ void test_shrpx_worker_match_downstream_addr_group(void) {
wcrouter.add_route(StringRef::from_lit("lacol."), 2);
wp.back().router.add_route(StringRef::from_lit("/"), 13);
- CU_ASSERT(11 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("git.nghttp2.org"),
- StringRef::from_lit("/echo"), groups, 255, balloc));
-
- CU_ASSERT(10 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("0git.nghttp2.org"),
- StringRef::from_lit("/echo"), groups, 255, balloc));
-
- CU_ASSERT(11 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("it.nghttp2.org"),
- StringRef::from_lit("/echo"), groups, 255, balloc));
-
- CU_ASSERT(255 == match_downstream_addr_group(
- routerconf, StringRef::from_lit(".nghttp2.org"),
- StringRef::from_lit("/echo/foxtrot"), groups, 255,
- balloc));
-
- CU_ASSERT(9 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("alpha.nghttp2.org"),
- StringRef::from_lit("/golf"), groups, 255, balloc));
-
- CU_ASSERT(0 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("nghttp2.org"),
- StringRef::from_lit("/echo"), groups, 255, balloc));
-
- CU_ASSERT(13 == match_downstream_addr_group(
- routerconf, StringRef::from_lit("test.local"),
- StringRef{}, groups, 255, balloc));
+ assert_size(11, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("git.nghttp2.org"),
+ StringRef::from_lit("/echo"), groups, 255, balloc));
+
+ assert_size(10, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("0git.nghttp2.org"),
+ StringRef::from_lit("/echo"), groups, 255, balloc));
+
+ assert_size(11, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("it.nghttp2.org"),
+ StringRef::from_lit("/echo"), groups, 255, balloc));
+
+ assert_size(255, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit(".nghttp2.org"),
+ StringRef::from_lit("/echo/foxtrot"), groups, 255, balloc));
+
+ assert_size(9, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("alpha.nghttp2.org"),
+ StringRef::from_lit("/golf"), groups, 255, balloc));
+
+ assert_size(0, ==,
+ match_downstream_addr_group(
+ routerconf, StringRef::from_lit("nghttp2.org"),
+ StringRef::from_lit("/echo"), groups, 255, balloc));
+
+ assert_size(13, ==,
+ match_downstream_addr_group(routerconf,
+ StringRef::from_lit("test.local"),
+ StringRef{}, groups, 255, balloc));
}
} // namespace shrpx
diff --git a/src/shrpx_worker_test.h b/src/shrpx_worker_test.h
index 8ffa2f1..4dfaa2b 100644
--- a/src/shrpx_worker_test.h
+++ b/src/shrpx_worker_test.h
@@ -29,9 +29,15 @@
# include <config.h>
#endif // HAVE_CONFIG_H
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
namespace shrpx {
-void test_shrpx_worker_match_downstream_addr_group(void);
+extern const MunitSuite worker_suite;
+
+munit_void_test_decl(test_shrpx_worker_match_downstream_addr_group);
} // namespace shrpx
diff --git a/src/template_test.cc b/src/template_test.cc
index 4a77315..db212d1 100644
--- a/src/template_test.cc
+++ b/src/template_test.cc
@@ -28,80 +28,92 @@
#include <iostream>
#include <sstream>
-#include <CUnit/CUnit.h>
+#include "munitxx.h"
#include "template.h"
namespace nghttp2 {
+namespace {
+const MunitTest tests[]{
+ munit_void_test(test_template_immutable_string),
+ munit_void_test(test_template_string_ref),
+ munit_test_end(),
+};
+} // namespace
+
+const MunitSuite template_suite{
+ "/template", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
void test_template_immutable_string(void) {
ImmutableString null;
- CU_ASSERT("" == null);
- CU_ASSERT(0 == null.size());
- CU_ASSERT(null.empty());
+ assert_string_equal("", null.c_str());
+ assert_size(0, ==, null.size());
+ assert_true(null.empty());
ImmutableString from_cstr("alpha");
- CU_ASSERT(0 == strcmp("alpha", from_cstr.c_str()));
- CU_ASSERT(5 == from_cstr.size());
- CU_ASSERT(!from_cstr.empty());
- CU_ASSERT("alpha" == from_cstr);
- CU_ASSERT(from_cstr == "alpha");
- CU_ASSERT(std::string("alpha") == from_cstr);
- CU_ASSERT(from_cstr == std::string("alpha"));
+ assert_string_equal("alpha", from_cstr.c_str());
+ assert_size(5, ==, from_cstr.size());
+ assert_false(from_cstr.empty());
+ assert_true("alpha" == from_cstr);
+ assert_true(from_cstr == "alpha");
+ assert_true(std::string("alpha") == from_cstr);
+ assert_true(from_cstr == std::string("alpha"));
// copy constructor
ImmutableString src("charlie");
ImmutableString copy = src;
- CU_ASSERT("charlie" == copy);
- CU_ASSERT(7 == copy.size());
+ assert_string_equal("charlie", copy.c_str());
+ assert_size(7, ==, copy.size());
// copy assignment
ImmutableString copy2;
copy2 = src;
- CU_ASSERT("charlie" == copy2);
- CU_ASSERT(7 == copy2.size());
+ assert_string_equal("charlie", copy2.c_str());
+ assert_size(7, ==, copy2.size());
// move constructor
ImmutableString move = std::move(copy);
- CU_ASSERT("charlie" == move);
- CU_ASSERT(7 == move.size());
- CU_ASSERT("" == copy);
- CU_ASSERT(0 == copy.size());
+ assert_string_equal("charlie", move.c_str());
+ assert_size(7, ==, move.size());
+ assert_string_equal("", copy.c_str());
+ assert_size(0, ==, copy.size());
// move assignment
move = std::move(from_cstr);
- CU_ASSERT("alpha" == move);
- CU_ASSERT(5 == move.size());
- CU_ASSERT("" == from_cstr);
- CU_ASSERT(0 == from_cstr.size());
+ assert_string_equal("alpha", move.c_str());
+ assert_size(5, ==, move.size());
+ assert_string_equal("", from_cstr.c_str());
+ assert_size(0, ==, from_cstr.size());
// from string literal
- auto from_lit = StringRef::from_lit("bravo");
+ auto from_lit = ImmutableString::from_lit("bravo");
- CU_ASSERT("bravo" == from_lit);
- CU_ASSERT(5 == from_lit.size());
+ assert_string_equal("bravo", from_lit.c_str());
+ assert_size(5, ==, from_lit.size());
// equality
ImmutableString eq("delta");
- CU_ASSERT("delta1" != eq);
- CU_ASSERT("delt" != eq);
- CU_ASSERT(eq != "delta1");
- CU_ASSERT(eq != "delt");
+ assert_true("delta1" != eq);
+ assert_true("delt" != eq);
+ assert_true(eq != "delta1");
+ assert_true(eq != "delt");
// operator[]
ImmutableString br_op("foxtrot");
- CU_ASSERT('f' == br_op[0]);
- CU_ASSERT('o' == br_op[1]);
- CU_ASSERT('t' == br_op[6]);
- CU_ASSERT('\0' == br_op[7]);
+ assert_char('f', ==, br_op[0]);
+ assert_char('o', ==, br_op[1]);
+ assert_char('t', ==, br_op[6]);
+ assert_char('\0', ==, br_op[7]);
// operator==(const ImmutableString &, const ImmutableString &)
{
@@ -109,9 +121,9 @@ void test_template_immutable_string(void) {
ImmutableString b("foo");
ImmutableString c("fo");
- CU_ASSERT(a == b);
- CU_ASSERT(a != c);
- CU_ASSERT(c != b);
+ assert_true(a == b);
+ assert_true(a != c);
+ assert_true(c != b);
}
// operator<<
@@ -120,7 +132,7 @@ void test_template_immutable_string(void) {
std::stringstream ss;
ss << a;
- CU_ASSERT("foo" == ss.str());
+ assert_stdstring_equal("foo", ss.str());
}
// operator +=(std::string &, const ImmutableString &)
@@ -128,60 +140,60 @@ void test_template_immutable_string(void) {
std::string a = "alpha";
a += ImmutableString("bravo");
- CU_ASSERT("alphabravo" == a);
+ assert_stdstring_equal("alphabravo", a);
}
}
void test_template_string_ref(void) {
StringRef empty;
- CU_ASSERT("" == empty);
- CU_ASSERT(0 == empty.size());
+ assert_stdstring_equal("", empty.str());
+ assert_size(0, ==, empty.size());
// from std::string
std::string alpha = "alpha";
StringRef ref(alpha);
- CU_ASSERT("alpha" == ref);
- CU_ASSERT(ref == "alpha");
- CU_ASSERT(alpha == ref);
- CU_ASSERT(ref == alpha);
- CU_ASSERT(5 == ref.size());
+ assert_true("alpha" == ref);
+ assert_true(ref == "alpha");
+ assert_true(alpha == ref);
+ assert_true(ref == alpha);
+ assert_size(5, ==, ref.size());
// from string literal
auto from_lit = StringRef::from_lit("alpha");
- CU_ASSERT("alpha" == from_lit);
- CU_ASSERT(5 == from_lit.size());
+ assert_stdstring_equal("alpha", from_lit.str());
+ assert_size(5, ==, from_lit.size());
// from ImmutableString
auto im = ImmutableString::from_lit("bravo");
StringRef imref(im);
- CU_ASSERT("bravo" == imref);
- CU_ASSERT(5 == imref.size());
+ assert_stdstring_equal("bravo", imref.str());
+ assert_size(5, ==, imref.size());
// from C-string
StringRef cstrref("charlie");
- CU_ASSERT("charlie" == cstrref);
- CU_ASSERT(7 == cstrref.size());
+ assert_stdstring_equal("charlie", cstrref.str());
+ assert_size(7, ==, cstrref.size());
// from C-string and its length
StringRef cstrnref("delta", 5);
- CU_ASSERT("delta" == cstrnref);
- CU_ASSERT(5 == cstrnref.size());
+ assert_stdstring_equal("delta", cstrnref.str());
+ assert_size(5, ==, cstrnref.size());
// operator[]
StringRef br_op("foxtrot");
- CU_ASSERT('f' == br_op[0]);
- CU_ASSERT('o' == br_op[1]);
- CU_ASSERT('t' == br_op[6]);
- CU_ASSERT('\0' == br_op[7]);
+ assert_char('f', ==, br_op[0]);
+ assert_char('o', ==, br_op[1]);
+ assert_char('t', ==, br_op[6]);
+ assert_char('\0', ==, br_op[7]);
// operator<<
{
@@ -189,7 +201,7 @@ void test_template_string_ref(void) {
std::stringstream ss;
ss << a;
- CU_ASSERT("foo" == ss.str());
+ assert_stdstring_equal("foo", ss.str());
}
// operator +=(std::string &, const StringRef &)
@@ -197,7 +209,7 @@ void test_template_string_ref(void) {
std::string a = "alpha";
a += StringRef("bravo");
- CU_ASSERT("alphabravo" == a);
+ assert_stdstring_equal("alphabravo", a);
}
}
diff --git a/src/template_test.h b/src/template_test.h
index 2c1448f..df39de9 100644
--- a/src/template_test.h
+++ b/src/template_test.h
@@ -29,10 +29,16 @@
# include <config.h>
#endif // HAVE_CONFIG_H
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
namespace nghttp2 {
-void test_template_immutable_string(void);
-void test_template_string_ref(void);
+extern const MunitSuite template_suite;
+
+munit_void_test_decl(test_template_immutable_string);
+munit_void_test_decl(test_template_string_ref);
} // namespace nghttp2
diff --git a/src/tls.cc b/src/tls.cc
index e88dc56..9babf2a 100644
--- a/src/tls.cc
+++ b/src/tls.cc
@@ -32,6 +32,11 @@
#include <openssl/crypto.h>
#include <openssl/conf.h>
+#ifdef HAVE_LIBBROTLI
+# include <brotli/encode.h>
+# include <brotli/decode.h>
+#endif // HAVE_LIBBROTLI
+
#include "ssl_compat.h"
namespace nghttp2 {
@@ -120,6 +125,57 @@ int ssl_ctx_set_proto_versions(SSL_CTX *ssl_ctx, int min, int max) {
return 0;
}
+#if defined(NGHTTP2_OPENSSL_IS_BORINGSSL) && defined(HAVE_LIBBROTLI)
+int cert_compress(SSL *ssl, CBB *out, const uint8_t *in, size_t in_len) {
+ uint8_t *dest;
+
+ auto compressed_size = BrotliEncoderMaxCompressedSize(in_len);
+ if (compressed_size == 0) {
+ return 0;
+ }
+
+ if (!CBB_reserve(out, &dest, compressed_size)) {
+ return 0;
+ }
+
+ if (BrotliEncoderCompress(BROTLI_MAX_QUALITY, BROTLI_DEFAULT_WINDOW,
+ BROTLI_MODE_GENERIC, in_len, in, &compressed_size,
+ dest) != BROTLI_TRUE) {
+ return 0;
+ }
+
+ if (!CBB_did_write(out, compressed_size)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+int cert_decompress(SSL *ssl, CRYPTO_BUFFER **out, size_t uncompressed_len,
+ const uint8_t *in, size_t in_len) {
+ uint8_t *dest;
+ auto buf = CRYPTO_BUFFER_alloc(&dest, uncompressed_len);
+ auto len = uncompressed_len;
+
+ if (BrotliDecoderDecompress(in_len, in, &len, dest) !=
+ BROTLI_DECODER_RESULT_SUCCESS) {
+ CRYPTO_BUFFER_free(buf);
+
+ return 0;
+ }
+
+ if (uncompressed_len != len) {
+ CRYPTO_BUFFER_free(buf);
+
+ return 0;
+ }
+
+ *out = buf;
+
+ return 1;
+}
+#endif // NGHTTP2_OPENSSL_IS_BORINGSSL && HAVE_LIBBROTLI
+
} // namespace tls
} // namespace nghttp2
diff --git a/src/tls.h b/src/tls.h
index 59e2ccd..03612c8 100644
--- a/src/tls.h
+++ b/src/tls.h
@@ -97,6 +97,15 @@ bool check_http2_requirement(SSL *ssl);
// 0 if it succeeds, or -1.
int ssl_ctx_set_proto_versions(SSL_CTX *ssl_ctx, int min, int max);
+constexpr uint16_t CERTIFICATE_COMPRESSION_ALGO_BROTLI = 2;
+
+#if defined(NGHTTP2_OPENSSL_IS_BORINGSSL) && defined(HAVE_LIBBROTLI)
+int cert_compress(SSL *ssl, CBB *out, const uint8_t *in, size_t in_len);
+
+int cert_decompress(SSL *ssl, CRYPTO_BUFFER **out, size_t uncompressed_len,
+ const uint8_t *in, size_t in_len);
+#endif // NGHTTP2_OPENSSL_IS_BORINGSSL && HAVE_LIBBROTLI
+
} // namespace tls
} // namespace nghttp2
diff --git a/src/util_test.cc b/src/util_test.cc
index 0ac0f1d..2e01e9d 100644
--- a/src/util_test.cc
+++ b/src/util_test.cc
@@ -28,7 +28,7 @@
#include <iostream>
#include <random>
-#include <CUnit/CUnit.h>
+#include "munitxx.h"
#include <nghttp2/nghttp2.h>
@@ -39,166 +39,233 @@ using namespace nghttp2;
namespace shrpx {
+namespace {
+const MunitTest tests[]{
+ munit_void_test(test_util_streq),
+ munit_void_test(test_util_strieq),
+ munit_void_test(test_util_inp_strlower),
+ munit_void_test(test_util_to_base64),
+ munit_void_test(test_util_to_token68),
+ munit_void_test(test_util_percent_encode_token),
+ munit_void_test(test_util_percent_decode),
+ munit_void_test(test_util_quote_string),
+ munit_void_test(test_util_utox),
+ munit_void_test(test_util_http_date),
+ munit_void_test(test_util_select_h2),
+ munit_void_test(test_util_ipv6_numeric_addr),
+ munit_void_test(test_util_utos),
+ munit_void_test(test_util_make_string_ref_uint),
+ munit_void_test(test_util_utos_unit),
+ munit_void_test(test_util_utos_funit),
+ munit_void_test(test_util_parse_uint_with_unit),
+ munit_void_test(test_util_parse_uint),
+ munit_void_test(test_util_parse_duration_with_unit),
+ munit_void_test(test_util_duration_str),
+ munit_void_test(test_util_format_duration),
+ munit_void_test(test_util_starts_with),
+ munit_void_test(test_util_ends_with),
+ munit_void_test(test_util_parse_http_date),
+ munit_void_test(test_util_localtime_date),
+ munit_void_test(test_util_get_uint64),
+ munit_void_test(test_util_parse_config_str_list),
+ munit_void_test(test_util_make_http_hostport),
+ munit_void_test(test_util_make_hostport),
+ munit_void_test(test_util_strifind),
+ munit_void_test(test_util_random_alpha_digit),
+ munit_void_test(test_util_format_hex),
+ munit_void_test(test_util_is_hex_string),
+ munit_void_test(test_util_decode_hex),
+ munit_void_test(test_util_extract_host),
+ munit_void_test(test_util_split_hostport),
+ munit_void_test(test_util_split_str),
+ munit_void_test(test_util_rstrip),
+ munit_test_end(),
+};
+} // namespace
+
+const MunitSuite util_suite{
+ "/util", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
+};
+
void test_util_streq(void) {
- CU_ASSERT(
+ assert_true(
util::streq(StringRef::from_lit("alpha"), StringRef::from_lit("alpha")));
- CU_ASSERT(!util::streq(StringRef::from_lit("alpha"),
- StringRef::from_lit("alphabravo")));
- CU_ASSERT(!util::streq(StringRef::from_lit("alphabravo"),
- StringRef::from_lit("alpha")));
- CU_ASSERT(
- !util::streq(StringRef::from_lit("alpha"), StringRef::from_lit("alphA")));
- CU_ASSERT(!util::streq(StringRef{}, StringRef::from_lit("a")));
- CU_ASSERT(util::streq(StringRef{}, StringRef{}));
- CU_ASSERT(!util::streq(StringRef::from_lit("alpha"), StringRef{}));
-
- CU_ASSERT(
- !util::streq(StringRef::from_lit("alph"), StringRef::from_lit("alpha")));
- CU_ASSERT(
- !util::streq(StringRef::from_lit("alpha"), StringRef::from_lit("alph")));
- CU_ASSERT(
- !util::streq(StringRef::from_lit("alpha"), StringRef::from_lit("alphA")));
-
- CU_ASSERT(util::streq_l("alpha", "alpha", 5));
- CU_ASSERT(util::streq_l("alpha", "alphabravo", 5));
- CU_ASSERT(!util::streq_l("alpha", "alphabravo", 6));
- CU_ASSERT(!util::streq_l("alphabravo", "alpha", 5));
- CU_ASSERT(!util::streq_l("alpha", "alphA", 5));
- CU_ASSERT(!util::streq_l("", "a", 1));
- CU_ASSERT(util::streq_l("", "", 0));
- CU_ASSERT(!util::streq_l("alpha", "", 0));
+ assert_false(util::streq(StringRef::from_lit("alpha"),
+ StringRef::from_lit("alphabravo")));
+ assert_false(util::streq(StringRef::from_lit("alphabravo"),
+ StringRef::from_lit("alpha")));
+ assert_false(
+ util::streq(StringRef::from_lit("alpha"), StringRef::from_lit("alphA")));
+ assert_false(util::streq(StringRef{}, StringRef::from_lit("a")));
+ assert_true(util::streq(StringRef{}, StringRef{}));
+ assert_false(util::streq(StringRef::from_lit("alpha"), StringRef{}));
+
+ assert_false(
+ util::streq(StringRef::from_lit("alph"), StringRef::from_lit("alpha")));
+ assert_false(
+ util::streq(StringRef::from_lit("alpha"), StringRef::from_lit("alph")));
+ assert_false(
+ util::streq(StringRef::from_lit("alpha"), StringRef::from_lit("alphA")));
+
+ assert_true(util::streq_l("alpha", "alpha", 5));
+ assert_true(util::streq_l("alpha", "alphabravo", 5));
+ assert_false(util::streq_l("alpha", "alphabravo", 6));
+ assert_false(util::streq_l("alphabravo", "alpha", 5));
+ assert_false(util::streq_l("alpha", "alphA", 5));
+ assert_false(util::streq_l("", "a", 1));
+ assert_true(util::streq_l("", "", 0));
+ assert_false(util::streq_l("alpha", "", 0));
}
void test_util_strieq(void) {
- CU_ASSERT(util::strieq(std::string("alpha"), std::string("alpha")));
- CU_ASSERT(util::strieq(std::string("alpha"), std::string("AlPhA")));
- CU_ASSERT(util::strieq(std::string(), std::string()));
- CU_ASSERT(!util::strieq(std::string("alpha"), std::string("AlPhA ")));
- CU_ASSERT(!util::strieq(std::string(), std::string("AlPhA ")));
+ assert_true(util::strieq(std::string("alpha"), std::string("alpha")));
+ assert_true(util::strieq(std::string("alpha"), std::string("AlPhA")));
+ assert_true(util::strieq(std::string(), std::string()));
+ assert_false(util::strieq(std::string("alpha"), std::string("AlPhA ")));
+ assert_false(util::strieq(std::string(), std::string("AlPhA ")));
- CU_ASSERT(
+ assert_true(
util::strieq(StringRef::from_lit("alpha"), StringRef::from_lit("alpha")));
- CU_ASSERT(
+ assert_true(
util::strieq(StringRef::from_lit("alpha"), StringRef::from_lit("AlPhA")));
- CU_ASSERT(util::strieq(StringRef{}, StringRef{}));
- CU_ASSERT(!util::strieq(StringRef::from_lit("alpha"),
- StringRef::from_lit("AlPhA ")));
- CU_ASSERT(
- !util::strieq(StringRef::from_lit(""), StringRef::from_lit("AlPhA ")));
+ assert_true(util::strieq(StringRef{}, StringRef{}));
+ assert_false(util::strieq(StringRef::from_lit("alpha"),
+ StringRef::from_lit("AlPhA ")));
+ assert_false(
+ util::strieq(StringRef::from_lit(""), StringRef::from_lit("AlPhA ")));
- CU_ASSERT(util::strieq_l("alpha", "alpha", 5));
- CU_ASSERT(util::strieq_l("alpha", "AlPhA", 5));
- CU_ASSERT(util::strieq_l("", static_cast<const char *>(nullptr), 0));
- CU_ASSERT(!util::strieq_l("alpha", "AlPhA ", 6));
- CU_ASSERT(!util::strieq_l("", "AlPhA ", 6));
+ assert_true(util::strieq_l("alpha", "alpha", 5));
+ assert_true(util::strieq_l("alpha", "AlPhA", 5));
+ assert_true(util::strieq_l("", static_cast<const char *>(nullptr), 0));
+ assert_false(util::strieq_l("alpha", "AlPhA ", 6));
+ assert_false(util::strieq_l("", "AlPhA ", 6));
- CU_ASSERT(util::strieq_l("alpha", StringRef::from_lit("alpha")));
- CU_ASSERT(util::strieq_l("alpha", StringRef::from_lit("AlPhA")));
- CU_ASSERT(util::strieq_l("", StringRef{}));
- CU_ASSERT(!util::strieq_l("alpha", StringRef::from_lit("AlPhA ")));
- CU_ASSERT(!util::strieq_l("", StringRef::from_lit("AlPhA ")));
+ assert_true(util::strieq_l("alpha", StringRef::from_lit("alpha")));
+ assert_true(util::strieq_l("alpha", StringRef::from_lit("AlPhA")));
+ assert_true(util::strieq_l("", StringRef{}));
+ assert_false(util::strieq_l("alpha", StringRef::from_lit("AlPhA ")));
+ assert_false(util::strieq_l("", StringRef::from_lit("AlPhA ")));
}
void test_util_inp_strlower(void) {
std::string a("alPha");
util::inp_strlower(a);
- CU_ASSERT("alpha" == a);
+ assert_stdstring_equal("alpha", a);
a = "ALPHA123BRAVO";
util::inp_strlower(a);
- CU_ASSERT("alpha123bravo" == a);
+ assert_stdstring_equal("alpha123bravo", a);
a = "";
util::inp_strlower(a);
- CU_ASSERT("" == a);
+ assert_stdstring_equal("", a);
}
void test_util_to_base64(void) {
BlockAllocator balloc(4096, 4096);
- CU_ASSERT("AAA++B/=" ==
- util::to_base64(balloc, StringRef::from_lit("AAA--B_")));
- CU_ASSERT("AAA++B/B" ==
- util::to_base64(balloc, StringRef::from_lit("AAA--B_B")));
+ assert_stdstring_equal(
+ "AAA++B/=",
+ util::to_base64(balloc, StringRef::from_lit("AAA--B_")).str());
+ assert_stdstring_equal(
+ "AAA++B/B",
+ util::to_base64(balloc, StringRef::from_lit("AAA--B_B")).str());
}
void test_util_to_token68(void) {
std::string x = "AAA++B/=";
util::to_token68(x);
- CU_ASSERT("AAA--B_" == x);
+ assert_stdstring_equal("AAA--B_", x);
x = "AAA++B/B";
util::to_token68(x);
- CU_ASSERT("AAA--B_B" == x);
+ assert_stdstring_equal("AAA--B_B", x);
}
void test_util_percent_encode_token(void) {
BlockAllocator balloc(4096, 4096);
- CU_ASSERT("h2" ==
- util::percent_encode_token(balloc, StringRef::from_lit("h2")));
- CU_ASSERT("h3~" ==
- util::percent_encode_token(balloc, StringRef::from_lit("h3~")));
- CU_ASSERT("100%25" ==
- util::percent_encode_token(balloc, StringRef::from_lit("100%")));
- CU_ASSERT("http%202" ==
- util::percent_encode_token(balloc, StringRef::from_lit("http 2")));
+ assert_stdstring_equal(
+ "h2",
+ util::percent_encode_token(balloc, StringRef::from_lit("h2")).str());
+ assert_stdstring_equal(
+ "h3~",
+ util::percent_encode_token(balloc, StringRef::from_lit("h3~")).str());
+ assert_stdstring_equal(
+ "100%25",
+ util::percent_encode_token(balloc, StringRef::from_lit("100%")).str());
+ assert_stdstring_equal(
+ "http%202",
+ util::percent_encode_token(balloc, StringRef::from_lit("http 2")).str());
}
void test_util_percent_decode(void) {
{
std::string s = "%66%6F%6f%62%61%72";
- CU_ASSERT("foobar" == util::percent_decode(std::begin(s), std::end(s)));
+ assert_stdstring_equal("foobar",
+ util::percent_decode(std::begin(s), std::end(s)));
}
{
std::string s = "%66%6";
- CU_ASSERT("f%6" == util::percent_decode(std::begin(s), std::end(s)));
+ assert_stdstring_equal("f%6",
+ util::percent_decode(std::begin(s), std::end(s)));
}
{
std::string s = "%66%";
- CU_ASSERT("f%" == util::percent_decode(std::begin(s), std::end(s)));
+ assert_stdstring_equal("f%",
+ util::percent_decode(std::begin(s), std::end(s)));
}
BlockAllocator balloc(1024, 1024);
- CU_ASSERT("foobar" == util::percent_decode(
- balloc, StringRef::from_lit("%66%6F%6f%62%61%72")));
+ assert_stdstring_equal(
+ "foobar",
+ util::percent_decode(balloc, StringRef::from_lit("%66%6F%6f%62%61%72"))
+ .str());
- CU_ASSERT("f%6" ==
- util::percent_decode(balloc, StringRef::from_lit("%66%6")));
+ assert_stdstring_equal(
+ "f%6", util::percent_decode(balloc, StringRef::from_lit("%66%6")).str());
- CU_ASSERT("f%" == util::percent_decode(balloc, StringRef::from_lit("%66%")));
+ assert_stdstring_equal(
+ "f%", util::percent_decode(balloc, StringRef::from_lit("%66%")).str());
}
void test_util_quote_string(void) {
BlockAllocator balloc(4096, 4096);
- CU_ASSERT("alpha" ==
- util::quote_string(balloc, StringRef::from_lit("alpha")));
- CU_ASSERT("" == util::quote_string(balloc, StringRef::from_lit("")));
- CU_ASSERT("\\\"alpha\\\"" ==
- util::quote_string(balloc, StringRef::from_lit("\"alpha\"")));
+ assert_stdstring_equal(
+ "alpha", util::quote_string(balloc, StringRef::from_lit("alpha")).str());
+ assert_stdstring_equal(
+ "", util::quote_string(balloc, StringRef::from_lit("")).str());
+ assert_stdstring_equal(
+ "\\\"alpha\\\"",
+ util::quote_string(balloc, StringRef::from_lit("\"alpha\"")).str());
}
void test_util_utox(void) {
- CU_ASSERT("0" == util::utox(0));
- CU_ASSERT("1" == util::utox(1));
- CU_ASSERT("F" == util::utox(15));
- CU_ASSERT("10" == util::utox(16));
- CU_ASSERT("3B9ACA07" == util::utox(1000000007));
- CU_ASSERT("100000000" == util::utox(1LL << 32));
+ assert_stdstring_equal("0", util::utox(0));
+ assert_stdstring_equal("1", util::utox(1));
+ assert_stdstring_equal("F", util::utox(15));
+ assert_stdstring_equal("10", util::utox(16));
+ assert_stdstring_equal("3B9ACA07", util::utox(1000000007));
+ assert_stdstring_equal("100000000", util::utox(1LL << 32));
}
void test_util_http_date(void) {
- CU_ASSERT("Thu, 01 Jan 1970 00:00:00 GMT" == util::http_date(0));
- CU_ASSERT("Wed, 29 Feb 2012 09:15:16 GMT" == util::http_date(1330506916));
+ assert_stdstring_equal("Thu, 01 Jan 1970 00:00:00 GMT", util::http_date(0));
+ assert_stdstring_equal("Wed, 29 Feb 2012 09:15:16 GMT",
+ util::http_date(1330506916));
std::array<char, 30> http_buf;
- CU_ASSERT("Thu, 01 Jan 1970 00:00:00 GMT" ==
- util::format_http_date(http_buf.data(),
- std::chrono::system_clock::time_point()));
- CU_ASSERT("Wed, 29 Feb 2012 09:15:16 GMT" ==
- util::format_http_date(http_buf.data(),
- std::chrono::system_clock::time_point(
- std::chrono::seconds(1330506916))));
+ assert_stdstring_equal(
+ "Thu, 01 Jan 1970 00:00:00 GMT",
+ util::format_http_date(http_buf.data(),
+ std::chrono::system_clock::time_point())
+ .str());
+ assert_stdstring_equal(
+ "Wed, 29 Feb 2012 09:15:16 GMT",
+ util::format_http_date(http_buf.data(),
+ std::chrono::system_clock::time_point(
+ std::chrono::seconds(1330506916)))
+ .str());
}
void test_util_select_h2(void) {
@@ -207,10 +274,10 @@ void test_util_select_h2(void) {
// Check single entry and select it.
const unsigned char t1[] = "\x2h2";
- CU_ASSERT(util::select_h2(&out, &outlen, t1, sizeof(t1) - 1));
- CU_ASSERT(
- memcmp(NGHTTP2_PROTO_VERSION_ID, out, NGHTTP2_PROTO_VERSION_ID_LEN) == 0);
- CU_ASSERT(NGHTTP2_PROTO_VERSION_ID_LEN == outlen);
+ assert_true(util::select_h2(&out, &outlen, t1, sizeof(t1) - 1));
+ assert_memory_equal(NGHTTP2_PROTO_VERSION_ID_LEN, NGHTTP2_PROTO_VERSION_ID,
+ out);
+ assert_uchar(NGHTTP2_PROTO_VERSION_ID_LEN, ==, outlen);
out = nullptr;
outlen = 0;
@@ -218,224 +285,235 @@ void test_util_select_h2(void) {
// Check the case where id is correct but length is invalid and too
// long.
const unsigned char t2[] = "\x6h2-14";
- CU_ASSERT(!util::select_h2(&out, &outlen, t2, sizeof(t2) - 1));
+ assert_false(util::select_h2(&out, &outlen, t2, sizeof(t2) - 1));
// Check the case where h2 is located after bogus ID.
const unsigned char t3[] = "\x2h3\x2h2";
- CU_ASSERT(util::select_h2(&out, &outlen, t3, sizeof(t3) - 1));
+ assert_true(util::select_h2(&out, &outlen, t3, sizeof(t3) - 1));
- CU_ASSERT(
- memcmp(NGHTTP2_PROTO_VERSION_ID, out, NGHTTP2_PROTO_VERSION_ID_LEN) == 0);
- CU_ASSERT(NGHTTP2_PROTO_VERSION_ID_LEN == outlen);
+ assert_memory_equal(NGHTTP2_PROTO_VERSION_ID_LEN, NGHTTP2_PROTO_VERSION_ID,
+ out);
+ assert_uchar(NGHTTP2_PROTO_VERSION_ID_LEN, ==, outlen);
out = nullptr;
outlen = 0;
// Check the case that last entry's length is invalid and too long.
const unsigned char t4[] = "\x2h3\x6h2-14";
- CU_ASSERT(!util::select_h2(&out, &outlen, t4, sizeof(t4) - 1));
+ assert_false(util::select_h2(&out, &outlen, t4, sizeof(t4) - 1));
// Check the case that all entries are not supported.
const unsigned char t5[] = "\x2h3\x2h4";
- CU_ASSERT(!util::select_h2(&out, &outlen, t5, sizeof(t5) - 1));
+ assert_false(util::select_h2(&out, &outlen, t5, sizeof(t5) - 1));
// Check the case where 2 values are eligible, but last one is
// picked up because it has precedence over the other.
const unsigned char t6[] = "\x5h2-14\x5h2-16";
- CU_ASSERT(util::select_h2(&out, &outlen, t6, sizeof(t6) - 1));
- CU_ASSERT(util::streq(NGHTTP2_H2_16, StringRef{out, outlen}));
+ assert_true(util::select_h2(&out, &outlen, t6, sizeof(t6) - 1));
+ assert_true(util::streq(NGHTTP2_H2_16, StringRef{out, outlen}));
}
void test_util_ipv6_numeric_addr(void) {
- CU_ASSERT(util::ipv6_numeric_addr("::1"));
- CU_ASSERT(util::ipv6_numeric_addr("2001:0db8:85a3:0042:1000:8a2e:0370:7334"));
+ assert_true(util::ipv6_numeric_addr("::1"));
+ assert_true(
+ util::ipv6_numeric_addr("2001:0db8:85a3:0042:1000:8a2e:0370:7334"));
// IPv4
- CU_ASSERT(!util::ipv6_numeric_addr("127.0.0.1"));
+ assert_false(util::ipv6_numeric_addr("127.0.0.1"));
// not numeric address
- CU_ASSERT(!util::ipv6_numeric_addr("localhost"));
+ assert_false(util::ipv6_numeric_addr("localhost"));
}
void test_util_utos(void) {
uint8_t buf[32];
- CU_ASSERT(("0" == StringRef{buf, util::utos(buf, 0)}));
- CU_ASSERT(("123" == StringRef{buf, util::utos(buf, 123)}));
- CU_ASSERT(("18446744073709551615" ==
- StringRef{buf, util::utos(buf, 18446744073709551615ULL)}));
+ assert_stdstring_equal("0", (std::string{buf, util::utos(buf, 0)}));
+ assert_stdstring_equal("123", (std::string{buf, util::utos(buf, 123)}));
+ assert_stdstring_equal(
+ "18446744073709551615",
+ (std::string{buf, util::utos(buf, 18446744073709551615ULL)}));
}
void test_util_make_string_ref_uint(void) {
BlockAllocator balloc(1024, 1024);
- CU_ASSERT("0" == util::make_string_ref_uint(balloc, 0));
- CU_ASSERT("123" == util::make_string_ref_uint(balloc, 123));
- CU_ASSERT("18446744073709551615" ==
- util::make_string_ref_uint(balloc, 18446744073709551615ULL));
+ assert_stdstring_equal("0", util::make_string_ref_uint(balloc, 0).str());
+ assert_stdstring_equal("123", util::make_string_ref_uint(balloc, 123).str());
+ assert_stdstring_equal(
+ "18446744073709551615",
+ util::make_string_ref_uint(balloc, 18446744073709551615ULL).str());
}
void test_util_utos_unit(void) {
- CU_ASSERT("0" == util::utos_unit(0));
- CU_ASSERT("1023" == util::utos_unit(1023));
- CU_ASSERT("1K" == util::utos_unit(1024));
- CU_ASSERT("1K" == util::utos_unit(1025));
- CU_ASSERT("1M" == util::utos_unit(1 << 20));
- CU_ASSERT("1G" == util::utos_unit(1 << 30));
- CU_ASSERT("1024G" == util::utos_unit(1LL << 40));
+ assert_stdstring_equal("0", util::utos_unit(0));
+ assert_stdstring_equal("1023", util::utos_unit(1023));
+ assert_stdstring_equal("1K", util::utos_unit(1024));
+ assert_stdstring_equal("1K", util::utos_unit(1025));
+ assert_stdstring_equal("1M", util::utos_unit(1 << 20));
+ assert_stdstring_equal("1G", util::utos_unit(1 << 30));
+ assert_stdstring_equal("1024G", util::utos_unit(1LL << 40));
}
void test_util_utos_funit(void) {
- CU_ASSERT("0" == util::utos_funit(0));
- CU_ASSERT("1023" == util::utos_funit(1023));
- CU_ASSERT("1.00K" == util::utos_funit(1024));
- CU_ASSERT("1.00K" == util::utos_funit(1025));
- CU_ASSERT("1.09K" == util::utos_funit(1119));
- CU_ASSERT("1.27K" == util::utos_funit(1300));
- CU_ASSERT("1.00M" == util::utos_funit(1 << 20));
- CU_ASSERT("1.18M" == util::utos_funit(1234567));
- CU_ASSERT("1.00G" == util::utos_funit(1 << 30));
- CU_ASSERT("4492450797.23G" == util::utos_funit(4823732313248234343LL));
- CU_ASSERT("1024.00G" == util::utos_funit(1LL << 40));
+ assert_stdstring_equal("0", util::utos_funit(0));
+ assert_stdstring_equal("1023", util::utos_funit(1023));
+ assert_stdstring_equal("1.00K", util::utos_funit(1024));
+ assert_stdstring_equal("1.00K", util::utos_funit(1025));
+ assert_stdstring_equal("1.09K", util::utos_funit(1119));
+ assert_stdstring_equal("1.27K", util::utos_funit(1300));
+ assert_stdstring_equal("1.00M", util::utos_funit(1 << 20));
+ assert_stdstring_equal("1.18M", util::utos_funit(1234567));
+ assert_stdstring_equal("1.00G", util::utos_funit(1 << 30));
+ assert_stdstring_equal("4492450797.23G",
+ util::utos_funit(4823732313248234343LL));
+ assert_stdstring_equal("1024.00G", util::utos_funit(1LL << 40));
}
void test_util_parse_uint_with_unit(void) {
- CU_ASSERT(0 == util::parse_uint_with_unit("0"));
- CU_ASSERT(1023 == util::parse_uint_with_unit("1023"));
- CU_ASSERT(1024 == util::parse_uint_with_unit("1k"));
- CU_ASSERT(2048 == util::parse_uint_with_unit("2K"));
- CU_ASSERT(1 << 20 == util::parse_uint_with_unit("1m"));
- CU_ASSERT(1 << 21 == util::parse_uint_with_unit("2M"));
- CU_ASSERT(1 << 30 == util::parse_uint_with_unit("1g"));
- CU_ASSERT(1LL << 31 == util::parse_uint_with_unit("2G"));
- CU_ASSERT(9223372036854775807LL ==
- util::parse_uint_with_unit("9223372036854775807"));
+ assert_int64(0, ==, util::parse_uint_with_unit("0"));
+ assert_int64(1023, ==, util::parse_uint_with_unit("1023"));
+ assert_int64(1024, ==, util::parse_uint_with_unit("1k"));
+ assert_int64(2048, ==, util::parse_uint_with_unit("2K"));
+ assert_int64(1 << 20, ==, util::parse_uint_with_unit("1m"));
+ assert_int64(1 << 21, ==, util::parse_uint_with_unit("2M"));
+ assert_int64(1 << 30, ==, util::parse_uint_with_unit("1g"));
+ assert_int64(1LL << 31, ==, util::parse_uint_with_unit("2G"));
+ assert_int64(9223372036854775807LL, ==,
+ util::parse_uint_with_unit("9223372036854775807"));
// check overflow case
- CU_ASSERT(-1 == util::parse_uint_with_unit("9223372036854775808"));
- CU_ASSERT(-1 == util::parse_uint_with_unit("10000000000000000000"));
- CU_ASSERT(-1 == util::parse_uint_with_unit("9223372036854775807G"));
+ assert_int64(-1, ==, util::parse_uint_with_unit("9223372036854775808"));
+ assert_int64(-1, ==, util::parse_uint_with_unit("10000000000000000000"));
+ assert_int64(-1, ==, util::parse_uint_with_unit("9223372036854775807G"));
// bad characters
- CU_ASSERT(-1 == util::parse_uint_with_unit("1.1"));
- CU_ASSERT(-1 == util::parse_uint_with_unit("1a"));
- CU_ASSERT(-1 == util::parse_uint_with_unit("a1"));
- CU_ASSERT(-1 == util::parse_uint_with_unit("1T"));
- CU_ASSERT(-1 == util::parse_uint_with_unit(""));
+ assert_int64(-1, ==, util::parse_uint_with_unit("1.1"));
+ assert_int64(-1, ==, util::parse_uint_with_unit("1a"));
+ assert_int64(-1, ==, util::parse_uint_with_unit("a1"));
+ assert_int64(-1, ==, util::parse_uint_with_unit("1T"));
+ assert_int64(-1, ==, util::parse_uint_with_unit(""));
}
void test_util_parse_uint(void) {
- CU_ASSERT(0 == util::parse_uint("0"));
- CU_ASSERT(1023 == util::parse_uint("1023"));
- CU_ASSERT(-1 == util::parse_uint("1k"));
- CU_ASSERT(9223372036854775807LL == util::parse_uint("9223372036854775807"));
+ assert_int64(0, ==, util::parse_uint("0"));
+ assert_int64(1023, ==, util::parse_uint("1023"));
+ assert_int64(-1, ==, util::parse_uint("1k"));
+ assert_int64(9223372036854775807LL, ==,
+ util::parse_uint("9223372036854775807"));
// check overflow case
- CU_ASSERT(-1 == util::parse_uint("9223372036854775808"));
- CU_ASSERT(-1 == util::parse_uint("10000000000000000000"));
+ assert_int64(-1, ==, util::parse_uint("9223372036854775808"));
+ assert_int64(-1, ==, util::parse_uint("10000000000000000000"));
// bad characters
- CU_ASSERT(-1 == util::parse_uint("1.1"));
- CU_ASSERT(-1 == util::parse_uint("1a"));
- CU_ASSERT(-1 == util::parse_uint("a1"));
- CU_ASSERT(-1 == util::parse_uint("1T"));
- CU_ASSERT(-1 == util::parse_uint(""));
+ assert_int64(-1, ==, util::parse_uint("1.1"));
+ assert_int64(-1, ==, util::parse_uint("1a"));
+ assert_int64(-1, ==, util::parse_uint("a1"));
+ assert_int64(-1, ==, util::parse_uint("1T"));
+ assert_int64(-1, ==, util::parse_uint(""));
}
void test_util_parse_duration_with_unit(void) {
- CU_ASSERT(0. == util::parse_duration_with_unit("0"));
- CU_ASSERT(123. == util::parse_duration_with_unit("123"));
- CU_ASSERT(123. == util::parse_duration_with_unit("123s"));
- CU_ASSERT(0.500 == util::parse_duration_with_unit("500ms"));
- CU_ASSERT(123. == util::parse_duration_with_unit("123S"));
- CU_ASSERT(0.500 == util::parse_duration_with_unit("500MS"));
- CU_ASSERT(180 == util::parse_duration_with_unit("3m"));
- CU_ASSERT(3600 * 5 == util::parse_duration_with_unit("5h"));
+ assert_double(0., ==, util::parse_duration_with_unit("0"));
+ assert_double(123., ==, util::parse_duration_with_unit("123"));
+ assert_double(123., ==, util::parse_duration_with_unit("123s"));
+ assert_double(0.500, ==, util::parse_duration_with_unit("500ms"));
+ assert_double(123., ==, util::parse_duration_with_unit("123S"));
+ assert_double(0.500, ==, util::parse_duration_with_unit("500MS"));
+ assert_double(180, ==, util::parse_duration_with_unit("3m"));
+ assert_double(3600 * 5, ==, util::parse_duration_with_unit("5h"));
auto err = std::numeric_limits<double>::infinity();
// check overflow case
- CU_ASSERT(err == util::parse_duration_with_unit("9223372036854775808"));
+ assert_double(err, ==, util::parse_duration_with_unit("9223372036854775808"));
// bad characters
- CU_ASSERT(err == util::parse_duration_with_unit("0u"));
- CU_ASSERT(err == util::parse_duration_with_unit("0xs"));
- CU_ASSERT(err == util::parse_duration_with_unit("0mt"));
- CU_ASSERT(err == util::parse_duration_with_unit("0mss"));
- CU_ASSERT(err == util::parse_duration_with_unit("s"));
- CU_ASSERT(err == util::parse_duration_with_unit("ms"));
+ assert_double(err, ==, util::parse_duration_with_unit("0u"));
+ assert_double(err, ==, util::parse_duration_with_unit("0xs"));
+ assert_double(err, ==, util::parse_duration_with_unit("0mt"));
+ assert_double(err, ==, util::parse_duration_with_unit("0mss"));
+ assert_double(err, ==, util::parse_duration_with_unit("s"));
+ assert_double(err, ==, util::parse_duration_with_unit("ms"));
}
void test_util_duration_str(void) {
- CU_ASSERT("0" == util::duration_str(0.));
- CU_ASSERT("1s" == util::duration_str(1.));
- CU_ASSERT("500ms" == util::duration_str(0.5));
- CU_ASSERT("1500ms" == util::duration_str(1.5));
- CU_ASSERT("2m" == util::duration_str(120.));
- CU_ASSERT("121s" == util::duration_str(121.));
- CU_ASSERT("1h" == util::duration_str(3600.));
+ assert_stdstring_equal("0", util::duration_str(0.));
+ assert_stdstring_equal("1s", util::duration_str(1.));
+ assert_stdstring_equal("500ms", util::duration_str(0.5));
+ assert_stdstring_equal("1500ms", util::duration_str(1.5));
+ assert_stdstring_equal("2m", util::duration_str(120.));
+ assert_stdstring_equal("121s", util::duration_str(121.));
+ assert_stdstring_equal("1h", util::duration_str(3600.));
}
void test_util_format_duration(void) {
- CU_ASSERT("0us" == util::format_duration(std::chrono::microseconds(0)));
- CU_ASSERT("999us" == util::format_duration(std::chrono::microseconds(999)));
- CU_ASSERT("1.00ms" == util::format_duration(std::chrono::microseconds(1000)));
- CU_ASSERT("1.09ms" == util::format_duration(std::chrono::microseconds(1090)));
- CU_ASSERT("1.01ms" == util::format_duration(std::chrono::microseconds(1009)));
- CU_ASSERT("999.99ms" ==
- util::format_duration(std::chrono::microseconds(999990)));
- CU_ASSERT("1.00s" ==
- util::format_duration(std::chrono::microseconds(1000000)));
- CU_ASSERT("1.05s" ==
- util::format_duration(std::chrono::microseconds(1050000)));
-
- CU_ASSERT("0us" == util::format_duration(0.));
- CU_ASSERT("999us" == util::format_duration(0.000999));
- CU_ASSERT("1.00ms" == util::format_duration(0.001));
- CU_ASSERT("1.09ms" == util::format_duration(0.00109));
- CU_ASSERT("1.01ms" == util::format_duration(0.001009));
- CU_ASSERT("999.99ms" == util::format_duration(0.99999));
- CU_ASSERT("1.00s" == util::format_duration(1.));
- CU_ASSERT("1.05s" == util::format_duration(1.05));
+ assert_stdstring_equal("0us",
+ util::format_duration(std::chrono::microseconds(0)));
+ assert_stdstring_equal("999us",
+ util::format_duration(std::chrono::microseconds(999)));
+ assert_stdstring_equal(
+ "1.00ms", util::format_duration(std::chrono::microseconds(1000)));
+ assert_stdstring_equal(
+ "1.09ms", util::format_duration(std::chrono::microseconds(1090)));
+ assert_stdstring_equal(
+ "1.01ms", util::format_duration(std::chrono::microseconds(1009)));
+ assert_stdstring_equal(
+ "999.99ms", util::format_duration(std::chrono::microseconds(999990)));
+ assert_stdstring_equal(
+ "1.00s", util::format_duration(std::chrono::microseconds(1000000)));
+ assert_stdstring_equal(
+ "1.05s", util::format_duration(std::chrono::microseconds(1050000)));
+
+ assert_stdstring_equal("0us", util::format_duration(0.));
+ assert_stdstring_equal("999us", util::format_duration(0.000999));
+ assert_stdstring_equal("1.00ms", util::format_duration(0.001));
+ assert_stdstring_equal("1.09ms", util::format_duration(0.00109));
+ assert_stdstring_equal("1.01ms", util::format_duration(0.001009));
+ assert_stdstring_equal("999.99ms", util::format_duration(0.99999));
+ assert_stdstring_equal("1.00s", util::format_duration(1.));
+ assert_stdstring_equal("1.05s", util::format_duration(1.05));
}
void test_util_starts_with(void) {
- CU_ASSERT(util::starts_with(StringRef::from_lit("foo"),
- StringRef::from_lit("foo")));
- CU_ASSERT(util::starts_with(StringRef::from_lit("fooo"),
- StringRef::from_lit("foo")));
- CU_ASSERT(util::starts_with(StringRef::from_lit("ofoo"), StringRef{}));
- CU_ASSERT(!util::starts_with(StringRef::from_lit("ofoo"),
- StringRef::from_lit("foo")));
-
- CU_ASSERT(util::istarts_with(StringRef::from_lit("FOO"),
- StringRef::from_lit("fOO")));
- CU_ASSERT(util::istarts_with(StringRef::from_lit("ofoo"), StringRef{}));
- CU_ASSERT(util::istarts_with(StringRef::from_lit("fOOo"),
- StringRef::from_lit("Foo")));
- CU_ASSERT(!util::istarts_with(StringRef::from_lit("ofoo"),
+ assert_true(util::starts_with(StringRef::from_lit("foo"),
+ StringRef::from_lit("foo")));
+ assert_true(util::starts_with(StringRef::from_lit("fooo"),
StringRef::from_lit("foo")));
+ assert_true(util::starts_with(StringRef::from_lit("ofoo"), StringRef{}));
+ assert_false(util::starts_with(StringRef::from_lit("ofoo"),
+ StringRef::from_lit("foo")));
- CU_ASSERT(util::istarts_with_l(StringRef::from_lit("fOOo"), "Foo"));
- CU_ASSERT(!util::istarts_with_l(StringRef::from_lit("ofoo"), "foo"));
+ assert_true(util::istarts_with(StringRef::from_lit("FOO"),
+ StringRef::from_lit("fOO")));
+ assert_true(util::istarts_with(StringRef::from_lit("ofoo"), StringRef{}));
+ assert_true(util::istarts_with(StringRef::from_lit("fOOo"),
+ StringRef::from_lit("Foo")));
+ assert_false(util::istarts_with(StringRef::from_lit("ofoo"),
+ StringRef::from_lit("foo")));
+
+ assert_true(util::istarts_with_l(StringRef::from_lit("fOOo"), "Foo"));
+ assert_false(util::istarts_with_l(StringRef::from_lit("ofoo"), "foo"));
}
void test_util_ends_with(void) {
- CU_ASSERT(
+ assert_true(
util::ends_with(StringRef::from_lit("foo"), StringRef::from_lit("foo")));
- CU_ASSERT(util::ends_with(StringRef::from_lit("foo"), StringRef{}));
- CU_ASSERT(
+ assert_true(util::ends_with(StringRef::from_lit("foo"), StringRef{}));
+ assert_true(
util::ends_with(StringRef::from_lit("ofoo"), StringRef::from_lit("foo")));
- CU_ASSERT(
- !util::ends_with(StringRef::from_lit("ofoo"), StringRef::from_lit("fo")));
+ assert_false(
+ util::ends_with(StringRef::from_lit("ofoo"), StringRef::from_lit("fo")));
- CU_ASSERT(
+ assert_true(
util::iends_with(StringRef::from_lit("fOo"), StringRef::from_lit("Foo")));
- CU_ASSERT(util::iends_with(StringRef::from_lit("foo"), StringRef{}));
- CU_ASSERT(util::iends_with(StringRef::from_lit("oFoo"),
- StringRef::from_lit("fOO")));
- CU_ASSERT(!util::iends_with(StringRef::from_lit("ofoo"),
- StringRef::from_lit("fo")));
+ assert_true(util::iends_with(StringRef::from_lit("foo"), StringRef{}));
+ assert_true(util::iends_with(StringRef::from_lit("oFoo"),
+ StringRef::from_lit("fOO")));
+ assert_false(
+ util::iends_with(StringRef::from_lit("ofoo"), StringRef::from_lit("fo")));
- CU_ASSERT(util::iends_with_l(StringRef::from_lit("oFoo"), "fOO"));
- CU_ASSERT(!util::iends_with_l(StringRef::from_lit("ofoo"), "fo"));
+ assert_true(util::iends_with_l(StringRef::from_lit("oFoo"), "fOO"));
+ assert_false(util::iends_with_l(StringRef::from_lit("ofoo"), "fo"));
}
void test_util_parse_http_date(void) {
- CU_ASSERT(1001939696 == util::parse_http_date(StringRef::from_lit(
- "Mon, 1 Oct 2001 12:34:56 GMT")));
+ assert_int64(1001939696, ==,
+ util::parse_http_date(
+ StringRef::from_lit("Mon, 1 Oct 2001 12:34:56 GMT")));
}
void test_util_localtime_date(void) {
@@ -450,25 +528,28 @@ void test_util_localtime_date(void) {
#endif // !__linux__
tzset();
- CU_ASSERT_STRING_EQUAL("02/Oct/2001:00:34:56 +1200",
- util::common_log_date(1001939696).c_str());
- CU_ASSERT_STRING_EQUAL("2001-10-02T00:34:56.123+12:00",
- util::iso8601_date(1001939696000LL + 123).c_str());
+ assert_stdstring_equal("02/Oct/2001:00:34:56 +1200",
+ util::common_log_date(1001939696));
+ assert_stdstring_equal("2001-10-02T00:34:56.123+12:00",
+ util::iso8601_date(1001939696000LL + 123));
std::array<char, 27> common_buf;
- CU_ASSERT("02/Oct/2001:00:34:56 +1200" ==
- util::format_common_log(common_buf.data(),
- std::chrono::system_clock::time_point(
- std::chrono::seconds(1001939696))));
+ assert_stdstring_equal(
+ "02/Oct/2001:00:34:56 +1200",
+ util::format_common_log(common_buf.data(),
+ std::chrono::system_clock::time_point(
+ std::chrono::seconds(1001939696)))
+ .str());
std::array<char, 30> iso8601_buf;
- CU_ASSERT(
- "2001-10-02T00:34:56.123+12:00" ==
+ assert_stdstring_equal(
+ "2001-10-02T00:34:56.123+12:00",
util::format_iso8601(iso8601_buf.data(),
std::chrono::system_clock::time_point(
- std::chrono::milliseconds(1001939696123LL))));
+ std::chrono::milliseconds(1001939696123LL)))
+ .str());
if (tz) {
setenv("TZ", tz, 1);
@@ -486,7 +567,7 @@ void test_util_get_uint64(void) {
auto n = util::get_uint64(v.data());
- CU_ASSERT(0x01123456ff9aabbcULL == n);
+ assert_uint64(0x01123456ff9aabbcULL, ==, n);
}
{
auto v = std::array<unsigned char, 8>{
@@ -494,83 +575,91 @@ void test_util_get_uint64(void) {
auto n = util::get_uint64(v.data());
- CU_ASSERT(0xffffffffffffffffULL == n);
+ assert_uint64(0xffffffffffffffffULL, ==, n);
}
}
void test_util_parse_config_str_list(void) {
auto res = util::parse_config_str_list(StringRef::from_lit("a"));
- CU_ASSERT(1 == res.size());
- CU_ASSERT("a" == res[0]);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("a", res[0]);
res = util::parse_config_str_list(StringRef::from_lit("a,"));
- CU_ASSERT(2 == res.size());
- CU_ASSERT("a" == res[0]);
- CU_ASSERT("" == res[1]);
+ assert_size(2, ==, res.size());
+ assert_stdstring_equal("a", res[0]);
+ assert_stdstring_equal("", res[1]);
res = util::parse_config_str_list(StringRef::from_lit(":a::"), ':');
- CU_ASSERT(4 == res.size());
- CU_ASSERT("" == res[0]);
- CU_ASSERT("a" == res[1]);
- CU_ASSERT("" == res[2]);
- CU_ASSERT("" == res[3]);
+ assert_size(4, ==, res.size());
+ assert_stdstring_equal("", res[0]);
+ assert_stdstring_equal("a", res[1]);
+ assert_stdstring_equal("", res[2]);
+ assert_stdstring_equal("", res[3]);
res = util::parse_config_str_list(StringRef{});
- CU_ASSERT(1 == res.size());
- CU_ASSERT("" == res[0]);
+ assert_size(1, ==, res.size());
+ assert_stdstring_equal("", res[0]);
res = util::parse_config_str_list(StringRef::from_lit("alpha,bravo,charlie"));
- CU_ASSERT(3 == res.size());
- CU_ASSERT("alpha" == res[0]);
- CU_ASSERT("bravo" == res[1]);
- CU_ASSERT("charlie" == res[2]);
+ assert_size(3, ==, res.size());
+ assert_stdstring_equal("alpha", res[0]);
+ assert_stdstring_equal("bravo", res[1]);
+ assert_stdstring_equal("charlie", res[2]);
}
void test_util_make_http_hostport(void) {
BlockAllocator balloc(4096, 4096);
- CU_ASSERT("localhost" == util::make_http_hostport(
- balloc, StringRef::from_lit("localhost"), 80));
- CU_ASSERT("[::1]" ==
- util::make_http_hostport(balloc, StringRef::from_lit("::1"), 443));
- CU_ASSERT(
- "localhost:3000" ==
- util::make_http_hostport(balloc, StringRef::from_lit("localhost"), 3000));
+ assert_stdstring_equal(
+ "localhost",
+ util::make_http_hostport(balloc, StringRef::from_lit("localhost"), 80)
+ .str());
+ assert_stdstring_equal(
+ "[::1]",
+ util::make_http_hostport(balloc, StringRef::from_lit("::1"), 443).str());
+ assert_stdstring_equal(
+ "localhost:3000",
+ util::make_http_hostport(balloc, StringRef::from_lit("localhost"), 3000)
+ .str());
}
void test_util_make_hostport(void) {
std::array<char, util::max_hostport> hostport_buf;
- CU_ASSERT("localhost:80" ==
- util::make_hostport(std::begin(hostport_buf),
- StringRef::from_lit("localhost"), 80));
- CU_ASSERT("[::1]:443" == util::make_hostport(std::begin(hostport_buf),
- StringRef::from_lit("::1"),
- 443));
+ assert_stdstring_equal(
+ "localhost:80", util::make_hostport(std::begin(hostport_buf),
+ StringRef::from_lit("localhost"), 80)
+ .str());
+ assert_stdstring_equal("[::1]:443",
+ util::make_hostport(std::begin(hostport_buf),
+ StringRef::from_lit("::1"), 443)
+ .str());
BlockAllocator balloc(4096, 4096);
- CU_ASSERT("localhost:80" ==
- util::make_hostport(balloc, StringRef::from_lit("localhost"), 80));
- CU_ASSERT("[::1]:443" ==
- util::make_hostport(balloc, StringRef::from_lit("::1"), 443));
+ assert_stdstring_equal(
+ "localhost:80",
+ util::make_hostport(balloc, StringRef::from_lit("localhost"), 80).str());
+ assert_stdstring_equal(
+ "[::1]:443",
+ util::make_hostport(balloc, StringRef::from_lit("::1"), 443).str());
}
void test_util_strifind(void) {
- CU_ASSERT(util::strifind(StringRef::from_lit("gzip, deflate, bzip2"),
- StringRef::from_lit("gzip")));
+ assert_true(util::strifind(StringRef::from_lit("gzip, deflate, bzip2"),
+ StringRef::from_lit("gzip")));
- CU_ASSERT(util::strifind(StringRef::from_lit("gzip, deflate, bzip2"),
- StringRef::from_lit("dEflate")));
+ assert_true(util::strifind(StringRef::from_lit("gzip, deflate, bzip2"),
+ StringRef::from_lit("dEflate")));
- CU_ASSERT(util::strifind(StringRef::from_lit("gzip, deflate, bzip2"),
- StringRef::from_lit("BZIP2")));
+ assert_true(util::strifind(StringRef::from_lit("gzip, deflate, bzip2"),
+ StringRef::from_lit("BZIP2")));
- CU_ASSERT(util::strifind(StringRef::from_lit("nghttp2"), StringRef{}));
+ assert_true(util::strifind(StringRef::from_lit("nghttp2"), StringRef{}));
// Be aware this fact
- CU_ASSERT(!util::strifind(StringRef{}, StringRef{}));
+ assert_false(util::strifind(StringRef{}, StringRef{}));
- CU_ASSERT(!util::strifind(StringRef::from_lit("nghttp2"),
- StringRef::from_lit("http1")));
+ assert_false(util::strifind(StringRef::from_lit("nghttp2"),
+ StringRef::from_lit("http1")));
}
void test_util_random_alpha_digit(void) {
@@ -580,116 +669,117 @@ void test_util_random_alpha_digit(void) {
auto p = util::random_alpha_digit(std::begin(data), std::end(data), gen);
- CU_ASSERT(std::end(data) == p);
+ assert_true(std::end(data) == p);
for (auto b : data) {
- CU_ASSERT(('A' <= b && b <= 'Z') || ('a' <= b && b <= 'z') ||
- ('0' <= b && b <= '9'));
+ assert_true(('A' <= b && b <= 'Z') || ('a' <= b && b <= 'z') ||
+ ('0' <= b && b <= '9'));
}
}
void test_util_format_hex(void) {
BlockAllocator balloc(4096, 4096);
- CU_ASSERT("0ff0" ==
- util::format_hex(balloc, StringRef::from_lit("\x0f\xf0")));
- CU_ASSERT("" == util::format_hex(balloc, StringRef::from_lit("")));
+ assert_stdstring_equal(
+ "0ff0", util::format_hex(balloc, StringRef::from_lit("\x0f\xf0")).str());
+ assert_stdstring_equal(
+ "", util::format_hex(balloc, StringRef::from_lit("")).str());
}
void test_util_is_hex_string(void) {
- CU_ASSERT(util::is_hex_string(StringRef{}));
- CU_ASSERT(util::is_hex_string(StringRef::from_lit("0123456789abcdef")));
- CU_ASSERT(util::is_hex_string(StringRef::from_lit("0123456789ABCDEF")));
- CU_ASSERT(!util::is_hex_string(StringRef::from_lit("000")));
- CU_ASSERT(!util::is_hex_string(StringRef::from_lit("XX")));
+ assert_true(util::is_hex_string(StringRef{}));
+ assert_true(util::is_hex_string(StringRef::from_lit("0123456789abcdef")));
+ assert_true(util::is_hex_string(StringRef::from_lit("0123456789ABCDEF")));
+ assert_false(util::is_hex_string(StringRef::from_lit("000")));
+ assert_false(util::is_hex_string(StringRef::from_lit("XX")));
}
void test_util_decode_hex(void) {
BlockAllocator balloc(4096, 4096);
- CU_ASSERT("\x0f\xf0" ==
- util::decode_hex(balloc, StringRef::from_lit("0ff0")));
- CU_ASSERT("" == util::decode_hex(balloc, StringRef{}));
+ assert_stdstring_equal(
+ "\x0f\xf0", util::decode_hex(balloc, StringRef::from_lit("0ff0")).str());
+ assert_stdstring_equal("", util::decode_hex(balloc, StringRef{}).str());
}
void test_util_extract_host(void) {
- CU_ASSERT(StringRef::from_lit("foo") ==
- util::extract_host(StringRef::from_lit("foo")));
- CU_ASSERT(StringRef::from_lit("foo") ==
- util::extract_host(StringRef::from_lit("foo:")));
- CU_ASSERT(StringRef::from_lit("foo") ==
- util::extract_host(StringRef::from_lit("foo:0")));
- CU_ASSERT(StringRef::from_lit("[::1]") ==
- util::extract_host(StringRef::from_lit("[::1]")));
- CU_ASSERT(StringRef::from_lit("[::1]") ==
- util::extract_host(StringRef::from_lit("[::1]:")));
-
- CU_ASSERT(util::extract_host(StringRef::from_lit(":foo")).empty());
- CU_ASSERT(util::extract_host(StringRef::from_lit("[::1")).empty());
- CU_ASSERT(util::extract_host(StringRef::from_lit("[::1]0")).empty());
- CU_ASSERT(util::extract_host(StringRef{}).empty());
+ assert_stdstring_equal("foo",
+ util::extract_host(StringRef::from_lit("foo")).str());
+ assert_stdstring_equal("foo",
+ util::extract_host(StringRef::from_lit("foo:")).str());
+ assert_stdstring_equal(
+ "foo", util::extract_host(StringRef::from_lit("foo:0")).str());
+ assert_stdstring_equal(
+ "[::1]", util::extract_host(StringRef::from_lit("[::1]")).str());
+ assert_stdstring_equal(
+ "[::1]", util::extract_host(StringRef::from_lit("[::1]:")).str());
+
+ assert_true(util::extract_host(StringRef::from_lit(":foo")).empty());
+ assert_true(util::extract_host(StringRef::from_lit("[::1")).empty());
+ assert_true(util::extract_host(StringRef::from_lit("[::1]0")).empty());
+ assert_true(util::extract_host(StringRef{}).empty());
}
void test_util_split_hostport(void) {
- CU_ASSERT(std::make_pair(StringRef::from_lit("foo"), StringRef{}) ==
- util::split_hostport(StringRef::from_lit("foo")));
- CU_ASSERT(
+ assert_true(std::make_pair(StringRef::from_lit("foo"), StringRef{}) ==
+ util::split_hostport(StringRef::from_lit("foo")));
+ assert_true(
std::make_pair(StringRef::from_lit("foo"), StringRef::from_lit("80")) ==
util::split_hostport(StringRef::from_lit("foo:80")));
- CU_ASSERT(
+ assert_true(
std::make_pair(StringRef::from_lit("::1"), StringRef::from_lit("80")) ==
util::split_hostport(StringRef::from_lit("[::1]:80")));
- CU_ASSERT(std::make_pair(StringRef::from_lit("::1"), StringRef{}) ==
- util::split_hostport(StringRef::from_lit("[::1]")));
+ assert_true(std::make_pair(StringRef::from_lit("::1"), StringRef{}) ==
+ util::split_hostport(StringRef::from_lit("[::1]")));
- CU_ASSERT(std::make_pair(StringRef{}, StringRef{}) ==
- util::split_hostport(StringRef{}));
- CU_ASSERT(std::make_pair(StringRef{}, StringRef{}) ==
- util::split_hostport(StringRef::from_lit("[::1]:")));
- CU_ASSERT(std::make_pair(StringRef{}, StringRef{}) ==
- util::split_hostport(StringRef::from_lit("foo:")));
- CU_ASSERT(std::make_pair(StringRef{}, StringRef{}) ==
- util::split_hostport(StringRef::from_lit("[::1:")));
- CU_ASSERT(std::make_pair(StringRef{}, StringRef{}) ==
- util::split_hostport(StringRef::from_lit("[::1]80")));
+ assert_true(std::make_pair(StringRef{}, StringRef{}) ==
+ util::split_hostport(StringRef{}));
+ assert_true(std::make_pair(StringRef{}, StringRef{}) ==
+ util::split_hostport(StringRef::from_lit("[::1]:")));
+ assert_true(std::make_pair(StringRef{}, StringRef{}) ==
+ util::split_hostport(StringRef::from_lit("foo:")));
+ assert_true(std::make_pair(StringRef{}, StringRef{}) ==
+ util::split_hostport(StringRef::from_lit("[::1:")));
+ assert_true(std::make_pair(StringRef{}, StringRef{}) ==
+ util::split_hostport(StringRef::from_lit("[::1]80")));
}
void test_util_split_str(void) {
- CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("")} ==
- util::split_str(StringRef::from_lit(""), ','));
- CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("alpha")} ==
- util::split_str(StringRef::from_lit("alpha"), ','));
- CU_ASSERT((std::vector<StringRef>{StringRef::from_lit("alpha"),
- StringRef::from_lit("")}) ==
- util::split_str(StringRef::from_lit("alpha,"), ','));
- CU_ASSERT((std::vector<StringRef>{StringRef::from_lit("alpha"),
- StringRef::from_lit("bravo")}) ==
- util::split_str(StringRef::from_lit("alpha,bravo"), ','));
- CU_ASSERT((std::vector<StringRef>{StringRef::from_lit("alpha"),
- StringRef::from_lit("bravo"),
- StringRef::from_lit("charlie")}) ==
- util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ','));
- CU_ASSERT(
+ assert_true(std::vector<StringRef>{StringRef::from_lit("")} ==
+ util::split_str(StringRef::from_lit(""), ','));
+ assert_true(std::vector<StringRef>{StringRef::from_lit("alpha")} ==
+ util::split_str(StringRef::from_lit("alpha"), ','));
+ assert_true((std::vector<StringRef>{StringRef::from_lit("alpha"),
+ StringRef::from_lit("")}) ==
+ util::split_str(StringRef::from_lit("alpha,"), ','));
+ assert_true((std::vector<StringRef>{StringRef::from_lit("alpha"),
+ StringRef::from_lit("bravo")}) ==
+ util::split_str(StringRef::from_lit("alpha,bravo"), ','));
+ assert_true((std::vector<StringRef>{StringRef::from_lit("alpha"),
+ StringRef::from_lit("bravo"),
+ StringRef::from_lit("charlie")}) ==
+ util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ','));
+ assert_true(
(std::vector<StringRef>{StringRef::from_lit("alpha"),
StringRef::from_lit("bravo"),
StringRef::from_lit("charlie")}) ==
util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ',', 0));
- CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("")} ==
- util::split_str(StringRef::from_lit(""), ',', 1));
- CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("")} ==
- util::split_str(StringRef::from_lit(""), ',', 2));
- CU_ASSERT(
+ assert_true(std::vector<StringRef>{StringRef::from_lit("")} ==
+ util::split_str(StringRef::from_lit(""), ',', 1));
+ assert_true(std::vector<StringRef>{StringRef::from_lit("")} ==
+ util::split_str(StringRef::from_lit(""), ',', 2));
+ assert_true(
(std::vector<StringRef>{StringRef::from_lit("alpha"),
StringRef::from_lit("bravo,charlie")}) ==
util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ',', 2));
- CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("alpha")} ==
- util::split_str(StringRef::from_lit("alpha"), ',', 2));
- CU_ASSERT((std::vector<StringRef>{StringRef::from_lit("alpha"),
- StringRef::from_lit("")}) ==
- util::split_str(StringRef::from_lit("alpha,"), ',', 2));
- CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("alpha")} ==
- util::split_str(StringRef::from_lit("alpha"), ',', 0));
- CU_ASSERT(
+ assert_true(std::vector<StringRef>{StringRef::from_lit("alpha")} ==
+ util::split_str(StringRef::from_lit("alpha"), ',', 2));
+ assert_true((std::vector<StringRef>{StringRef::from_lit("alpha"),
+ StringRef::from_lit("")}) ==
+ util::split_str(StringRef::from_lit("alpha,"), ',', 2));
+ assert_true(std::vector<StringRef>{StringRef::from_lit("alpha")} ==
+ util::split_str(StringRef::from_lit("alpha"), ',', 0));
+ assert_true(
std::vector<StringRef>{StringRef::from_lit("alpha,bravo,charlie")} ==
util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ',', 1));
}
@@ -697,11 +787,16 @@ void test_util_split_str(void) {
void test_util_rstrip(void) {
BlockAllocator balloc(4096, 4096);
- CU_ASSERT("alpha" == util::rstrip(balloc, StringRef::from_lit("alpha")));
- CU_ASSERT("alpha" == util::rstrip(balloc, StringRef::from_lit("alpha ")));
- CU_ASSERT("alpha" == util::rstrip(balloc, StringRef::from_lit("alpha \t")));
- CU_ASSERT("" == util::rstrip(balloc, StringRef::from_lit("")));
- CU_ASSERT("" == util::rstrip(balloc, StringRef::from_lit("\t\t\t ")));
+ assert_stdstring_equal(
+ "alpha", util::rstrip(balloc, StringRef::from_lit("alpha")).str());
+ assert_stdstring_equal(
+ "alpha", util::rstrip(balloc, StringRef::from_lit("alpha ")).str());
+ assert_stdstring_equal(
+ "alpha", util::rstrip(balloc, StringRef::from_lit("alpha \t")).str());
+ assert_stdstring_equal("",
+ util::rstrip(balloc, StringRef::from_lit("")).str());
+ assert_stdstring_equal(
+ "", util::rstrip(balloc, StringRef::from_lit("\t\t\t ")).str());
}
} // namespace shrpx
diff --git a/src/util_test.h b/src/util_test.h
index 48925ab..8b9608b 100644
--- a/src/util_test.h
+++ b/src/util_test.h
@@ -29,46 +29,52 @@
# include <config.h>
#endif // HAVE_CONFIG_H
+#define MUNIT_ENABLE_ASSERT_ALIASES
+
+#include "munit.h"
+
namespace shrpx {
-void test_util_streq(void);
-void test_util_strieq(void);
-void test_util_inp_strlower(void);
-void test_util_to_base64(void);
-void test_util_to_token68(void);
-void test_util_percent_encode_token(void);
-void test_util_percent_decode(void);
-void test_util_quote_string(void);
-void test_util_utox(void);
-void test_util_http_date(void);
-void test_util_select_h2(void);
-void test_util_ipv6_numeric_addr(void);
-void test_util_utos(void);
-void test_util_make_string_ref_uint(void);
-void test_util_utos_unit(void);
-void test_util_utos_funit(void);
-void test_util_parse_uint_with_unit(void);
-void test_util_parse_uint(void);
-void test_util_parse_duration_with_unit(void);
-void test_util_duration_str(void);
-void test_util_format_duration(void);
-void test_util_starts_with(void);
-void test_util_ends_with(void);
-void test_util_parse_http_date(void);
-void test_util_localtime_date(void);
-void test_util_get_uint64(void);
-void test_util_parse_config_str_list(void);
-void test_util_make_http_hostport(void);
-void test_util_make_hostport(void);
-void test_util_strifind(void);
-void test_util_random_alpha_digit(void);
-void test_util_format_hex(void);
-void test_util_is_hex_string(void);
-void test_util_decode_hex(void);
-void test_util_extract_host(void);
-void test_util_split_hostport(void);
-void test_util_split_str(void);
-void test_util_rstrip(void);
+extern const MunitSuite util_suite;
+
+munit_void_test_decl(test_util_streq);
+munit_void_test_decl(test_util_strieq);
+munit_void_test_decl(test_util_inp_strlower);
+munit_void_test_decl(test_util_to_base64);
+munit_void_test_decl(test_util_to_token68);
+munit_void_test_decl(test_util_percent_encode_token);
+munit_void_test_decl(test_util_percent_decode);
+munit_void_test_decl(test_util_quote_string);
+munit_void_test_decl(test_util_utox);
+munit_void_test_decl(test_util_http_date);
+munit_void_test_decl(test_util_select_h2);
+munit_void_test_decl(test_util_ipv6_numeric_addr);
+munit_void_test_decl(test_util_utos);
+munit_void_test_decl(test_util_make_string_ref_uint);
+munit_void_test_decl(test_util_utos_unit);
+munit_void_test_decl(test_util_utos_funit);
+munit_void_test_decl(test_util_parse_uint_with_unit);
+munit_void_test_decl(test_util_parse_uint);
+munit_void_test_decl(test_util_parse_duration_with_unit);
+munit_void_test_decl(test_util_duration_str);
+munit_void_test_decl(test_util_format_duration);
+munit_void_test_decl(test_util_starts_with);
+munit_void_test_decl(test_util_ends_with);
+munit_void_test_decl(test_util_parse_http_date);
+munit_void_test_decl(test_util_localtime_date);
+munit_void_test_decl(test_util_get_uint64);
+munit_void_test_decl(test_util_parse_config_str_list);
+munit_void_test_decl(test_util_make_http_hostport);
+munit_void_test_decl(test_util_make_hostport);
+munit_void_test_decl(test_util_strifind);
+munit_void_test_decl(test_util_random_alpha_digit);
+munit_void_test_decl(test_util_format_hex);
+munit_void_test_decl(test_util_is_hex_string);
+munit_void_test_decl(test_util_decode_hex);
+munit_void_test_decl(test_util_extract_host);
+munit_void_test_decl(test_util_split_hostport);
+munit_void_test_decl(test_util_split_str);
+munit_void_test_decl(test_util_rstrip);
} // namespace shrpx