diff --git a/lib/nghttp2_frame.c b/lib/nghttp2_frame.c index b422327e..451aea55 100644 --- a/lib/nghttp2_frame.c +++ b/lib/nghttp2_frame.c @@ -622,13 +622,19 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv) size_t i; for(i = 0; i < niv; ++i) { switch(iv[i].settings_id) { + case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: + case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: + break; + case NGHTTP2_SETTINGS_ENABLE_PUSH: + if(iv[i].value != 0 && iv[i].value != 1) { + return 0; + } + break; case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: if(iv[i].value > (uint32_t)NGHTTP2_MAX_WINDOW_SIZE) { return 0; } break; - default: - break; } } return 1; diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index f5264e0b..0108d542 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -2720,23 +2720,27 @@ int nghttp2_session_on_settings_received(nghttp2_session *session, } } break; + case NGHTTP2_SETTINGS_ENABLE_PUSH: + if(entry->value != 0 && entry->value != 1) { + return nghttp2_session_handle_invalid_connection + (session, frame, NGHTTP2_PROTOCOL_ERROR); + } + break; case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: /* Update the initial window size of the all active streams */ /* Check that initial_window_size < (1u << 31) */ - if(entry->value <= NGHTTP2_MAX_WINDOW_SIZE) { - rv = nghttp2_session_update_remote_initial_window_size - (session, entry->value); - if(rv != 0) { - if(nghttp2_is_fatal(rv)) { - return rv; - } else { - return nghttp2_session_handle_invalid_connection - (session, frame, NGHTTP2_FLOW_CONTROL_ERROR); - } - } - } else { + if(entry->value > NGHTTP2_MAX_WINDOW_SIZE) { return nghttp2_session_handle_invalid_connection - (session, frame, NGHTTP2_PROTOCOL_ERROR); + (session, frame, NGHTTP2_FLOW_CONTROL_ERROR); + } + rv = nghttp2_session_update_remote_initial_window_size + (session, entry->value); + if(nghttp2_is_fatal(rv)) { + return rv; + } + if(rv != 0) { + return nghttp2_session_handle_invalid_connection + (session, frame, NGHTTP2_FLOW_CONTROL_ERROR); } break; } diff --git a/tests/nghttp2_frame_test.c b/tests/nghttp2_frame_test.c index b28d7d33..08e7f698 100644 --- a/tests/nghttp2_frame_test.c +++ b/tests/nghttp2_frame_test.c @@ -409,4 +409,13 @@ void test_nghttp2_iv_check(void) /* Too large window size */ iv[1].value = (uint32_t)NGHTTP2_MAX_WINDOW_SIZE + 1; CU_ASSERT(0 == nghttp2_iv_check(iv, 2)); + + /* ENABLE_PUSH only allows 0 or 1 */ + iv[1].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH; + iv[1].value = 0; + CU_ASSERT(nghttp2_iv_check(iv, 2)); + iv[1].value = 1; + CU_ASSERT(nghttp2_iv_check(iv, 2)); + iv[1].value = 3; + CU_ASSERT(!nghttp2_iv_check(iv, 2)); } diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c index cbf31a3e..5ec1b04a 100644 --- a/tests/nghttp2_session_test.c +++ b/tests/nghttp2_session_test.c @@ -1314,8 +1314,7 @@ void test_nghttp2_session_on_settings_received(void) iv[3].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE; iv[3].value = 1024; - /* Unknown settings ID */ - iv[4].settings_id = 999; + iv[4].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH; iv[4].value = 0; memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); @@ -1343,6 +1342,8 @@ void test_nghttp2_session_on_settings_received(void) session->remote_settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]); CU_ASSERT(1024 == session->remote_settings[NGHTTP2_SETTINGS_HEADER_TABLE_SIZE]); + CU_ASSERT(0 == + session->remote_settings[NGHTTP2_SETTINGS_ENABLE_PUSH]); CU_ASSERT(64*1024 == stream1->remote_window_size); CU_ASSERT(0 == stream2->remote_window_size);