diff --git a/lib/nghttp2_submit.c b/lib/nghttp2_submit.c index 3c6a3664..bdce2b24 100644 --- a/lib/nghttp2_submit.c +++ b/lib/nghttp2_submit.c @@ -470,8 +470,8 @@ int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags _U_, item->aux_data.ext.builtin = 1; - altsvc = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { + altsvc = nghttp2_mem_malloc(mem, sizeof(nghttp2_ext_altsvc)); + if (altsvc == NULL) { rv = NGHTTP2_ERR_NOMEM; goto fail_altsvc_malloc; } diff --git a/tests/failmalloc.c b/tests/failmalloc.c index 472be317..f2734033 100644 --- a/tests/failmalloc.c +++ b/tests/failmalloc.c @@ -55,6 +55,8 @@ int main(int argc _U_, char *argv[] _U_) { /* add the tests to the suite */ if (!CU_add_test(pSuite, "failmalloc_session_send", test_nghttp2_session_send) || + !CU_add_test(pSuite, "failmalloc_session_send_server", + test_nghttp2_session_send_server) || !CU_add_test(pSuite, "failmalloc_session_recv", test_nghttp2_session_recv) || !CU_add_test(pSuite, "failmalloc_frame", test_nghttp2_frame) || diff --git a/tests/failmalloc_test.c b/tests/failmalloc_test.c index 923975b0..9869611d 100644 --- a/tests/failmalloc_test.c +++ b/tests/failmalloc_test.c @@ -217,6 +217,50 @@ void test_nghttp2_session_send(void) { TEST_FAILMALLOC_RUN(run_nghttp2_session_send); } +static void run_nghttp2_session_send_server(void) { + nghttp2_session *session; + nghttp2_session_callbacks *callbacks; + int rv; + const uint8_t *txdata; + ssize_t txdatalen; + rv = nghttp2_session_callbacks_new(&callbacks); + if (rv != 0) { + return; + } + + rv = nghttp2_session_server_new3(&session, callbacks, NULL, NULL, + nghttp2_mem_fm()); + + nghttp2_session_callbacks_del(callbacks); + + if (rv != 0) { + return; + } + + const uint8_t origin[] = "nghttp2.org"; + const uint8_t altsvc_field_value[] = "h2=\":443\""; + + rv = nghttp2_submit_altsvc(session, NGHTTP2_FLAG_NONE, 0, origin, + sizeof(origin) - 1, altsvc_field_value, + sizeof(altsvc_field_value) - 1); + if (rv != 0) { + goto fail; + } + + txdatalen = nghttp2_session_mem_send(session, &txdata); + + if (txdatalen < 0) { + goto fail; + } + +fail: + nghttp2_session_del(session); +} + +void test_nghttp2_session_send_server(void) { + TEST_FAILMALLOC_RUN(run_nghttp2_session_send_server); +} + static void run_nghttp2_session_recv(void) { nghttp2_session *session; nghttp2_session_callbacks callbacks; diff --git a/tests/failmalloc_test.h b/tests/failmalloc_test.h index fb7e7701..c4306530 100644 --- a/tests/failmalloc_test.h +++ b/tests/failmalloc_test.h @@ -30,6 +30,7 @@ #endif /* HAVE_CONFIG_H */ void test_nghttp2_session_send(void); +void test_nghttp2_session_send_server(void); void test_nghttp2_session_recv(void); void test_nghttp2_frame(void); void test_nghttp2_hd(void); diff --git a/tests/main.c b/tests/main.c index 6a985317..fe8ec8e6 100644 --- a/tests/main.c +++ b/tests/main.c @@ -197,6 +197,7 @@ int main(int argc _U_, char *argv[] _U_) { !CU_add_test(pSuite, "submit_invalid_nv", test_nghttp2_submit_invalid_nv) || !CU_add_test(pSuite, "submit_extension", test_nghttp2_submit_extension) || + !CU_add_test(pSuite, "submit_altsvc", test_nghttp2_submit_altsvc) || !CU_add_test(pSuite, "session_open_stream", test_nghttp2_session_open_stream) || !CU_add_test(pSuite, "session_open_stream_with_idle_stream_dep", diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c index 2e7dafee..509a15de 100644 --- a/tests/nghttp2_session_test.c +++ b/tests/nghttp2_session_test.c @@ -5217,6 +5217,82 @@ void test_nghttp2_submit_extension(void) { nghttp2_buf_free(&ud.scratchbuf, mem); } +void test_nghttp2_submit_altsvc(void) { + nghttp2_session *session; + nghttp2_session_callbacks callbacks; + nghttp2_mem *mem; + my_user_data ud; + int rv; + ssize_t len; + const uint8_t *data; + nghttp2_frame_hd hd; + size_t origin_len; + + mem = nghttp2_mem_default(); + + memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); + + nghttp2_session_server_new(&session, &callbacks, &ud); + + const uint8_t origin[] = "nghttp2.org"; + const uint8_t field_value[] = "h2=\":443\""; + + rv = nghttp2_submit_altsvc(session, NGHTTP2_FLAG_NONE, 0, origin, + sizeof(origin) - 1, field_value, + sizeof(field_value) - 1); + + CU_ASSERT(0 == rv); + + ud.frame_send_cb_called = 0; + + len = nghttp2_session_mem_send(session, &data); + + CU_ASSERT(len == + NGHTTP2_FRAME_HDLEN + 2 + sizeof(origin) - 1 + sizeof(field_value) - + 1); + + nghttp2_frame_unpack_frame_hd(&hd, data); + + CU_ASSERT(2 + sizeof(origin) - 1 + sizeof(field_value) - 1 == hd.length); + CU_ASSERT(NGHTTP2_ALTSVC == hd.type); + CU_ASSERT(NGHTTP2_FLAG_NONE == hd.flags); + + origin_len = nghttp2_get_uint16(data + NGHTTP2_FRAME_HDLEN); + + CU_ASSERT(sizeof(origin) - 1 == origin_len); + CU_ASSERT(0 == + memcmp(origin, data + NGHTTP2_FRAME_HDLEN + 2, sizeof(origin) - 1)); + CU_ASSERT(0 == memcmp(field_value, + data + NGHTTP2_FRAME_HDLEN + 2 + sizeof(origin) - 1, + hd.length - (sizeof(origin) - 1) - 2)); + + /* submitting empty origin with stream_id == 0 is error */ + rv = nghttp2_submit_altsvc(session, NGHTTP2_FLAG_NONE, 0, NULL, 0, + field_value, sizeof(field_value) - 1); + + CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT == rv); + + /* submitting non-empty origin with stream_id != 0 is error */ + rv = nghttp2_submit_altsvc(session, NGHTTP2_FLAG_NONE, 1, origin, + sizeof(origin) - 1, field_value, + sizeof(field_value) - 1); + + CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT == rv); + + nghttp2_session_del(session); + + /* submitting from client side session is error */ + nghttp2_session_client_new(&session, &callbacks, NULL); + + rv = nghttp2_submit_altsvc(session, NGHTTP2_FLAG_NONE, 0, origin, + sizeof(origin) - 1, field_value, + sizeof(field_value) - 1); + + CU_ASSERT(NGHTTP2_ERR_INVALID_STATE == rv); + + nghttp2_session_del(session); +} + void test_nghttp2_session_open_stream(void) { nghttp2_session *session; nghttp2_session_callbacks callbacks; diff --git a/tests/nghttp2_session_test.h b/tests/nghttp2_session_test.h index 27415c2f..8199ecd6 100644 --- a/tests/nghttp2_session_test.h +++ b/tests/nghttp2_session_test.h @@ -95,6 +95,7 @@ void test_nghttp2_submit_window_update_local_window_size(void); void test_nghttp2_submit_shutdown_notice(void); void test_nghttp2_submit_invalid_nv(void); void test_nghttp2_submit_extension(void); +void test_nghttp2_submit_altsvc(void); void test_nghttp2_session_open_stream(void); void test_nghttp2_session_open_stream_with_idle_stream_dep(void); void test_nghttp2_session_get_next_ob_item(void);