Allow NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE return from on_headers_callback

This commit is contained in:
Tatsuhiro Tsujikawa 2014-01-28 01:17:23 +09:00
parent ce434d56a7
commit f308b7b512
2 changed files with 28 additions and 4 deletions

View File

@ -1099,9 +1099,18 @@ typedef int (*nghttp2_on_unknown_frame_recv_callback)
* to produce these parameters, because it may refer to the memory * to produce these parameters, because it may refer to the memory
* region included in the input bytes. * region included in the input bytes.
* *
* Returning :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close
* the stream by issuing RST_STREAM with
* :enum:`NGHTTP2_INTERNAL_ERROR`. In this case,
* :type:`nghttp2_on_end_headers_callback` will not be invoked.
*
* The implementation of this function must return 0 if it * The implementation of this function must return 0 if it
* succeeds. It may return :enum:`NGHTTP2_ERR_PAUSE`. If the other * succeeds. It may return :enum:`NGHTTP2_ERR_PAUSE` or
* nonzero value is returned, it is treated as fatal error and * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. For other critical
* failures, it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If
* the other nonzero value is returned, it is treated as
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
*/ */

View File

@ -1861,7 +1861,8 @@ static int session_call_on_header(nghttp2_session *session,
nv->name, nv->namelen, nv->name, nv->namelen,
nv->value, nv->valuelen, nv->value, nv->valuelen,
session->user_data); session->user_data);
if(rv == NGHTTP2_ERR_PAUSE) { if(rv == NGHTTP2_ERR_PAUSE ||
rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
return rv; return rv;
} }
if(rv != 0) { if(rv != 0) {
@ -1988,7 +1989,8 @@ static ssize_t inflate_header_block(nghttp2_session *session,
*readlen_ptr += rv; *readlen_ptr += rv;
if(call_header_cb && (inflate_flags & NGHTTP2_HD_INFLATE_EMIT)) { if(call_header_cb && (inflate_flags & NGHTTP2_HD_INFLATE_EMIT)) {
rv = session_call_on_header(session, frame, &nv); rv = session_call_on_header(session, frame, &nv);
/* This handles NGHTTP2_ERR_PAUSE as well */ /* This handles NGHTTP2_ERR_PAUSE and
NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE as well */
if(rv != 0) { if(rv != 0) {
return rv; return rv;
} }
@ -3643,6 +3645,19 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
if(rv == NGHTTP2_ERR_PAUSE) { if(rv == NGHTTP2_ERR_PAUSE) {
return in - first; return in - first;
} }
if(rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
/* The application says no more headers. We decompress the
rest of the header block but not invoke
on_header_callback and on_end_headers_callback. */
rv = nghttp2_session_add_rst_stream(session,
iframe->frame.hd.stream_id,
NGHTTP2_INTERNAL_ERROR);
if(nghttp2_is_fatal(rv)) {
return rv;
}
iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
break;
}
if(rv == NGHTTP2_ERR_HEADER_COMP) { if(rv == NGHTTP2_ERR_HEADER_COMP) {
/* GOAWAY is already issued */ /* GOAWAY is already issued */
if(iframe->payloadleft == 0) { if(iframe->payloadleft == 0) {