Add nghttp2_option_set_no_http_messaging() API function

This API function with nonzero |val| parameter disables HTTP Messaging
validation in nghttp2 library, so that application can use nghttp2
library for non-HTTP use.
This commit is contained in:
Tatsuhiro Tsujikawa 2015-02-20 23:26:56 +09:00
parent b3846d6c27
commit e45c523dc7
5 changed files with 43 additions and 16 deletions

View File

@ -42,7 +42,8 @@ Everything described in that section is not validated however. We
briefly describe what the library does in this area. In the following
description, without loss of generality we omit CONTINUATION frame
since they must follow HEADERS frame and are processed atomically. In
other words, they are just one big HEADERS frame.
other words, they are just one big HEADERS frame. To disable these
validations, use `nghttp2_option_set_no_http_messaging()`.
For HTTP request, including those carried by PUSH_PROMISE, HTTP
message starts with one HEADERS frame containing request headers. It
@ -72,6 +73,10 @@ field-value production rules described in `RFC 7230, section
3.2. <https://tools.ietf.org/html/rfc7230#section-3.2>`_.
Additionally, all field name must be lower cased.
With the above validations, nghttp2 library guarantees that header
field name passed to `nghttp2_on_header_callback()` is not empty.
Also required pseudo headers are all present and not empty.
nghttp2 enforces "Content-Length" validation as well. All request or
response headers must not contain more than one "Content-Length"
header field. If "Content-Length" header field is present, it must be

View File

@ -1408,21 +1408,14 @@ typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session,
* :type:`nghttp2_on_frame_recv_callback` for the |frame| will not be
* invoked.
*
* The |name| may be ``NULL`` if the |namelen| is 0. The same thing
* can be said about the |value|.
* The |value| may be ``NULL`` if the |valuelen| is 0.
*
* Please note that nghttp2 library does not perform any validity
* check against the |name| and the |value|. For example, the
* |namelen| could be 0, and/or the |value| contains ``0x0a`` or
* ``0x0d``. The application must check them if it matters. The
* helper function `nghttp2_check_header_name()` and
* `nghttp2_check_header_value()` provide simple validation against
* HTTP2 header field construction rule.
*
* HTTP/2 specification requires that pseudo header fields (header
* field starting with ':') must appear in front of regular header
* fields. The library does not validate this requirement. The
* application must check them if it matters.
* Please note that unless `nghttp2_option_set_no_http_messaging()` is
* used, nghttp2 library does perform validation against the |name|
* and the |value| using `nghttp2_check_header_name()` and
* `nghttp2_check_header_value()`. In addition to this, nghttp2
* performs vaidation based on HTTP Messaging rule, which is briefly
* explained in `HTTP Messaging`_ section.
*
* If the application uses `nghttp2_session_mem_recv()`, it can return
* :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
@ -1890,6 +1883,18 @@ void nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option,
*/
void nghttp2_option_set_recv_client_preface(nghttp2_option *option, int val);
/**
* @function
*
* By default, nghttp2 library enforces subset of HTTP Messaging rules
* described in `HTTP/2 specification, section 8
* <https://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-8>`_.
* See `HTTP Messaging`_ section for details. For those applications
* who use nghttp2 library as non-HTTP use, give nonzero to |val| to
* disable this enforcement.
*/
void nghttp2_option_set_no_http_messaging(nghttp2_option *option, int val);
/**
* @function
*

View File

@ -51,3 +51,8 @@ void nghttp2_option_set_recv_client_preface(nghttp2_option *option, int val) {
option->opt_set_mask |= NGHTTP2_OPT_RECV_CLIENT_PREFACE;
option->recv_client_preface = val;
}
void nghttp2_option_set_no_http_messaging(nghttp2_option *option, int val) {
option->opt_set_mask |= NGHTTP2_OPT_NO_HTTP_MESSAGING;
option->no_http_messaging = val;
}

View File

@ -58,6 +58,7 @@ typedef enum {
*/
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS = 1 << 1,
NGHTTP2_OPT_RECV_CLIENT_PREFACE = 1 << 2,
NGHTTP2_OPT_NO_HTTP_MESSAGING = 1 << 3,
} nghttp2_option_flag;
/**
@ -81,6 +82,10 @@ struct nghttp2_option {
* NGHTTP2_OPT_RECV_CLIENT_PREFACE
*/
uint8_t recv_client_preface;
/**
* NGHTTP2_OPT_NO_HTTP_MESSAGING
*/
uint8_t no_http_messaging;
};
#endif /* NGHTTP2_OPTION_H */

View File

@ -414,10 +414,17 @@ static int session_new(nghttp2_session **session_ptr,
option->peer_max_concurrent_streams;
}
if (option->opt_set_mask & NGHTTP2_OPT_RECV_CLIENT_PREFACE) {
if ((option->opt_set_mask & NGHTTP2_OPT_RECV_CLIENT_PREFACE) &&
option->recv_client_preface) {
(*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_RECV_CLIENT_PREFACE;
}
if ((option->opt_set_mask & NGHTTP2_OPT_NO_HTTP_MESSAGING) &&
option->no_http_messaging) {
(*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_HTTP_MESSAGING;
}
}
(*session_ptr)->callbacks = *callbacks;