diff --git a/lib/nghttp2_option.c b/lib/nghttp2_option.c index 65200942..e8d6ed16 100644 --- a/lib/nghttp2_option.c +++ b/lib/nghttp2_option.c @@ -24,6 +24,8 @@ */ #include "nghttp2_option.h" +#include "nghttp2_session.h" + int nghttp2_option_new(nghttp2_option **option_ptr) { *option_ptr = calloc(1, sizeof(nghttp2_option)); @@ -79,12 +81,14 @@ void nghttp2_option_set_user_recv_extension_type(nghttp2_option *option, void nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option, uint8_t type) { - if (type < 10) { + switch (type) { + case NGHTTP2_ALTSVC: + option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES; + option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_ALTSVC; + return; + default: return; } - - option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES; - set_ext_type(option->builtin_recv_ext_types, type); } void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option, int val) { diff --git a/lib/nghttp2_option.h b/lib/nghttp2_option.h index b7d69610..87ef4e04 100644 --- a/lib/nghttp2_option.h +++ b/lib/nghttp2_option.h @@ -82,6 +82,10 @@ struct nghttp2_option { * NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS */ uint32_t max_reserved_remote_streams; + /** + * NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES + */ + uint32_t builtin_recv_ext_types; /** * NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE */ @@ -102,10 +106,6 @@ struct nghttp2_option { * NGHTTP2_OPT_USER_RECV_EXT_TYPES */ uint8_t user_recv_ext_types[32]; - /** - * NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES - */ - uint8_t builtin_recv_ext_types[32]; }; #endif /* NGHTTP2_OPTION_H */ diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index 8af22bd7..d204596a 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -323,10 +323,12 @@ static void session_inbound_frame_reset(nghttp2_session *session) { if (check_ext_type_set(session->user_recv_ext_types, iframe->frame.hd.type)) { nghttp2_frame_extension_free(&iframe->frame.ext); - } else if (check_ext_type_set(session->builtin_recv_ext_types, - iframe->frame.hd.type)) { + } else { switch (iframe->frame.hd.type) { case NGHTTP2_ALTSVC: + if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) == 0) { + break; + } nghttp2_frame_altsvc_free(&iframe->frame.ext, mem); break; } @@ -492,9 +494,7 @@ static int session_new(nghttp2_session **session_ptr, } if (option->opt_set_mask & NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES) { - memcpy((*session_ptr)->builtin_recv_ext_types, - option->builtin_recv_ext_types, - sizeof((*session_ptr)->builtin_recv_ext_types)); + (*session_ptr)->builtin_recv_ext_types = option->builtin_recv_ext_types; } if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_PING_ACK) && @@ -5556,10 +5556,16 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in, iframe->state = NGHTTP2_IB_READ_EXTENSION_PAYLOAD; break; - } else if (check_ext_type_set(session->builtin_recv_ext_types, - iframe->frame.hd.type)) { + } else { switch (iframe->frame.hd.type) { case NGHTTP2_ALTSVC: + if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) == + 0) { + busy = 1; + iframe->state = NGHTTP2_IB_IGN_PAYLOAD; + break; + } + DEBUGF(fprintf(stderr, "recv: ALTSVC\n")); iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; @@ -5590,12 +5596,6 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in, break; } - } else { - busy = 1; - - iframe->state = NGHTTP2_IB_IGN_PAYLOAD; - - break; } } diff --git a/lib/nghttp2_session.h b/lib/nghttp2_session.h index 1e391dcb..a5cb1aec 100644 --- a/lib/nghttp2_session.h +++ b/lib/nghttp2_session.h @@ -54,6 +54,15 @@ typedef enum { NGHTTP2_OPTMASK_NO_AUTO_PING_ACK = 1 << 3 } nghttp2_optmask; +/* + * bitmask for built-in type to enable the default handling for that + * type of the frame. + */ +typedef enum { + NGHTTP2_TYPEMASK_NONE = 0, + NGHTTP2_TYPEMASK_ALTSVC = 1 << 0 +} nghttp2_typemask; + typedef enum { NGHTTP2_OB_POP_ITEM, NGHTTP2_OB_SEND_DATA, @@ -295,6 +304,9 @@ struct nghttp2_session { /* Unacked local SETTINGS_MAX_CONCURRENT_STREAMS value. We use this to refuse the incoming stream if it exceeds this value. */ uint32_t pending_local_max_concurrent_stream; + /* The bitwose OR of zero or more of nghttp2_typemask to indicate + that the default handling of extension frame is enabled. */ + uint32_t builtin_recv_ext_types; /* Unacked local ENABLE_PUSH value. We use this to refuse PUSH_PROMISE before SETTINGS ACK is received. */ uint8_t pending_enable_push; @@ -314,7 +326,6 @@ struct nghttp2_session { bit is set, it indicates that incoming frame with that type is passed to user defined callbacks, otherwise they are ignored. */ uint8_t user_recv_ext_types[32]; - uint8_t builtin_recv_ext_types[32]; }; /* Struct used when updating initial window size of each active