Add SETTINGS_ENABLE_CONNECT_PROTOCOL

This commit is contained in:
Tatsuhiro Tsujikawa 2018-03-10 17:19:45 +09:00
parent e5b3f9addd
commit 51e4ca9f7e
5 changed files with 63 additions and 1 deletions

View File

@ -680,7 +680,12 @@ typedef enum {
/**
* SETTINGS_MAX_HEADER_LIST_SIZE
*/
NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 0x06
NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 0x06,
/**
* SETTINGS_ENABLE_CONNECT_PROTOCOL
* (https://tools.ietf.org/html/draft-ietf-httpbis-h2-websockets-00)
*/
NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08
} nghttp2_settings_id;
/* Note: If we add SETTINGS, update the capacity of
NGHTTP2_INBOUND_NUM_IV as well */

View File

@ -1050,6 +1050,11 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv) {
break;
case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
break;
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
if (iv[i].value != 0 && iv[i].value != 1) {
return 0;
}
break;
}
}
return 1;

View File

@ -4361,6 +4361,9 @@ int nghttp2_session_update_local_settings(nghttp2_session *session,
case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
session->local_settings.max_header_list_size = iv[i].value;
break;
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
session->local_settings.enable_connect_protocol = iv[i].value;
break;
}
}
@ -4499,6 +4502,26 @@ int nghttp2_session_on_settings_received(nghttp2_session *session,
session->remote_settings.max_header_list_size = entry->value;
break;
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
if (entry->value != 0 && entry->value != 1) {
return session_handle_invalid_connection(
session, frame, NGHTTP2_ERR_PROTO,
"SETTINGS: invalid SETTINGS_ENABLE_CONNECT_PROTOCOL");
}
if (!session->server &&
session->remote_settings.enable_connect_protocol &&
entry->value == 0) {
return session_handle_invalid_connection(
session, frame, NGHTTP2_ERR_PROTO,
"SETTINGS: server attempted to disable "
"SETTINGS_ENABLE_CONNECT_PROTOCOL");
}
session->remote_settings.enable_connect_protocol = entry->value;
break;
}
}
@ -5250,6 +5273,7 @@ static void inbound_frame_set_settings_entry(nghttp2_inbound_frame *iframe) {
case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
case NGHTTP2_SETTINGS_MAX_FRAME_SIZE:
case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
break;
default:
DEBUGF("recv: unknown settings id=0x%02x\n", iv.settings_id);
@ -7330,6 +7354,8 @@ uint32_t nghttp2_session_get_remote_settings(nghttp2_session *session,
return session->remote_settings.max_frame_size;
case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
return session->remote_settings.max_header_list_size;
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
return session->remote_settings.enable_connect_protocol;
}
assert(0);
@ -7351,6 +7377,8 @@ uint32_t nghttp2_session_get_local_settings(nghttp2_session *session,
return session->local_settings.max_frame_size;
case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
return session->local_settings.max_header_list_size;
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
return session->local_settings.enable_connect_protocol;
}
assert(0);

View File

@ -164,6 +164,7 @@ typedef struct {
uint32_t initial_window_size;
uint32_t max_frame_size;
uint32_t max_header_list_size;
uint32_t enable_connect_protocol;
} nghttp2_settings_storage;
typedef enum {

View File

@ -3480,6 +3480,29 @@ void test_nghttp2_session_on_settings_received(void) {
CU_ASSERT(NGHTTP2_STREAM_CLOSING == stream1->state);
nghttp2_session_del(session);
/* It is invalid that peer disables ENABLE_CONNECT_PROTOCOL once it
has been enabled. */
nghttp2_session_client_new(&session, &callbacks, NULL);
session->remote_settings.enable_connect_protocol = 1;
iv[0].settings_id = NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL;
iv[0].value = 0;
nghttp2_frame_settings_init(&frame.settings, NGHTTP2_FLAG_NONE, dup_iv(iv, 1),
1);
CU_ASSERT(0 == nghttp2_session_on_settings_received(session, &frame, 0));
nghttp2_frame_settings_free(&frame.settings, mem);
item = nghttp2_session_get_next_ob_item(session);
CU_ASSERT(NULL != item);
CU_ASSERT(NGHTTP2_GOAWAY == item->frame.hd.type);
nghttp2_session_del(session);
}
void test_nghttp2_session_on_push_promise_received(void) {