From 41e707627531f5d154af7c77ec3d573c90de7b60 Mon Sep 17 00:00:00 2001 From: nodejs-github-bot <18269663+nodejs-github-bot@users.noreply.github.com> Date: Sun, 21 Dec 2025 00:41:46 +0000 Subject: [PATCH 1/2] deps: update nghttp2 to 1.68.0 --- .../nghttp2/lib/includes/nghttp2/nghttp2ver.h | 4 +- deps/nghttp2/lib/nghttp2_alpn.h | 4 +- deps/nghttp2/lib/nghttp2_buf.h | 4 +- deps/nghttp2/lib/nghttp2_callbacks.h | 4 +- deps/nghttp2/lib/nghttp2_debug.c | 4 +- deps/nghttp2/lib/nghttp2_debug.h | 8 +- deps/nghttp2/lib/nghttp2_extpri.h | 4 +- deps/nghttp2/lib/nghttp2_frame.h | 4 +- deps/nghttp2/lib/nghttp2_hd.h | 4 +- deps/nghttp2/lib/nghttp2_hd_huffman.h | 4 +- deps/nghttp2/lib/nghttp2_helper.h | 4 +- deps/nghttp2/lib/nghttp2_http.h | 4 +- deps/nghttp2/lib/nghttp2_int.h | 10 +- deps/nghttp2/lib/nghttp2_mem.h | 4 +- deps/nghttp2/lib/nghttp2_net.h | 16 +- deps/nghttp2/lib/nghttp2_option.h | 4 +- deps/nghttp2/lib/nghttp2_outbound_item.h | 4 +- deps/nghttp2/lib/nghttp2_pq.h | 4 +- deps/nghttp2/lib/nghttp2_priority_spec.h | 4 +- deps/nghttp2/lib/nghttp2_queue.h | 4 +- deps/nghttp2/lib/nghttp2_ratelim.h | 4 +- deps/nghttp2/lib/nghttp2_rcbuf.h | 4 +- deps/nghttp2/lib/nghttp2_session.c | 216 +++++++++++------- deps/nghttp2/lib/nghttp2_session.h | 4 +- deps/nghttp2/lib/nghttp2_stream.h | 4 +- deps/nghttp2/lib/nghttp2_submit.h | 4 +- deps/nghttp2/lib/nghttp2_time.c | 15 +- deps/nghttp2/lib/nghttp2_time.h | 4 +- deps/nghttp2/lib/nghttp2_version.c | 2 +- 29 files changed, 206 insertions(+), 153 deletions(-) diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h index bd5e6c28723232..8dfe536dec9ade 100644 --- a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h +++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h @@ -29,7 +29,7 @@ * @macro * Version number of the nghttp2 library release */ -#define NGHTTP2_VERSION "1.67.1" +#define NGHTTP2_VERSION "1.68.0" /** * @macro @@ -37,6 +37,6 @@ * release. This is a 24 bit number with 8 bits for major number, 8 bits * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. */ -#define NGHTTP2_VERSION_NUM 0x014301 +#define NGHTTP2_VERSION_NUM 0x014400 #endif /* NGHTTP2VER_H */ diff --git a/deps/nghttp2/lib/nghttp2_alpn.h b/deps/nghttp2/lib/nghttp2_alpn.h index 09810fd821490a..ecc9ed204e9d0a 100644 --- a/deps/nghttp2/lib/nghttp2_alpn.h +++ b/deps/nghttp2/lib/nghttp2_alpn.h @@ -27,8 +27,8 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include -#endif /* NGHTTP2_ALPN_H */ +#endif /* !defined(NGHTTP2_ALPN_H) */ diff --git a/deps/nghttp2/lib/nghttp2_buf.h b/deps/nghttp2/lib/nghttp2_buf.h index 95ff3706a232a3..636aa619cb69c2 100644 --- a/deps/nghttp2/lib/nghttp2_buf.h +++ b/deps/nghttp2/lib/nghttp2_buf.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -409,4 +409,4 @@ int nghttp2_bufs_next_present(nghttp2_bufs *bufs); */ size_t nghttp2_bufs_len(nghttp2_bufs *bufs); -#endif /* NGHTTP2_BUF_H */ +#endif /* !defined(NGHTTP2_BUF_H) */ diff --git a/deps/nghttp2/lib/nghttp2_callbacks.h b/deps/nghttp2/lib/nghttp2_callbacks.h index ad515970c48a36..4b45e57849b646 100644 --- a/deps/nghttp2/lib/nghttp2_callbacks.h +++ b/deps/nghttp2/lib/nghttp2_callbacks.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -154,4 +154,4 @@ struct nghttp2_session_callbacks { nghttp2_rand_callback rand_callback; }; -#endif /* NGHTTP2_CALLBACKS_H */ +#endif /* !defined(NGHTTP2_CALLBACKS_H) */ diff --git a/deps/nghttp2/lib/nghttp2_debug.c b/deps/nghttp2/lib/nghttp2_debug.c index 09dd2b28587af5..b5f33ef3a6d1a9 100644 --- a/deps/nghttp2/lib/nghttp2_debug.c +++ b/deps/nghttp2/lib/nghttp2_debug.c @@ -50,11 +50,11 @@ void nghttp2_set_debug_vprintf_callback( static_debug_vprintf_callback = debug_vprintf_callback; } -#else /* !DEBUGBUILD */ +#else /* !defined(DEBUGBUILD) */ void nghttp2_set_debug_vprintf_callback( nghttp2_debug_vprintf_callback debug_vprintf_callback) { (void)debug_vprintf_callback; } -#endif /* !DEBUGBUILD */ +#endif /* !defined(DEBUGBUILD) */ diff --git a/deps/nghttp2/lib/nghttp2_debug.h b/deps/nghttp2/lib/nghttp2_debug.h index cbb4dd57547234..26566a622dba85 100644 --- a/deps/nghttp2/lib/nghttp2_debug.h +++ b/deps/nghttp2/lib/nghttp2_debug.h @@ -27,17 +27,17 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include #ifdef DEBUGBUILD # define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__) void nghttp2_debug_vprintf(const char *format, ...); -#else +#else /* !defined(DEBUGBUILD) */ # define DEBUGF(...) \ do { \ } while (0) -#endif +#endif /* !defined(DEBUGBUILD) */ -#endif /* NGHTTP2_DEBUG_H */ +#endif /* !defined(NGHTTP2_DEBUG_H) */ diff --git a/deps/nghttp2/lib/nghttp2_extpri.h b/deps/nghttp2/lib/nghttp2_extpri.h index db911972084c72..2e0391653b2c3e 100644 --- a/deps/nghttp2/lib/nghttp2_extpri.h +++ b/deps/nghttp2/lib/nghttp2_extpri.h @@ -28,7 +28,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -62,4 +62,4 @@ void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri); */ #define nghttp2_extpri_uint8_inc(PRI) (((PRI) & NGHTTP2_EXTPRI_INC_MASK) != 0) -#endif /* NGHTTP2_EXTPRI_H */ +#endif /* !defined(NGHTTP2_EXTPRI_H) */ diff --git a/deps/nghttp2/lib/nghttp2_frame.h b/deps/nghttp2/lib/nghttp2_frame.h index d58668806c432a..ed4ab2c6842e71 100644 --- a/deps/nghttp2/lib/nghttp2_frame.h +++ b/deps/nghttp2/lib/nghttp2_frame.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include #include "nghttp2_hd.h" @@ -634,4 +634,4 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv); void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd, size_t padlen, int framehd_only); -#endif /* NGHTTP2_FRAME_H */ +#endif /* !defined(NGHTTP2_FRAME_H) */ diff --git a/deps/nghttp2/lib/nghttp2_hd.h b/deps/nghttp2/lib/nghttp2_hd.h index 38a31a83c3891d..bdc7fad5c2b50e 100644 --- a/deps/nghttp2/lib/nghttp2_hd.h +++ b/deps/nghttp2/lib/nghttp2_hd.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -439,4 +439,4 @@ nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, */ int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx); -#endif /* NGHTTP2_HD_H */ +#endif /* !defined(NGHTTP2_HD_H) */ diff --git a/deps/nghttp2/lib/nghttp2_hd_huffman.h b/deps/nghttp2/lib/nghttp2_hd_huffman.h index 2bfd5318165f28..df037a8b20efc3 100644 --- a/deps/nghttp2/lib/nghttp2_hd_huffman.h +++ b/deps/nghttp2/lib/nghttp2_hd_huffman.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -69,4 +69,4 @@ typedef struct { extern const nghttp2_huff_sym huff_sym_table[]; extern const nghttp2_huff_decode huff_decode_table[][16]; -#endif /* NGHTTP2_HD_HUFFMAN_H */ +#endif /* !defined(NGHTTP2_HD_HUFFMAN_H) */ diff --git a/deps/nghttp2/lib/nghttp2_helper.h b/deps/nghttp2/lib/nghttp2_helper.h index f5de6290dab0e1..7d64076140ce88 100644 --- a/deps/nghttp2/lib/nghttp2_helper.h +++ b/deps/nghttp2/lib/nghttp2_helper.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include #include @@ -142,4 +142,4 @@ int nghttp2_should_send_window_update(int32_t local_window_size, */ uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len); -#endif /* NGHTTP2_HELPER_H */ +#endif /* !defined(NGHTTP2_HELPER_H) */ diff --git a/deps/nghttp2/lib/nghttp2_http.h b/deps/nghttp2/lib/nghttp2_http.h index d9992fe690830b..2925334c0b64e8 100644 --- a/deps/nghttp2/lib/nghttp2_http.h +++ b/deps/nghttp2/lib/nghttp2_http.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include #include "nghttp2_session.h" @@ -97,4 +97,4 @@ void nghttp2_http_record_request_method(nghttp2_stream *stream, int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value, size_t valuelen); -#endif /* NGHTTP2_HTTP_H */ +#endif /* !defined(NGHTTP2_HTTP_H) */ diff --git a/deps/nghttp2/lib/nghttp2_int.h b/deps/nghttp2/lib/nghttp2_int.h index b23585ccb27da2..d89cf154543f53 100644 --- a/deps/nghttp2/lib/nghttp2_int.h +++ b/deps/nghttp2/lib/nghttp2_int.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -52,7 +52,11 @@ typedef enum { * Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke * nghttp2_on_invalid_header_callback. */ - NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106 + NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106, + /* + * Cancel pushed stream. + */ + NGHTTP2_ERR_PUSH_CANCEL = -107, } nghttp2_internal_error; -#endif /* NGHTTP2_INT_H */ +#endif /* !defined(NGHTTP2_INT_H) */ diff --git a/deps/nghttp2/lib/nghttp2_mem.h b/deps/nghttp2/lib/nghttp2_mem.h index f83dbcb8f9a588..10af7c695ef81f 100644 --- a/deps/nghttp2/lib/nghttp2_mem.h +++ b/deps/nghttp2/lib/nghttp2_mem.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -42,4 +42,4 @@ void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data); void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size); void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size); -#endif /* NGHTTP2_MEM_H */ +#endif /* !defined(NGHTTP2_MEM_H) */ diff --git a/deps/nghttp2/lib/nghttp2_net.h b/deps/nghttp2/lib/nghttp2_net.h index 521f98143e4765..0c57d947964460 100644 --- a/deps/nghttp2/lib/nghttp2_net.h +++ b/deps/nghttp2/lib/nghttp2_net.h @@ -27,28 +27,28 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #ifdef HAVE_ARPA_INET_H # include -#endif /* HAVE_ARPA_INET_H */ +#endif /* defined(HAVE_ARPA_INET_H) */ #ifdef HAVE_NETINET_IN_H # include -#endif /* HAVE_NETINET_IN_H */ +#endif /* defined(HAVE_NETINET_IN_H) */ #include -#if defined(WIN32) +#ifdef WIN32 /* Windows requires ws2_32 library for ntonl family functions. We define inline functions for those function so that we don't have dependency on that lib. */ # ifdef _MSC_VER # define STIN static __inline -# else +# else /* !defined(_MSC_VER) */ # define STIN static inline -# endif +# endif /* !defined(_MSC_VER) */ STIN uint32_t htonl(uint32_t hostlong) { uint32_t res; @@ -86,6 +86,6 @@ STIN uint16_t ntohs(uint16_t netshort) { return res; } -#endif /* WIN32 */ +#endif /* defined(WIN32) */ -#endif /* NGHTTP2_NET_H */ +#endif /* !defined(NGHTTP2_NET_H) */ diff --git a/deps/nghttp2/lib/nghttp2_option.h b/deps/nghttp2/lib/nghttp2_option.h index 78fa21e4a77ac8..711185ba2f8e82 100644 --- a/deps/nghttp2/lib/nghttp2_option.h +++ b/deps/nghttp2/lib/nghttp2_option.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -160,4 +160,4 @@ struct nghttp2_option { uint8_t user_recv_ext_types[32]; }; -#endif /* NGHTTP2_OPTION_H */ +#endif /* !defined(NGHTTP2_OPTION_H) */ diff --git a/deps/nghttp2/lib/nghttp2_outbound_item.h b/deps/nghttp2/lib/nghttp2_outbound_item.h index 4e91750088f809..6e8e310cc475dd 100644 --- a/deps/nghttp2/lib/nghttp2_outbound_item.h +++ b/deps/nghttp2/lib/nghttp2_outbound_item.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include #include "nghttp2_frame.h" @@ -186,4 +186,4 @@ void nghttp2_outbound_queue_pop(nghttp2_outbound_queue *q); /* Returns the size of the queue */ #define nghttp2_outbound_queue_size(Q) ((Q)->n) -#endif /* NGHTTP2_OUTBOUND_ITEM_H */ +#endif /* !defined(NGHTTP2_OUTBOUND_ITEM_H) */ diff --git a/deps/nghttp2/lib/nghttp2_pq.h b/deps/nghttp2/lib/nghttp2_pq.h index c8d90ef2cc8f33..5dd863f86ae956 100644 --- a/deps/nghttp2/lib/nghttp2_pq.h +++ b/deps/nghttp2/lib/nghttp2_pq.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include #include "nghttp2_int.h" @@ -121,4 +121,4 @@ int nghttp2_pq_each(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg); */ void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item); -#endif /* NGHTTP2_PQ_H */ +#endif /* !defined(NGHTTP2_PQ_H) */ diff --git a/deps/nghttp2/lib/nghttp2_priority_spec.h b/deps/nghttp2/lib/nghttp2_priority_spec.h index 92ece822a8f257..158e0dcdbe6c0a 100644 --- a/deps/nghttp2/lib/nghttp2_priority_spec.h +++ b/deps/nghttp2/lib/nghttp2_priority_spec.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -39,4 +39,4 @@ */ void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec); -#endif /* NGHTTP2_PRIORITY_SPEC_H */ +#endif /* !defined(NGHTTP2_PRIORITY_SPEC_H) */ diff --git a/deps/nghttp2/lib/nghttp2_queue.h b/deps/nghttp2/lib/nghttp2_queue.h index a06fa6c7a46fc7..c63897c04bef7e 100644 --- a/deps/nghttp2/lib/nghttp2_queue.h +++ b/deps/nghttp2/lib/nghttp2_queue.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include "config.h" -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -48,4 +48,4 @@ void *nghttp2_queue_front(nghttp2_queue *queue); void *nghttp2_queue_back(nghttp2_queue *queue); int nghttp2_queue_empty(nghttp2_queue *queue); -#endif /* NGHTTP2_QUEUE_H */ +#endif /* !defined(NGHTTP2_QUEUE_H) */ diff --git a/deps/nghttp2/lib/nghttp2_ratelim.h b/deps/nghttp2/lib/nghttp2_ratelim.h index 866ed3f00aed4c..d1097f2f81c406 100644 --- a/deps/nghttp2/lib/nghttp2_ratelim.h +++ b/deps/nghttp2/lib/nghttp2_ratelim.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -54,4 +54,4 @@ void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp); succeeds, or -1. */ int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n); -#endif /* NGHTTP2_RATELIM_H */ +#endif /* !defined(NGHTTP2_RATELIM_H) */ diff --git a/deps/nghttp2/lib/nghttp2_rcbuf.h b/deps/nghttp2/lib/nghttp2_rcbuf.h index 6814e709fb4148..ef82e1b3abd744 100644 --- a/deps/nghttp2/lib/nghttp2_rcbuf.h +++ b/deps/nghttp2/lib/nghttp2_rcbuf.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -77,4 +77,4 @@ int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src, */ void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf); -#endif /* NGHTTP2_RCBUF_H */ +#endif /* !defined(NGHTTP2_RCBUF_H) */ diff --git a/deps/nghttp2/lib/nghttp2_session.c b/deps/nghttp2/lib/nghttp2_session.c index a53c7420b36952..1f4ea54c62e23e 100644 --- a/deps/nghttp2/lib/nghttp2_session.c +++ b/deps/nghttp2/lib/nghttp2_session.c @@ -3272,7 +3272,9 @@ static int session_call_on_invalid_header(nghttp2_session *session, session, frame, nv->name->base, nv->name->len, nv->value->base, nv->value->len, nv->flags, session->user_data); } else { - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + /* If both callbacks are not set, the invalid field nv is + ignored. */ + return 0; } if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { @@ -3357,6 +3359,10 @@ static uint32_t get_error_code_from_lib_error_code(int lib_error_code) { case NGHTTP2_ERR_HTTP_HEADER: case NGHTTP2_ERR_HTTP_MESSAGING: return NGHTTP2_PROTOCOL_ERROR; + case NGHTTP2_ERR_INTERNAL: + return NGHTTP2_INTERNAL_ERROR; + case NGHTTP2_ERR_PUSH_CANCEL: + return NGHTTP2_CANCEL; default: return NGHTTP2_INTERNAL_ERROR; } @@ -3408,7 +3414,7 @@ static int session_handle_invalid_stream2(nghttp2_session *session, if (rv != 0) { return rv; } - if (session->callbacks.on_invalid_frame_recv_callback) { + if (frame && session->callbacks.on_invalid_frame_recv_callback) { if (session->callbacks.on_invalid_frame_recv_callback( session, frame, lib_error_code, session->user_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; @@ -3563,7 +3569,29 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, rv2 = session_call_on_invalid_header(session, frame, &nv); if (rv2 == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = NGHTTP2_ERR_HTTP_HEADER; + DEBUGF("recv: HTTP error: type=%u, id=%d, header %.*s: %.*s\n", + frame->hd.type, frame->hd.stream_id, (int)nv.name->len, + nv.name->base, (int)nv.value->len, nv.value->base); + + rv = session_call_error_callback( + session, NGHTTP2_ERR_HTTP_HEADER, + "Invalid HTTP header field was received: frame type: " + "%u, stream: %d, name: [%.*s], value: [%.*s]", + frame->hd.type, frame->hd.stream_id, (int)nv.name->len, + nv.name->base, (int)nv.value->len, nv.value->base); + + if (nghttp2_is_fatal(rv)) { + return rv; + } + + rv = session_handle_invalid_stream2( + session, subject_stream->stream_id, frame, + NGHTTP2_ERR_HTTP_HEADER); + if (nghttp2_is_fatal(rv)) { + return rv; + } + + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } else { if (rv2 != 0) { return rv2; @@ -3603,13 +3631,8 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, return rv; } - rv = - session_handle_invalid_stream2(session, subject_stream->stream_id, - frame, NGHTTP2_ERR_HTTP_HEADER); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + return nghttp2_session_terminate_session(session, + NGHTTP2_PROTOCOL_ERROR); } } if (rv == 0) { @@ -3722,27 +3745,7 @@ static int session_after_header_block_received(nghttp2_session *session) { } } if (rv != 0) { - int32_t stream_id; - - if (frame->hd.type == NGHTTP2_PUSH_PROMISE) { - stream_id = frame->push_promise.promised_stream_id; - } else { - stream_id = frame->hd.stream_id; - } - - rv = session_handle_invalid_stream2(session, stream_id, frame, - NGHTTP2_ERR_HTTP_MESSAGING); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (frame->hd.type == NGHTTP2_HEADERS && - (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); - /* Don't call nghttp2_session_close_stream_if_shut_rdwr - because RST_STREAM has been submitted. */ - } - return 0; + return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR); } } @@ -4078,8 +4081,7 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) { rv = nghttp2_stream_update_remote_initial_window_size( stream, arg->new_window_size, arg->old_window_size); if (rv != 0) { - return nghttp2_session_add_rst_stream(arg->session, stream->stream_id, - NGHTTP2_FLOW_CONTROL_ERROR); + return NGHTTP2_ERR_FLOW_CONTROL; } /* If window size gets positive, push deferred DATA frame to @@ -4105,6 +4107,8 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) { * * NGHTTP2_ERR_NOMEM * Out of memory. + * NGHTTP2_ERR_FLOW_CONTROL + * Window size gets out of range. */ static int session_update_remote_initial_window_size(nghttp2_session *session, @@ -4128,8 +4132,7 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) { rv = nghttp2_stream_update_local_initial_window_size( stream, arg->new_window_size, arg->old_window_size); if (rv != 0) { - return nghttp2_session_add_rst_stream(arg->session, stream->stream_id, - NGHTTP2_FLOW_CONTROL_ERROR); + return NGHTTP2_ERR_FLOW_CONTROL; } if (stream->window_update_queued) { @@ -4163,6 +4166,8 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) { * * NGHTTP2_ERR_NOMEM * Out of memory. + * NGHTTP2_ERR_FLOW_CONTROL + * Window size gets out of range. */ static int session_update_local_initial_window_size(nghttp2_session *session, @@ -4549,9 +4554,9 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session, session->max_incoming_reserved_streams) { /* Currently, client does not retain closed stream, so we don't check NGHTTP2_SHUT_RD condition here. */ - - rv = nghttp2_session_add_rst_stream( - session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL); + rv = session_handle_invalid_stream2(session, + frame->push_promise.promised_stream_id, + NULL, NGHTTP2_ERR_PUSH_CANCEL); if (rv != 0) { return rv; } @@ -4708,8 +4713,9 @@ static int session_on_stream_window_update_received(nghttp2_session *session, } if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment < stream->remote_window_size) { - return session_handle_invalid_stream(session, frame, - NGHTTP2_ERR_FLOW_CONTROL); + return session_handle_invalid_connection( + session, frame, NGHTTP2_ERR_FLOW_CONTROL, + "WINDOW_UPDATE: window size overflow"); } stream->remote_window_size += frame->window_update.window_size_increment; @@ -4939,16 +4945,7 @@ int nghttp2_session_on_data_received(nghttp2_session *session, if (session_enforce_http_messaging(session) && (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { if (nghttp2_http_on_remote_end_stream(stream) != 0) { - rv = nghttp2_session_add_rst_stream(session, stream->stream_id, - NGHTTP2_PROTOCOL_ERROR); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); - /* Don't call nghttp2_session_close_stream_if_shut_rdwr because - RST_STREAM has been submitted. */ - return 0; + return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR); } } @@ -5006,8 +5003,8 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session, rv = adjust_recv_window_size(&stream->recv_window_size, delta_size, stream->local_window_size); if (rv != 0) { - return nghttp2_session_add_rst_stream(session, stream->stream_id, - NGHTTP2_FLOW_CONTROL_ERROR); + return nghttp2_session_terminate_session(session, + NGHTTP2_FLOW_CONTROL_ERROR); } /* We don't have to send WINDOW_UPDATE if the data received is the last chunk in the incoming stream. */ @@ -5590,8 +5587,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = nghttp2_session_add_rst_stream( - session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR); + rv = session_handle_invalid_stream2( + session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL); if (nghttp2_is_fatal(rv)) { return rv; } @@ -5657,7 +5654,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, DEBUGF("recv: WINDOW_UPDATE\n"); break; } -#endif /* DEBUGBUILD */ +#endif /* defined(DEBUGBUILD) */ iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; @@ -5841,6 +5838,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, case NGHTTP2_ALTSVC: if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) == 0) { + /* Receiving too frequent unknown frames is suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; break; @@ -5852,6 +5859,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, iframe->frame.ext.payload = &iframe->ext_frame_payload.altsvc; if (session->server) { + /* Receiving too frequent ALTSVC from client is + suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; break; @@ -5871,6 +5889,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, break; case NGHTTP2_ORIGIN: if (!(session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ORIGIN)) { + /* Receiving too frequent unknown frames is suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; break; @@ -5882,6 +5910,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (session->server || iframe->frame.hd.stream_id || (iframe->frame.hd.flags & 0xf0)) { + /* Receiving too frequent invalid frames is + suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; break; @@ -5908,6 +5947,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, case NGHTTP2_PRIORITY_UPDATE: if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) { + /* Receiving too frequent unknown frames is suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; break; @@ -6055,8 +6104,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = nghttp2_session_add_rst_stream( - session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR); + rv = session_handle_invalid_stream2( + session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6139,9 +6188,9 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = nghttp2_session_add_rst_stream( - session, iframe->frame.push_promise.promised_stream_id, - NGHTTP2_INTERNAL_ERROR); + rv = session_handle_invalid_stream2( + session, iframe->frame.push_promise.promised_stream_id, NULL, + NGHTTP2_ERR_INTERNAL); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6266,7 +6315,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } else { DEBUGF("recv: [IB_IGN_HEADER_BLOCK]\n"); } -#endif /* DEBUGBUILD */ +#endif /* defined(DEBUGBUILD) */ readlen = inbound_frame_payload_readlen(iframe, in, last); @@ -6319,12 +6368,12 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, iframe->payloadleft -= hd_proclen; /* Use promised stream ID for PUSH_PROMISE */ - rv = nghttp2_session_add_rst_stream( + rv = session_handle_invalid_stream2( session, iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE ? iframe->frame.push_promise.promised_stream_id : iframe->frame.hd.stream_id, - NGHTTP2_INTERNAL_ERROR); + NULL, NGHTTP2_ERR_INTERNAL); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6371,6 +6420,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (nghttp2_is_fatal(rv)) { return rv; } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } } session_inbound_frame_reset(session); @@ -6494,7 +6547,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } else { fprintf(stderr, "recv: [IB_IGN_CONTINUATION]\n"); } -#endif /* DEBUGBUILD */ +#endif /* defined(DEBUGBUILD) */ if (++session->num_continuations > session->max_continuations) { return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS; @@ -6596,6 +6649,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (nghttp2_is_fatal(rv)) { return rv; } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } } busy = 1; @@ -6668,6 +6725,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, return rv; } + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + data_readlen = inbound_frame_effective_readlen(iframe, iframe->payloadleft, readlen); @@ -6697,28 +6758,13 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (data_readlen > 0) { if (session_enforce_http_messaging(session)) { if (nghttp2_http_on_data_chunk(stream, (size_t)data_readlen) != 0) { - if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) { - /* Consume all data for connection immediately here */ - rv = session_update_connection_consumed_size( - session, (size_t)data_readlen); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_DATA) { - return (nghttp2_ssize)inlen; - } - } - - rv = nghttp2_session_add_rst_stream( - session, iframe->frame.hd.stream_id, NGHTTP2_PROTOCOL_ERROR); + rv = nghttp2_session_terminate_session(session, + NGHTTP2_PROTOCOL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } - busy = 1; - iframe->state = NGHTTP2_IB_IGN_DATA; - break; + + return (nghttp2_ssize)inlen; } } if (session->callbacks.on_data_chunk_recv_callback) { @@ -6745,6 +6791,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, return rv; } + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + session_inbound_frame_reset(session); break; diff --git a/deps/nghttp2/lib/nghttp2_session.h b/deps/nghttp2/lib/nghttp2_session.h index 25f300d23f131c..edbef80d397123 100644 --- a/deps/nghttp2/lib/nghttp2_session.h +++ b/deps/nghttp2/lib/nghttp2_session.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include #include "nghttp2_map.h" @@ -892,4 +892,4 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session, size_t delta_size, int send_window_update); -#endif /* NGHTTP2_SESSION_H */ +#endif /* !defined(NGHTTP2_SESSION_H) */ diff --git a/deps/nghttp2/lib/nghttp2_stream.h b/deps/nghttp2/lib/nghttp2_stream.h index e73cd283b1dca4..603209ec645f30 100644 --- a/deps/nghttp2/lib/nghttp2_stream.h +++ b/deps/nghttp2/lib/nghttp2_stream.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include #include "nghttp2_outbound_item.h" @@ -294,4 +294,4 @@ void nghttp2_stream_attach_item(nghttp2_stream *stream, */ void nghttp2_stream_detach_item(nghttp2_stream *stream); -#endif /* NGHTTP2_STREAM */ +#endif /* !defined(NGHTTP2_STREAM_H) */ diff --git a/deps/nghttp2/lib/nghttp2_submit.h b/deps/nghttp2/lib/nghttp2_submit.h index 350ee02275902a..decf803db27c0d 100644 --- a/deps/nghttp2/lib/nghttp2_submit.h +++ b/deps/nghttp2/lib/nghttp2_submit.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -37,4 +37,4 @@ int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags, int32_t stream_id, const nghttp2_data_provider_wrap *dpw); -#endif /* NGHTTP2_SUBMIT_H */ +#endif /* !defined(NGHTTP2_SUBMIT_H) */ diff --git a/deps/nghttp2/lib/nghttp2_time.c b/deps/nghttp2/lib/nghttp2_time.c index 148ccfdce81c12..18fd7bcac3771c 100644 --- a/deps/nghttp2/lib/nghttp2_time.c +++ b/deps/nghttp2/lib/nghttp2_time.c @@ -26,7 +26,7 @@ #ifdef HAVE_WINDOWS_H # include -#endif /* HAVE_WINDOWS_H */ +#endif /* defined(HAVE_WINDOWS_H) */ #include @@ -40,12 +40,11 @@ static uint64_t time_now_sec(void) { return (uint64_t)t; } -#endif /* !HAVE_GETTICKCOUNT64 || __CYGWIN__ */ +#endif /* !defined(HAVE_GETTICKCOUNT64) || defined(__CYGWIN__) */ #if defined(HAVE_GETTICKCOUNT64) && !defined(__CYGWIN__) uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; } -#elif defined(HAVE_CLOCK_GETTIME) && defined(HAVE_DECL_CLOCK_MONOTONIC) && \ - HAVE_DECL_CLOCK_MONOTONIC +#elif defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC uint64_t nghttp2_time_now_sec(void) { struct timespec tp; int rv = clock_gettime(CLOCK_MONOTONIC, &tp); @@ -56,8 +55,8 @@ uint64_t nghttp2_time_now_sec(void) { return (uint64_t)tp.tv_sec; } -#else /* (!HAVE_CLOCK_GETTIME || !HAVE_DECL_CLOCK_MONOTONIC) && \ - (!HAVE_GETTICKCOUNT64 || __CYGWIN__)) */ +#else /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) && \ + (!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */ uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); } -#endif /* (!HAVE_CLOCK_GETTIME || !HAVE_DECL_CLOCK_MONOTONIC) && \ - (!HAVE_GETTICKCOUNT64 || __CYGWIN__)) */ +#endif /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) && \ + (!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */ diff --git a/deps/nghttp2/lib/nghttp2_time.h b/deps/nghttp2/lib/nghttp2_time.h index 03c0bbe944ee3b..a91e62ada35e7a 100644 --- a/deps/nghttp2/lib/nghttp2_time.h +++ b/deps/nghttp2/lib/nghttp2_time.h @@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include @@ -35,4 +35,4 @@ timepoint. If it is unable to get seconds, it returns 0. */ uint64_t nghttp2_time_now_sec(void); -#endif /* NGHTTP2_TIME_H */ +#endif /* !defined(NGHTTP2_TIME_H) */ diff --git a/deps/nghttp2/lib/nghttp2_version.c b/deps/nghttp2/lib/nghttp2_version.c index 4211f2cf8f624d..39a49ff351b9ed 100644 --- a/deps/nghttp2/lib/nghttp2_version.c +++ b/deps/nghttp2/lib/nghttp2_version.c @@ -24,7 +24,7 @@ */ #ifdef HAVE_CONFIG_H # include -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include From 1ab27948cf1b7862acac337f4cd498ed6c2e53c9 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sun, 26 Oct 2025 21:32:37 +0100 Subject: [PATCH 2/2] deps: nghttp2: revert 7784fa979d0b This commit reverts "Make error handling robust". Without this revert, we are getting timeouts, crashes, and different error codes in `parallel/test-http2-*`. Refs: https://github.com/nghttp2/nghttp2/commit/7784fa979d0bcf801a35f1afbb25fb048d815cd7 Refs: https://github.com/nodejs/node/issues/60661 --- deps/nghttp2/lib/nghttp2_int.h | 6 +- deps/nghttp2/lib/nghttp2_session.c | 158 +++++++++++++++-------------- 2 files changed, 81 insertions(+), 83 deletions(-) diff --git a/deps/nghttp2/lib/nghttp2_int.h b/deps/nghttp2/lib/nghttp2_int.h index d89cf154543f53..4e3b26860daf07 100644 --- a/deps/nghttp2/lib/nghttp2_int.h +++ b/deps/nghttp2/lib/nghttp2_int.h @@ -52,11 +52,7 @@ typedef enum { * Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke * nghttp2_on_invalid_header_callback. */ - NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106, - /* - * Cancel pushed stream. - */ - NGHTTP2_ERR_PUSH_CANCEL = -107, + NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106 } nghttp2_internal_error; #endif /* !defined(NGHTTP2_INT_H) */ diff --git a/deps/nghttp2/lib/nghttp2_session.c b/deps/nghttp2/lib/nghttp2_session.c index 1f4ea54c62e23e..97d7fda1d295d5 100644 --- a/deps/nghttp2/lib/nghttp2_session.c +++ b/deps/nghttp2/lib/nghttp2_session.c @@ -3272,9 +3272,7 @@ static int session_call_on_invalid_header(nghttp2_session *session, session, frame, nv->name->base, nv->name->len, nv->value->base, nv->value->len, nv->flags, session->user_data); } else { - /* If both callbacks are not set, the invalid field nv is - ignored. */ - return 0; + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { @@ -3359,10 +3357,6 @@ static uint32_t get_error_code_from_lib_error_code(int lib_error_code) { case NGHTTP2_ERR_HTTP_HEADER: case NGHTTP2_ERR_HTTP_MESSAGING: return NGHTTP2_PROTOCOL_ERROR; - case NGHTTP2_ERR_INTERNAL: - return NGHTTP2_INTERNAL_ERROR; - case NGHTTP2_ERR_PUSH_CANCEL: - return NGHTTP2_CANCEL; default: return NGHTTP2_INTERNAL_ERROR; } @@ -3414,7 +3408,7 @@ static int session_handle_invalid_stream2(nghttp2_session *session, if (rv != 0) { return rv; } - if (frame && session->callbacks.on_invalid_frame_recv_callback) { + if (session->callbacks.on_invalid_frame_recv_callback) { if (session->callbacks.on_invalid_frame_recv_callback( session, frame, lib_error_code, session->user_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; @@ -3569,29 +3563,7 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, rv2 = session_call_on_invalid_header(session, frame, &nv); if (rv2 == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - DEBUGF("recv: HTTP error: type=%u, id=%d, header %.*s: %.*s\n", - frame->hd.type, frame->hd.stream_id, (int)nv.name->len, - nv.name->base, (int)nv.value->len, nv.value->base); - - rv = session_call_error_callback( - session, NGHTTP2_ERR_HTTP_HEADER, - "Invalid HTTP header field was received: frame type: " - "%u, stream: %d, name: [%.*s], value: [%.*s]", - frame->hd.type, frame->hd.stream_id, (int)nv.name->len, - nv.name->base, (int)nv.value->len, nv.value->base); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - rv = session_handle_invalid_stream2( - session, subject_stream->stream_id, frame, - NGHTTP2_ERR_HTTP_HEADER); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + rv = NGHTTP2_ERR_HTTP_HEADER; } else { if (rv2 != 0) { return rv2; @@ -3631,8 +3603,13 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, return rv; } - return nghttp2_session_terminate_session(session, - NGHTTP2_PROTOCOL_ERROR); + rv = + session_handle_invalid_stream2(session, subject_stream->stream_id, + frame, NGHTTP2_ERR_HTTP_HEADER); + if (nghttp2_is_fatal(rv)) { + return rv; + } + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } } if (rv == 0) { @@ -3745,7 +3722,27 @@ static int session_after_header_block_received(nghttp2_session *session) { } } if (rv != 0) { - return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR); + int32_t stream_id; + + if (frame->hd.type == NGHTTP2_PUSH_PROMISE) { + stream_id = frame->push_promise.promised_stream_id; + } else { + stream_id = frame->hd.stream_id; + } + + rv = session_handle_invalid_stream2(session, stream_id, frame, + NGHTTP2_ERR_HTTP_MESSAGING); + if (nghttp2_is_fatal(rv)) { + return rv; + } + + if (frame->hd.type == NGHTTP2_HEADERS && + (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { + nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); + /* Don't call nghttp2_session_close_stream_if_shut_rdwr + because RST_STREAM has been submitted. */ + } + return 0; } } @@ -4081,7 +4078,8 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) { rv = nghttp2_stream_update_remote_initial_window_size( stream, arg->new_window_size, arg->old_window_size); if (rv != 0) { - return NGHTTP2_ERR_FLOW_CONTROL; + return nghttp2_session_add_rst_stream(arg->session, stream->stream_id, + NGHTTP2_FLOW_CONTROL_ERROR); } /* If window size gets positive, push deferred DATA frame to @@ -4107,8 +4105,6 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) { * * NGHTTP2_ERR_NOMEM * Out of memory. - * NGHTTP2_ERR_FLOW_CONTROL - * Window size gets out of range. */ static int session_update_remote_initial_window_size(nghttp2_session *session, @@ -4132,7 +4128,8 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) { rv = nghttp2_stream_update_local_initial_window_size( stream, arg->new_window_size, arg->old_window_size); if (rv != 0) { - return NGHTTP2_ERR_FLOW_CONTROL; + return nghttp2_session_add_rst_stream(arg->session, stream->stream_id, + NGHTTP2_FLOW_CONTROL_ERROR); } if (stream->window_update_queued) { @@ -4166,8 +4163,6 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) { * * NGHTTP2_ERR_NOMEM * Out of memory. - * NGHTTP2_ERR_FLOW_CONTROL - * Window size gets out of range. */ static int session_update_local_initial_window_size(nghttp2_session *session, @@ -4554,9 +4549,9 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session, session->max_incoming_reserved_streams) { /* Currently, client does not retain closed stream, so we don't check NGHTTP2_SHUT_RD condition here. */ - rv = session_handle_invalid_stream2(session, - frame->push_promise.promised_stream_id, - NULL, NGHTTP2_ERR_PUSH_CANCEL); + + rv = nghttp2_session_add_rst_stream( + session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL); if (rv != 0) { return rv; } @@ -4713,9 +4708,8 @@ static int session_on_stream_window_update_received(nghttp2_session *session, } if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment < stream->remote_window_size) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_FLOW_CONTROL, - "WINDOW_UPDATE: window size overflow"); + return session_handle_invalid_stream(session, frame, + NGHTTP2_ERR_FLOW_CONTROL); } stream->remote_window_size += frame->window_update.window_size_increment; @@ -4945,7 +4939,16 @@ int nghttp2_session_on_data_received(nghttp2_session *session, if (session_enforce_http_messaging(session) && (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { if (nghttp2_http_on_remote_end_stream(stream) != 0) { - return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR); + rv = nghttp2_session_add_rst_stream(session, stream->stream_id, + NGHTTP2_PROTOCOL_ERROR); + if (nghttp2_is_fatal(rv)) { + return rv; + } + + nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); + /* Don't call nghttp2_session_close_stream_if_shut_rdwr because + RST_STREAM has been submitted. */ + return 0; } } @@ -5003,8 +5006,8 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session, rv = adjust_recv_window_size(&stream->recv_window_size, delta_size, stream->local_window_size); if (rv != 0) { - return nghttp2_session_terminate_session(session, - NGHTTP2_FLOW_CONTROL_ERROR); + return nghttp2_session_add_rst_stream(session, stream->stream_id, + NGHTTP2_FLOW_CONTROL_ERROR); } /* We don't have to send WINDOW_UPDATE if the data received is the last chunk in the incoming stream. */ @@ -5587,8 +5590,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = session_handle_invalid_stream2( - session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL); + rv = nghttp2_session_add_rst_stream( + session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6104,8 +6107,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = session_handle_invalid_stream2( - session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL); + rv = nghttp2_session_add_rst_stream( + session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6188,9 +6191,9 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = session_handle_invalid_stream2( - session, iframe->frame.push_promise.promised_stream_id, NULL, - NGHTTP2_ERR_INTERNAL); + rv = nghttp2_session_add_rst_stream( + session, iframe->frame.push_promise.promised_stream_id, + NGHTTP2_INTERNAL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6368,12 +6371,12 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, iframe->payloadleft -= hd_proclen; /* Use promised stream ID for PUSH_PROMISE */ - rv = session_handle_invalid_stream2( + rv = nghttp2_session_add_rst_stream( session, iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE ? iframe->frame.push_promise.promised_stream_id : iframe->frame.hd.stream_id, - NULL, NGHTTP2_ERR_INTERNAL); + NGHTTP2_INTERNAL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6420,10 +6423,6 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (nghttp2_is_fatal(rv)) { return rv; } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } } session_inbound_frame_reset(session); @@ -6649,10 +6648,6 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (nghttp2_is_fatal(rv)) { return rv; } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } } busy = 1; @@ -6725,10 +6720,6 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, return rv; } - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - data_readlen = inbound_frame_effective_readlen(iframe, iframe->payloadleft, readlen); @@ -6758,13 +6749,28 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (data_readlen > 0) { if (session_enforce_http_messaging(session)) { if (nghttp2_http_on_data_chunk(stream, (size_t)data_readlen) != 0) { - rv = nghttp2_session_terminate_session(session, - NGHTTP2_PROTOCOL_ERROR); + if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) { + /* Consume all data for connection immediately here */ + rv = session_update_connection_consumed_size( + session, (size_t)data_readlen); + + if (nghttp2_is_fatal(rv)) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_DATA) { + return (nghttp2_ssize)inlen; + } + } + + rv = nghttp2_session_add_rst_stream( + session, iframe->frame.hd.stream_id, NGHTTP2_PROTOCOL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } - - return (nghttp2_ssize)inlen; + busy = 1; + iframe->state = NGHTTP2_IB_IGN_DATA; + break; } } if (session->callbacks.on_data_chunk_recv_callback) { @@ -6791,10 +6797,6 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, return rv; } - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - session_inbound_frame_reset(session); break;