altsvc: Add tests, ignore altsvc if stream does not exist
This commit is contained in:
parent
6638ca9333
commit
d4144a7475
|
@ -4663,6 +4663,7 @@ static int session_process_window_update_frame(nghttp2_session *session) {
|
||||||
int nghttp2_session_on_altsvc_received(nghttp2_session *session,
|
int nghttp2_session_on_altsvc_received(nghttp2_session *session,
|
||||||
nghttp2_frame *frame) {
|
nghttp2_frame *frame) {
|
||||||
nghttp2_ext_altsvc *altsvc;
|
nghttp2_ext_altsvc *altsvc;
|
||||||
|
nghttp2_stream *stream;
|
||||||
|
|
||||||
altsvc = frame->ext.payload;
|
altsvc = frame->ext.payload;
|
||||||
|
|
||||||
|
@ -4672,10 +4673,21 @@ int nghttp2_session_on_altsvc_received(nghttp2_session *session,
|
||||||
if (altsvc->origin_len == 0) {
|
if (altsvc->origin_len == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (altsvc->origin_len > 0) {
|
} else {
|
||||||
|
if (altsvc->origin_len > 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
||||||
|
if (!stream) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream->state == NGHTTP2_STREAM_CLOSING) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return session_call_on_frame_received(session, frame);
|
return session_call_on_frame_received(session, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,8 @@ int main(int argc _U_, char *argv[] _U_) {
|
||||||
test_nghttp2_session_recv_too_large_frame_length) ||
|
test_nghttp2_session_recv_too_large_frame_length) ||
|
||||||
!CU_add_test(pSuite, "session_recv_extension",
|
!CU_add_test(pSuite, "session_recv_extension",
|
||||||
test_nghttp2_session_recv_extension) ||
|
test_nghttp2_session_recv_extension) ||
|
||||||
|
!CU_add_test(pSuite, "session_recv_altsvc",
|
||||||
|
test_nghttp2_session_recv_altsvc) ||
|
||||||
!CU_add_test(pSuite, "session_continue", test_nghttp2_session_continue) ||
|
!CU_add_test(pSuite, "session_continue", test_nghttp2_session_continue) ||
|
||||||
!CU_add_test(pSuite, "session_add_frame",
|
!CU_add_test(pSuite, "session_add_frame",
|
||||||
test_nghttp2_session_add_frame) ||
|
test_nghttp2_session_add_frame) ||
|
||||||
|
@ -132,6 +134,8 @@ int main(int argc _U_, char *argv[] _U_) {
|
||||||
test_nghttp2_session_on_data_received) ||
|
test_nghttp2_session_on_data_received) ||
|
||||||
!CU_add_test(pSuite, "session_on_data_received_fail_fast",
|
!CU_add_test(pSuite, "session_on_data_received_fail_fast",
|
||||||
test_nghttp2_session_on_data_received_fail_fast) ||
|
test_nghttp2_session_on_data_received_fail_fast) ||
|
||||||
|
!CU_add_test(pSuite, "session_on_altsvc_received",
|
||||||
|
test_nghttp2_session_on_altsvc_received) ||
|
||||||
!CU_add_test(pSuite, "session_send_headers_start_stream",
|
!CU_add_test(pSuite, "session_send_headers_start_stream",
|
||||||
test_nghttp2_session_send_headers_start_stream) ||
|
test_nghttp2_session_send_headers_start_stream) ||
|
||||||
!CU_add_test(pSuite, "session_send_headers_reply",
|
!CU_add_test(pSuite, "session_send_headers_reply",
|
||||||
|
|
|
@ -1955,6 +1955,124 @@ void test_nghttp2_session_recv_extension(void) {
|
||||||
nghttp2_option_del(option);
|
nghttp2_option_del(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_nghttp2_session_recv_altsvc(void) {
|
||||||
|
nghttp2_session *session;
|
||||||
|
nghttp2_session_callbacks callbacks;
|
||||||
|
my_user_data ud;
|
||||||
|
nghttp2_buf buf;
|
||||||
|
nghttp2_frame_hd hd;
|
||||||
|
nghttp2_mem *mem;
|
||||||
|
ssize_t rv;
|
||||||
|
nghttp2_option *option;
|
||||||
|
static const uint8_t origin[] = "nghttp2.org";
|
||||||
|
static const uint8_t field_value[] = "h2=\":443\"";
|
||||||
|
|
||||||
|
mem = nghttp2_mem_default();
|
||||||
|
|
||||||
|
nghttp2_buf_init2(&buf, NGHTTP2_FRAME_HDLEN + NGHTTP2_MAX_FRAME_SIZE_MIN,
|
||||||
|
mem);
|
||||||
|
|
||||||
|
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
||||||
|
|
||||||
|
callbacks.on_frame_recv_callback = on_frame_recv_callback;
|
||||||
|
|
||||||
|
nghttp2_option_new(&option);
|
||||||
|
nghttp2_option_set_builtin_recv_extension_type(option, NGHTTP2_ALTSVC);
|
||||||
|
|
||||||
|
nghttp2_session_client_new2(&session, &callbacks, &ud, option);
|
||||||
|
|
||||||
|
nghttp2_frame_hd_init(&hd, 2 + sizeof(origin) - 1 + sizeof(field_value) - 1,
|
||||||
|
NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE, 0);
|
||||||
|
nghttp2_frame_pack_frame_hd(buf.last, &hd);
|
||||||
|
buf.last += NGHTTP2_FRAME_HDLEN;
|
||||||
|
nghttp2_put_uint16be(buf.last, sizeof(origin) - 1);
|
||||||
|
buf.last += 2;
|
||||||
|
buf.last = nghttp2_cpymem(buf.last, origin, sizeof(origin) - 1);
|
||||||
|
buf.last = nghttp2_cpymem(buf.last, field_value, sizeof(field_value) - 1);
|
||||||
|
|
||||||
|
ud.frame_recv_cb_called = 0;
|
||||||
|
rv = nghttp2_session_mem_recv(session, buf.pos, nghttp2_buf_len(&buf));
|
||||||
|
|
||||||
|
CU_ASSERT((ssize_t)nghttp2_buf_len(&buf) == rv);
|
||||||
|
CU_ASSERT(1 == ud.frame_recv_cb_called);
|
||||||
|
CU_ASSERT(NGHTTP2_ALTSVC == ud.recv_frame_hd.type);
|
||||||
|
CU_ASSERT(NGHTTP2_FLAG_NONE == ud.recv_frame_hd.flags);
|
||||||
|
CU_ASSERT(0 == ud.recv_frame_hd.stream_id);
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
/* size of origin is larger than frame length */
|
||||||
|
nghttp2_buf_reset(&buf);
|
||||||
|
|
||||||
|
nghttp2_session_client_new2(&session, &callbacks, &ud, option);
|
||||||
|
|
||||||
|
nghttp2_frame_hd_init(&hd, 2 + sizeof(origin) - 1 - 1, NGHTTP2_ALTSVC,
|
||||||
|
NGHTTP2_FLAG_NONE, 0);
|
||||||
|
nghttp2_frame_pack_frame_hd(buf.last, &hd);
|
||||||
|
buf.last += NGHTTP2_FRAME_HDLEN;
|
||||||
|
nghttp2_put_uint16be(buf.last, sizeof(origin) - 1);
|
||||||
|
buf.last += 2;
|
||||||
|
buf.last = nghttp2_cpymem(buf.last, origin, sizeof(origin) - 1 - 1);
|
||||||
|
|
||||||
|
ud.frame_recv_cb_called = 0;
|
||||||
|
rv = nghttp2_session_mem_recv(session, buf.pos, nghttp2_buf_len(&buf));
|
||||||
|
|
||||||
|
CU_ASSERT((ssize_t)nghttp2_buf_len(&buf) == rv);
|
||||||
|
CU_ASSERT(0 == ud.frame_recv_cb_called);
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
/* send large frame (16KiB) */
|
||||||
|
nghttp2_buf_reset(&buf);
|
||||||
|
|
||||||
|
nghttp2_session_client_new2(&session, &callbacks, &ud, option);
|
||||||
|
|
||||||
|
nghttp2_frame_hd_init(&hd, NGHTTP2_MAX_FRAME_SIZE_MIN, NGHTTP2_ALTSVC,
|
||||||
|
NGHTTP2_FLAG_NONE, 0);
|
||||||
|
nghttp2_frame_pack_frame_hd(buf.last, &hd);
|
||||||
|
buf.last += NGHTTP2_FRAME_HDLEN;
|
||||||
|
nghttp2_put_uint16be(buf.last, sizeof(origin) - 1);
|
||||||
|
buf.last += 2;
|
||||||
|
buf.last = nghttp2_cpymem(buf.last, origin, sizeof(origin) - 1);
|
||||||
|
memset(buf.last, 0, nghttp2_buf_avail(&buf));
|
||||||
|
buf.last += nghttp2_buf_avail(&buf);
|
||||||
|
|
||||||
|
ud.frame_recv_cb_called = 0;
|
||||||
|
rv = nghttp2_session_mem_recv(session, buf.pos, nghttp2_buf_len(&buf));
|
||||||
|
|
||||||
|
CU_ASSERT((ssize_t)nghttp2_buf_len(&buf) == rv);
|
||||||
|
CU_ASSERT(1 == ud.frame_recv_cb_called);
|
||||||
|
CU_ASSERT(NGHTTP2_ALTSVC == ud.recv_frame_hd.type);
|
||||||
|
CU_ASSERT(NGHTTP2_MAX_FRAME_SIZE_MIN == ud.recv_frame_hd.length);
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
/* received by server */
|
||||||
|
nghttp2_buf_reset(&buf);
|
||||||
|
|
||||||
|
nghttp2_session_server_new2(&session, &callbacks, &ud, option);
|
||||||
|
|
||||||
|
nghttp2_frame_hd_init(&hd, 2 + sizeof(origin) - 1 + sizeof(field_value) - 1,
|
||||||
|
NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE, 0);
|
||||||
|
nghttp2_frame_pack_frame_hd(buf.last, &hd);
|
||||||
|
buf.last += NGHTTP2_FRAME_HDLEN;
|
||||||
|
nghttp2_put_uint16be(buf.last, sizeof(origin) - 1);
|
||||||
|
buf.last += 2;
|
||||||
|
buf.last = nghttp2_cpymem(buf.last, origin, sizeof(origin) - 1);
|
||||||
|
buf.last = nghttp2_cpymem(buf.last, field_value, sizeof(field_value) - 1);
|
||||||
|
|
||||||
|
ud.frame_recv_cb_called = 0;
|
||||||
|
rv = nghttp2_session_mem_recv(session, buf.pos, nghttp2_buf_len(&buf));
|
||||||
|
|
||||||
|
CU_ASSERT((ssize_t)nghttp2_buf_len(&buf) == rv);
|
||||||
|
CU_ASSERT(0 == ud.frame_recv_cb_called);
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
nghttp2_buf_free(&buf, mem);
|
||||||
|
nghttp2_option_del(option);
|
||||||
|
}
|
||||||
|
|
||||||
void test_nghttp2_session_continue(void) {
|
void test_nghttp2_session_continue(void) {
|
||||||
nghttp2_session *session;
|
nghttp2_session *session;
|
||||||
nghttp2_session_callbacks callbacks;
|
nghttp2_session_callbacks callbacks;
|
||||||
|
@ -3364,6 +3482,113 @@ void test_nghttp2_session_on_data_received_fail_fast(void) {
|
||||||
nghttp2_session_del(session);
|
nghttp2_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_nghttp2_session_on_altsvc_received(void) {
|
||||||
|
nghttp2_session *session;
|
||||||
|
nghttp2_session_callbacks callbacks;
|
||||||
|
my_user_data ud;
|
||||||
|
nghttp2_frame frame;
|
||||||
|
nghttp2_mem *mem;
|
||||||
|
nghttp2_option *option;
|
||||||
|
uint8_t origin[] = "nghttp2.org";
|
||||||
|
uint8_t field_value[] = "h2=\":443\"";
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
mem = nghttp2_mem_default();
|
||||||
|
|
||||||
|
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
||||||
|
callbacks.on_frame_recv_callback = on_frame_recv_callback;
|
||||||
|
|
||||||
|
nghttp2_option_new(&option);
|
||||||
|
nghttp2_option_set_builtin_recv_extension_type(option, NGHTTP2_ALTSVC);
|
||||||
|
|
||||||
|
nghttp2_session_client_new2(&session, &callbacks, &ud, option);
|
||||||
|
|
||||||
|
frame.ext.payload = &session->iframe.ext_frame_payload;
|
||||||
|
|
||||||
|
/* We just pass the strings without making a copy. This is OK,
|
||||||
|
since we never call nghttp2_frame_altsvc_free(). */
|
||||||
|
nghttp2_frame_altsvc_init(&frame.ext, 0, origin, sizeof(origin) - 1,
|
||||||
|
field_value, sizeof(field_value) - 1);
|
||||||
|
|
||||||
|
ud.frame_recv_cb_called = 0;
|
||||||
|
rv = nghttp2_session_on_altsvc_received(session, &frame);
|
||||||
|
|
||||||
|
CU_ASSERT(0 == rv);
|
||||||
|
CU_ASSERT(1 == ud.frame_recv_cb_called);
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
/* Receiving empty origin with stream ID == 0 */
|
||||||
|
nghttp2_session_client_new2(&session, &callbacks, &ud, option);
|
||||||
|
|
||||||
|
frame.ext.payload = &session->iframe.ext_frame_payload;
|
||||||
|
|
||||||
|
nghttp2_frame_altsvc_init(&frame.ext, 0, origin, 0, field_value,
|
||||||
|
sizeof(field_value) - 1);
|
||||||
|
|
||||||
|
ud.frame_recv_cb_called = 0;
|
||||||
|
rv = nghttp2_session_on_altsvc_received(session, &frame);
|
||||||
|
|
||||||
|
CU_ASSERT(0 == rv);
|
||||||
|
CU_ASSERT(0 == ud.frame_recv_cb_called);
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
/* Receiving non-empty origin with stream ID != 0 */
|
||||||
|
nghttp2_session_client_new2(&session, &callbacks, &ud, option);
|
||||||
|
|
||||||
|
frame.ext.payload = &session->iframe.ext_frame_payload;
|
||||||
|
|
||||||
|
open_sent_stream(session, 1);
|
||||||
|
|
||||||
|
nghttp2_frame_altsvc_init(&frame.ext, 1, origin, sizeof(origin) - 1,
|
||||||
|
field_value, sizeof(field_value) - 1);
|
||||||
|
|
||||||
|
ud.frame_recv_cb_called = 0;
|
||||||
|
rv = nghttp2_session_on_altsvc_received(session, &frame);
|
||||||
|
|
||||||
|
CU_ASSERT(0 == rv);
|
||||||
|
CU_ASSERT(0 == ud.frame_recv_cb_called);
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
/* Receiving empty origin with stream ID != 0; this is OK */
|
||||||
|
nghttp2_session_client_new2(&session, &callbacks, &ud, option);
|
||||||
|
|
||||||
|
frame.ext.payload = &session->iframe.ext_frame_payload;
|
||||||
|
|
||||||
|
open_sent_stream(session, 1);
|
||||||
|
|
||||||
|
nghttp2_frame_altsvc_init(&frame.ext, 1, origin, 0, field_value,
|
||||||
|
sizeof(field_value) - 1);
|
||||||
|
|
||||||
|
ud.frame_recv_cb_called = 0;
|
||||||
|
rv = nghttp2_session_on_altsvc_received(session, &frame);
|
||||||
|
|
||||||
|
CU_ASSERT(0 == rv);
|
||||||
|
CU_ASSERT(1 == ud.frame_recv_cb_called);
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
/* Stream does not exist; ALTSVC will be ignored. */
|
||||||
|
nghttp2_session_client_new2(&session, &callbacks, &ud, option);
|
||||||
|
|
||||||
|
frame.ext.payload = &session->iframe.ext_frame_payload;
|
||||||
|
|
||||||
|
nghttp2_frame_altsvc_init(&frame.ext, 1, origin, 0, field_value,
|
||||||
|
sizeof(field_value) - 1);
|
||||||
|
|
||||||
|
ud.frame_recv_cb_called = 0;
|
||||||
|
rv = nghttp2_session_on_altsvc_received(session, &frame);
|
||||||
|
|
||||||
|
CU_ASSERT(0 == rv);
|
||||||
|
CU_ASSERT(0 == ud.frame_recv_cb_called);
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
nghttp2_option_del(option);
|
||||||
|
}
|
||||||
|
|
||||||
void test_nghttp2_session_send_headers_start_stream(void) {
|
void test_nghttp2_session_send_headers_start_stream(void) {
|
||||||
nghttp2_session *session;
|
nghttp2_session *session;
|
||||||
nghttp2_session_callbacks callbacks;
|
nghttp2_session_callbacks callbacks;
|
||||||
|
|
|
@ -45,6 +45,7 @@ void test_nghttp2_session_recv_unexpected_continuation(void);
|
||||||
void test_nghttp2_session_recv_settings_header_table_size(void);
|
void test_nghttp2_session_recv_settings_header_table_size(void);
|
||||||
void test_nghttp2_session_recv_too_large_frame_length(void);
|
void test_nghttp2_session_recv_too_large_frame_length(void);
|
||||||
void test_nghttp2_session_recv_extension(void);
|
void test_nghttp2_session_recv_extension(void);
|
||||||
|
void test_nghttp2_session_recv_altsvc(void);
|
||||||
void test_nghttp2_session_continue(void);
|
void test_nghttp2_session_continue(void);
|
||||||
void test_nghttp2_session_add_frame(void);
|
void test_nghttp2_session_add_frame(void);
|
||||||
void test_nghttp2_session_on_request_headers_received(void);
|
void test_nghttp2_session_on_request_headers_received(void);
|
||||||
|
@ -60,6 +61,7 @@ void test_nghttp2_session_on_goaway_received(void);
|
||||||
void test_nghttp2_session_on_window_update_received(void);
|
void test_nghttp2_session_on_window_update_received(void);
|
||||||
void test_nghttp2_session_on_data_received(void);
|
void test_nghttp2_session_on_data_received(void);
|
||||||
void test_nghttp2_session_on_data_received_fail_fast(void);
|
void test_nghttp2_session_on_data_received_fail_fast(void);
|
||||||
|
void test_nghttp2_session_on_altsvc_received(void);
|
||||||
void test_nghttp2_session_send_headers_start_stream(void);
|
void test_nghttp2_session_send_headers_start_stream(void);
|
||||||
void test_nghttp2_session_send_headers_reply(void);
|
void test_nghttp2_session_send_headers_reply(void);
|
||||||
void test_nghttp2_session_send_headers_frame_size_error(void);
|
void test_nghttp2_session_send_headers_frame_size_error(void);
|
||||||
|
|
Loading…
Reference in New Issue