Send 24 bytes client magic byte string by library
Previously nghttp2_session_send() and nghttp2_session_mem_send() did not send 24 bytes client magic byte string (MAGIC). We made nghttp2_session_recv() and nghttp2_session_mem_recv() process MAGIC by default, so it is natural to make library send MAGIC as well. This commit makes nghttp2_session_send() and nghttp2_session_mem_send() send MAGIC. This commit also replace "connection preface" with "client magic", since we call MAGIC as "connection preface" but it is just a part of connection preface. NGHTTP2_CLIENT_CONNECTION_PREFACE macro was replaced with NGHTTP2_CLIENT_MAGIC. The already deprecated NGHTTP2_CLIENT_CONNECTION_HEADER macro was removed permanently. nghttp2_option_set_no_recv_client_preface() was renamed as nghttp2_option_set_no_recv_client_magic(). NGHTTP2_ERR_BAD_PREFACE was renamed as NGHTTP2_ERR_BAD_CLIENT_MAGIC.
This commit is contained in:
parent
ebf214c8fc
commit
d0c27d5229
|
@ -20,17 +20,15 @@ nghttp2 callback functions directly or indirectly. It will lead to the
|
||||||
crash. You can submit requests or frames in the callbacks then call
|
crash. You can submit requests or frames in the callbacks then call
|
||||||
these functions outside the callbacks.
|
these functions outside the callbacks.
|
||||||
|
|
||||||
Currently, `nghttp2_session_send()` and `nghttp2_session_mem_send()`
|
`nghttp2_session_send()` and `nghttp2_session_mem_send()` send first
|
||||||
do not send client connection preface
|
24 bytes of client magic string (MAGIC)
|
||||||
(:macro:`NGHTTP2_CLIENT_CONNECTION_PREFACE`). The applications are
|
(:macro:`NGHTTP2_CLIENT_MAGIC`) on client configuration. The
|
||||||
responsible to send it before sending any HTTP/2 frames using these
|
applications are responsible to send SETTINGS frame as part of
|
||||||
functions if :type:`nghttp2_session` is configured as client.
|
connection preface using `nghttp2_submit_settings()`. Similarly,
|
||||||
Similarly, `nghttp2_session_recv()` and `nghttp2_session_mem_recv()`
|
`nghttp2_session_recv()` and `nghttp2_session_mem_recv()` consume
|
||||||
do not consume client connection preface unless
|
MAGIC on server configuration unless
|
||||||
`nghttp2_option_set_recv_client_preface()` is used with nonzero option
|
`nghttp2_option_set_no_recv_client_magic()` is used with nonzero
|
||||||
value. The applications are responsible to receive it before calling
|
option value.
|
||||||
these functions if :type:`nghttp2_session` is configured as server and
|
|
||||||
`nghttp2_option_set_recv_client_preface()` is not used.
|
|
||||||
|
|
||||||
.. _http-messaging:
|
.. _http-messaging:
|
||||||
|
|
||||||
|
|
|
@ -184,9 +184,9 @@ its bufferevent, so it closes underlying connection as well. It also
|
||||||
calls `nghttp2_session_del()` to delete nghttp2 session object.
|
calls `nghttp2_session_del()` to delete nghttp2 session object.
|
||||||
|
|
||||||
We begin HTTP/2 communication by sending client connection preface,
|
We begin HTTP/2 communication by sending client connection preface,
|
||||||
which is 24 bytes magic byte sequence
|
which is 24 bytes magic byte string (:macro:`NGHTTP2_CLIENT_MAGIC`)
|
||||||
(:macro:`NGHTTP2_CLIENT_CONNECTION_PREFACE`) and SETTINGS frame. The
|
followed by SETTINGS frame. First 24 bytes magic string is
|
||||||
transmission of client connection header is done in
|
automatically sent by nghttp2 library. We send SETTINGS frame in
|
||||||
``send_client_connection_header()``::
|
``send_client_connection_header()``::
|
||||||
|
|
||||||
static void send_client_connection_header(http2_session_data *session_data) {
|
static void send_client_connection_header(http2_session_data *session_data) {
|
||||||
|
@ -194,8 +194,7 @@ transmission of client connection header is done in
|
||||||
{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100}};
|
{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100}};
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
bufferevent_write(session_data->bev, NGHTTP2_CLIENT_CONNECTION_PREFACE,
|
/* client 24 bytes magic string will be sent by nghttp2 library */
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN);
|
|
||||||
rv = nghttp2_submit_settings(session_data->session, NGHTTP2_FLAG_NONE, iv,
|
rv = nghttp2_submit_settings(session_data->session, NGHTTP2_FLAG_NONE, iv,
|
||||||
ARRLEN(iv));
|
ARRLEN(iv));
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
|
|
|
@ -194,15 +194,8 @@ We initialize a nghttp2 session object which is done in
|
||||||
``initialize_nghttp2_session()``::
|
``initialize_nghttp2_session()``::
|
||||||
|
|
||||||
static void initialize_nghttp2_session(http2_session_data *session_data) {
|
static void initialize_nghttp2_session(http2_session_data *session_data) {
|
||||||
nghttp2_option *option;
|
|
||||||
nghttp2_session_callbacks *callbacks;
|
nghttp2_session_callbacks *callbacks;
|
||||||
|
|
||||||
nghttp2_option_new(&option);
|
|
||||||
|
|
||||||
/* Tells nghttp2_session object that it handles client connection
|
|
||||||
preface */
|
|
||||||
nghttp2_option_set_recv_client_preface(option, 1);
|
|
||||||
|
|
||||||
nghttp2_session_callbacks_new(&callbacks);
|
nghttp2_session_callbacks_new(&callbacks);
|
||||||
|
|
||||||
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
|
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
|
||||||
|
@ -219,20 +212,15 @@ We initialize a nghttp2 session object which is done in
|
||||||
nghttp2_session_callbacks_set_on_begin_headers_callback(
|
nghttp2_session_callbacks_set_on_begin_headers_callback(
|
||||||
callbacks, on_begin_headers_callback);
|
callbacks, on_begin_headers_callback);
|
||||||
|
|
||||||
nghttp2_session_server_new2(&session_data->session, callbacks, session_data,
|
nghttp2_session_server_new(&session_data->session, callbacks, session_data);
|
||||||
option);
|
|
||||||
|
|
||||||
nghttp2_session_callbacks_del(callbacks);
|
nghttp2_session_callbacks_del(callbacks);
|
||||||
nghttp2_option_del(option);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Since we are creating a server and uses options, the nghttp2 session
|
Since we are creating a server and uses options, the nghttp2 session
|
||||||
object is created using `nghttp2_session_server_new2()` function. We
|
object is created using `nghttp2_session_server_new2()` function. We
|
||||||
registers five callbacks for nghttp2 session object. We'll talk about
|
registers five callbacks for nghttp2 session object. We'll talk about
|
||||||
these callbacks later. Our server only speaks HTTP/2. In this case,
|
these callbacks later.
|
||||||
we use `nghttp2_option_set_recv_client_preface()` to make
|
|
||||||
:type:`nghttp2_session` object handle client connection preface, which
|
|
||||||
saves some lines of application code.
|
|
||||||
|
|
||||||
After initialization of the nghttp2 session object, we are going to send
|
After initialization of the nghttp2 session object, we are going to send
|
||||||
a server connection header in ``send_server_connection_header()``::
|
a server connection header in ``send_server_connection_header()``::
|
||||||
|
|
|
@ -528,14 +528,6 @@ static void fetch_uri(const struct URI *uri) {
|
||||||
connection.ssl = ssl;
|
connection.ssl = ssl;
|
||||||
connection.want_io = IO_NONE;
|
connection.want_io = IO_NONE;
|
||||||
|
|
||||||
/* Send connection header in blocking I/O mode */
|
|
||||||
rv = SSL_write(ssl, NGHTTP2_CLIENT_CONNECTION_PREFACE,
|
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN);
|
|
||||||
if (rv <= 0) {
|
|
||||||
dief("SSL_write failed: could not send connection preface",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Here make file descriptor non-block */
|
/* Here make file descriptor non-block */
|
||||||
make_non_block(fd);
|
make_non_block(fd);
|
||||||
set_tcp_nodelay(fd);
|
set_tcp_nodelay(fd);
|
||||||
|
|
|
@ -345,8 +345,7 @@ static void send_client_connection_header(http2_session_data *session_data) {
|
||||||
{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100}};
|
{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100}};
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
bufferevent_write(session_data->bev, NGHTTP2_CLIENT_CONNECTION_PREFACE,
|
/* client 24 bytes magic string will be sent by nghttp2 library */
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN);
|
|
||||||
rv = nghttp2_submit_settings(session_data->session, NGHTTP2_FLAG_NONE, iv,
|
rv = nghttp2_submit_settings(session_data->session, NGHTTP2_FLAG_NONE, iv,
|
||||||
ARRLEN(iv));
|
ARRLEN(iv));
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
|
|
|
@ -194,32 +194,17 @@ typedef struct {
|
||||||
/**
|
/**
|
||||||
* @macro
|
* @macro
|
||||||
*
|
*
|
||||||
* The client connection preface.
|
* The client magic string, which is the first 24 bytes byte string of
|
||||||
|
* client connection preface.
|
||||||
*/
|
*/
|
||||||
#define NGHTTP2_CLIENT_CONNECTION_PREFACE "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
|
#define NGHTTP2_CLIENT_MAGIC "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @macro
|
* @macro
|
||||||
*
|
*
|
||||||
* The length of :macro:`NGHTTP2_CLIENT_CONNECTION_PREFACE`.
|
* The length of :macro:`NGHTTP2_CLIENT_MAGIC`.
|
||||||
*/
|
*/
|
||||||
#define NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN 24
|
#define NGHTTP2_CLIENT_MAGIC_LEN 24
|
||||||
|
|
||||||
/**
|
|
||||||
* @macro
|
|
||||||
*
|
|
||||||
* The client connection header. This macro is obsoleted by
|
|
||||||
* NGHTTP2_CLIENT_CONNECTION_PREFACE.
|
|
||||||
*/
|
|
||||||
#define NGHTTP2_CLIENT_CONNECTION_HEADER NGHTTP2_CLIENT_CONNECTION_PREFACE
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @macro
|
|
||||||
*
|
|
||||||
* The length of :macro:`NGHTTP2_CLIENT_CONNECTION_HEADER`.
|
|
||||||
*/
|
|
||||||
#define NGHTTP2_CLIENT_CONNECTION_HEADER_LEN \
|
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum
|
* @enum
|
||||||
|
@ -397,10 +382,10 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
NGHTTP2_ERR_CALLBACK_FAILURE = -902,
|
NGHTTP2_ERR_CALLBACK_FAILURE = -902,
|
||||||
/**
|
/**
|
||||||
* Invalid connection preface was received and further processing is
|
* Invalid client magic (see :macro:`NGHTTP2_CLIENT_MAGIC`) was
|
||||||
* not possible.
|
* received and further processing is not possible.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_ERR_BAD_PREFACE = -903
|
NGHTTP2_ERR_BAD_CLIENT_MAGIC = -903
|
||||||
} nghttp2_error;
|
} nghttp2_error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1975,25 +1960,22 @@ nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option,
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
* By default, nghttp2 library, if configured as server, requires
|
* By default, nghttp2 library, if configured as server, requires
|
||||||
* first 24 bytes of client connection preface. In most cases, this
|
* first 24 bytes of client magic byte string (MAGIC). In most cases,
|
||||||
* will simplify the implementation of server. But sometimes erver
|
* this will simplify the implementation of server. But sometimes
|
||||||
* may want to detect the application protocol based on first few
|
* server may want to detect the application protocol based on first
|
||||||
* bytes on clear text communication.
|
* few bytes on clear text communication.
|
||||||
*
|
*
|
||||||
* If this option is used with nonzero |val|, nghttp2 library does not
|
* If this option is used with nonzero |val|, nghttp2 library does not
|
||||||
* handle first 24 bytes client connection preface. It still checks
|
* handle MAGIC. It still checks following SETTINGS frame. This
|
||||||
* following SETTINGS frame. This means that applications should deal
|
* means that applications should deal with MAGIC by themselves.
|
||||||
* with 24 bytes connection preface by themselves.
|
|
||||||
*
|
*
|
||||||
* If this option is not used or used with zero value, if client
|
* If this option is not used or used with zero value, if MAGIC does
|
||||||
* connection preface does not match the one
|
* not match :macro:`NGHTTP2_CLIENT_MAGIC`, `nghttp2_session_recv()`
|
||||||
* (:macro:`NGHTTP2_CLIENT_CONNECTION_PREFACE`) in the HTTP/2
|
* and `nghttp2_session_mem_recv()` will return error
|
||||||
* specification, `nghttp2_session_recv()` and
|
* :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal error.
|
||||||
* `nghttp2_session_mem_recv()` will return error
|
|
||||||
* :enum:`NGHTTP2_ERR_BAD_PREFACE`, which is fatal error.
|
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN void
|
NGHTTP2_EXTERN void
|
||||||
nghttp2_option_set_no_recv_client_preface(nghttp2_option *option, int val);
|
nghttp2_option_set_no_recv_client_magic(nghttp2_option *option, int val);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
|
@ -2310,10 +2292,10 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
|
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
|
||||||
* The callback function failed.
|
* The callback function failed.
|
||||||
* :enum:`NGHTTP2_ERR_BAD_PREFACE`
|
* :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`
|
||||||
* Invalid client preface was detected. This error only returns
|
* Invalid client magic was detected. This error only returns
|
||||||
* when |session| was configured as server and
|
* when |session| was configured as server and
|
||||||
* `nghttp2_option_set_no_recv_client_preface()` is not used with
|
* `nghttp2_option_set_no_recv_client_magic()` is not used with
|
||||||
* nonzero value.
|
* nonzero value.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session);
|
NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session);
|
||||||
|
@ -2346,10 +2328,10 @@ NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session);
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
|
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
|
||||||
* The callback function failed.
|
* The callback function failed.
|
||||||
* :enum:`NGHTTP2_ERR_BAD_PREFACE`
|
* :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`
|
||||||
* Invalid client preface was detected. This error only returns
|
* Invalid client magic was detected. This error only returns
|
||||||
* when |session| was configured as server and
|
* when |session| was configured as server and
|
||||||
* `nghttp2_option_set_no_recv_client_preface()` is not used with
|
* `nghttp2_option_set_no_recv_client_magic()` is not used with
|
||||||
* nonzero value.
|
* nonzero value.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
|
NGHTTP2_EXTERN ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
|
||||||
|
|
|
@ -307,8 +307,8 @@ const char *nghttp2_strerror(int error_code) {
|
||||||
return "Out of memory";
|
return "Out of memory";
|
||||||
case NGHTTP2_ERR_CALLBACK_FAILURE:
|
case NGHTTP2_ERR_CALLBACK_FAILURE:
|
||||||
return "The user callback function failed";
|
return "The user callback function failed";
|
||||||
case NGHTTP2_ERR_BAD_PREFACE:
|
case NGHTTP2_ERR_BAD_CLIENT_MAGIC:
|
||||||
return "Received bad connection preface";
|
return "Received bad clinet magic byte string";
|
||||||
default:
|
default:
|
||||||
return "Unknown error code";
|
return "Unknown error code";
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,10 +47,9 @@ void nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option,
|
||||||
option->peer_max_concurrent_streams = val;
|
option->peer_max_concurrent_streams = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_option_set_no_recv_client_preface(nghttp2_option *option,
|
void nghttp2_option_set_no_recv_client_magic(nghttp2_option *option, int val) {
|
||||||
int val) {
|
option->opt_set_mask |= NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC;
|
||||||
option->opt_set_mask |= NGHTTP2_OPT_NO_RECV_CLIENT_PREFACE;
|
option->no_recv_client_magic = val;
|
||||||
option->no_recv_client_preface = val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_option_set_no_http_messaging(nghttp2_option *option, int val) {
|
void nghttp2_option_set_no_http_messaging(nghttp2_option *option, int val) {
|
||||||
|
|
|
@ -57,7 +57,7 @@ typedef enum {
|
||||||
* SETTINGS_MAX_CONCURRENT_STREAMS from the remote endpoint.
|
* SETTINGS_MAX_CONCURRENT_STREAMS from the remote endpoint.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS = 1 << 1,
|
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS = 1 << 1,
|
||||||
NGHTTP2_OPT_NO_RECV_CLIENT_PREFACE = 1 << 2,
|
NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC = 1 << 2,
|
||||||
NGHTTP2_OPT_NO_HTTP_MESSAGING = 1 << 3,
|
NGHTTP2_OPT_NO_HTTP_MESSAGING = 1 << 3,
|
||||||
} nghttp2_option_flag;
|
} nghttp2_option_flag;
|
||||||
|
|
||||||
|
@ -79,9 +79,9 @@ struct nghttp2_option {
|
||||||
*/
|
*/
|
||||||
uint8_t no_auto_window_update;
|
uint8_t no_auto_window_update;
|
||||||
/**
|
/**
|
||||||
* NGHTTP2_OPT_NO_RECV_CLIENT_PREFACE
|
* NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC
|
||||||
*/
|
*/
|
||||||
uint8_t no_recv_client_preface;
|
uint8_t no_recv_client_magic;
|
||||||
/**
|
/**
|
||||||
* NGHTTP2_OPT_NO_HTTP_MESSAGING
|
* NGHTTP2_OPT_NO_HTTP_MESSAGING
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -314,9 +314,9 @@ static void active_outbound_item_reset(nghttp2_active_outbound_item *aob,
|
||||||
aob->state = NGHTTP2_OB_POP_ITEM;
|
aob->state = NGHTTP2_OB_POP_ITEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This global variable exists for tests where we want to disable this
|
/* The global variable for tests where we want to disable strict
|
||||||
check. */
|
preface handling. */
|
||||||
int nghttp2_enable_strict_connection_preface_check = 1;
|
int nghttp2_enable_strict_preface = 1;
|
||||||
|
|
||||||
static int session_new(nghttp2_session **session_ptr,
|
static int session_new(nghttp2_session **session_ptr,
|
||||||
const nghttp2_session_callbacks *callbacks,
|
const nghttp2_session_callbacks *callbacks,
|
||||||
|
@ -417,10 +417,10 @@ static int session_new(nghttp2_session **session_ptr,
|
||||||
option->peer_max_concurrent_streams;
|
option->peer_max_concurrent_streams;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((option->opt_set_mask & NGHTTP2_OPT_NO_RECV_CLIENT_PREFACE) &&
|
if ((option->opt_set_mask & NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC) &&
|
||||||
option->no_recv_client_preface) {
|
option->no_recv_client_magic) {
|
||||||
|
|
||||||
(*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_RECV_CLIENT_PREFACE;
|
(*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((option->opt_set_mask & NGHTTP2_OPT_NO_HTTP_MESSAGING) &&
|
if ((option->opt_set_mask & NGHTTP2_OPT_NO_HTTP_MESSAGING) &&
|
||||||
|
@ -435,17 +435,23 @@ static int session_new(nghttp2_session **session_ptr,
|
||||||
|
|
||||||
session_inbound_frame_reset(*session_ptr);
|
session_inbound_frame_reset(*session_ptr);
|
||||||
|
|
||||||
if (nghttp2_enable_strict_connection_preface_check) {
|
if (nghttp2_enable_strict_preface) {
|
||||||
nghttp2_inbound_frame *iframe = &(*session_ptr)->iframe;
|
nghttp2_inbound_frame *iframe = &(*session_ptr)->iframe;
|
||||||
|
|
||||||
if (server &&
|
if (server &&
|
||||||
((*session_ptr)->opt_flags & NGHTTP2_OPTMASK_NO_RECV_CLIENT_PREFACE) ==
|
((*session_ptr)->opt_flags & NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC) ==
|
||||||
0) {
|
0) {
|
||||||
iframe->state = NGHTTP2_IB_READ_CLIENT_PREFACE;
|
iframe->state = NGHTTP2_IB_READ_CLIENT_MAGIC;
|
||||||
iframe->payloadleft = NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN;
|
iframe->payloadleft = NGHTTP2_CLIENT_MAGIC_LEN;
|
||||||
} else {
|
} else {
|
||||||
iframe->state = NGHTTP2_IB_READ_FIRST_SETTINGS;
|
iframe->state = NGHTTP2_IB_READ_FIRST_SETTINGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!server) {
|
||||||
|
(*session_ptr)->aob.state = NGHTTP2_OB_SEND_CLIENT_MAGIC;
|
||||||
|
nghttp2_bufs_add(&(*session_ptr)->aob.framebufs, NGHTTP2_CLIENT_MAGIC,
|
||||||
|
NGHTTP2_CLIENT_MAGIC_LEN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2979,6 +2985,25 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case NGHTTP2_OB_SEND_CLIENT_MAGIC: {
|
||||||
|
size_t datalen;
|
||||||
|
nghttp2_buf *buf;
|
||||||
|
|
||||||
|
buf = &framebufs->cur->buf;
|
||||||
|
|
||||||
|
if (buf->pos == buf->last) {
|
||||||
|
DEBUGF(fprintf(stderr, "send: end transmission of client magic\n"));
|
||||||
|
active_outbound_item_reset(aob, mem);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data_ptr = buf->pos;
|
||||||
|
datalen = nghttp2_buf_len(buf);
|
||||||
|
|
||||||
|
buf->pos += datalen;
|
||||||
|
|
||||||
|
return datalen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2993,14 +3018,16 @@ ssize_t nghttp2_session_mem_send(nghttp2_session *session,
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have to call session_after_frame_sent1 here to handle stream
|
if (session->aob.item) {
|
||||||
closure upon transmission of frames. Otherwise, END_STREAM may
|
/* We have to call session_after_frame_sent1 here to handle stream
|
||||||
be reached to client before we call nghttp2_session_mem_send
|
closure upon transmission of frames. Otherwise, END_STREAM may
|
||||||
again and we may get exceeding number of incoming streams. */
|
be reached to client before we call nghttp2_session_mem_send
|
||||||
rv = session_after_frame_sent1(session);
|
again and we may get exceeding number of incoming streams. */
|
||||||
if (rv < 0) {
|
rv = session_after_frame_sent1(session);
|
||||||
assert(nghttp2_is_fatal(rv));
|
if (rv < 0) {
|
||||||
return (ssize_t)rv;
|
assert(nghttp2_is_fatal(rv));
|
||||||
|
return (ssize_t)rv;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
|
@ -4907,14 +4934,13 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
switch (iframe->state) {
|
switch (iframe->state) {
|
||||||
case NGHTTP2_IB_READ_CLIENT_PREFACE:
|
case NGHTTP2_IB_READ_CLIENT_MAGIC:
|
||||||
readlen = nghttp2_min(inlen, iframe->payloadleft);
|
readlen = nghttp2_min(inlen, iframe->payloadleft);
|
||||||
|
|
||||||
if (memcmp(NGHTTP2_CLIENT_CONNECTION_PREFACE +
|
if (memcmp(NGHTTP2_CLIENT_MAGIC + NGHTTP2_CLIENT_MAGIC_LEN -
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN -
|
|
||||||
iframe->payloadleft,
|
iframe->payloadleft,
|
||||||
in, readlen) != 0) {
|
in, readlen) != 0) {
|
||||||
return NGHTTP2_ERR_BAD_PREFACE;
|
return NGHTTP2_ERR_BAD_CLIENT_MAGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe->payloadleft -= readlen;
|
iframe->payloadleft -= readlen;
|
||||||
|
|
|
@ -46,14 +46,15 @@
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE = 1 << 0,
|
NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE = 1 << 0,
|
||||||
NGHTTP2_OPTMASK_NO_RECV_CLIENT_PREFACE = 1 << 1,
|
NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC = 1 << 1,
|
||||||
NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2,
|
NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2,
|
||||||
} nghttp2_optmask;
|
} nghttp2_optmask;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NGHTTP2_OB_POP_ITEM,
|
NGHTTP2_OB_POP_ITEM,
|
||||||
NGHTTP2_OB_SEND_DATA,
|
NGHTTP2_OB_SEND_DATA,
|
||||||
NGHTTP2_OB_SEND_NO_COPY
|
NGHTTP2_OB_SEND_NO_COPY,
|
||||||
|
NGHTTP2_OB_SEND_CLIENT_MAGIC
|
||||||
} nghttp2_outbound_state;
|
} nghttp2_outbound_state;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -69,7 +70,7 @@ typedef struct {
|
||||||
/* Internal state when receiving incoming frame */
|
/* Internal state when receiving incoming frame */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* Receiving frame header */
|
/* Receiving frame header */
|
||||||
NGHTTP2_IB_READ_CLIENT_PREFACE,
|
NGHTTP2_IB_READ_CLIENT_MAGIC,
|
||||||
NGHTTP2_IB_READ_FIRST_SETTINGS,
|
NGHTTP2_IB_READ_FIRST_SETTINGS,
|
||||||
NGHTTP2_IB_READ_HEAD,
|
NGHTTP2_IB_READ_HEAD,
|
||||||
NGHTTP2_IB_READ_NBYTE,
|
NGHTTP2_IB_READ_NBYTE,
|
||||||
|
|
|
@ -1477,8 +1477,6 @@ if asyncio:
|
||||||
cnghttp2.NGHTTP2_PROTO_VERSION_ID:
|
cnghttp2.NGHTTP2_PROTO_VERSION_ID:
|
||||||
self.transport.abort()
|
self.transport.abort()
|
||||||
|
|
||||||
# Send preamble
|
|
||||||
self.transport.write(cnghttp2.NGHTTP2_CLIENT_CONNECTION_PREFACE)
|
|
||||||
self.http2 = _HTTP2ClientSessionCore(self.transport)
|
self.http2 = _HTTP2ClientSessionCore(self.transport)
|
||||||
|
|
||||||
# Clear pending requests
|
# Clear pending requests
|
||||||
|
|
|
@ -431,7 +431,7 @@ int Http2Handler::read_clear() {
|
||||||
|
|
||||||
rv = nghttp2_session_mem_recv(session_, buf.data(), nread);
|
rv = nghttp2_session_mem_recv(session_, buf.data(), nread);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
if (rv != NGHTTP2_ERR_BAD_PREFACE) {
|
if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
|
||||||
std::cerr << "nghttp2_session_mem_recv() returned error: "
|
std::cerr << "nghttp2_session_mem_recv() returned error: "
|
||||||
<< nghttp2_strerror(rv) << std::endl;
|
<< nghttp2_strerror(rv) << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -558,7 +558,7 @@ int Http2Handler::read_tls() {
|
||||||
|
|
||||||
rv = nghttp2_session_mem_recv(session_, buf.data(), nread);
|
rv = nghttp2_session_mem_recv(session_, buf.data(), nread);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
if (rv != NGHTTP2_ERR_BAD_PREFACE) {
|
if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
|
||||||
std::cerr << "nghttp2_session_mem_recv() returned error: "
|
std::cerr << "nghttp2_session_mem_recv() returned error: "
|
||||||
<< nghttp2_strerror(rv) << std::endl;
|
<< nghttp2_strerror(rv) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,10 +75,6 @@ void session_impl::connected(tcp::resolver::iterator endpoint_it) {
|
||||||
|
|
||||||
socket().set_option(boost::asio::ip::tcp::no_delay(true));
|
socket().set_option(boost::asio::ip::tcp::no_delay(true));
|
||||||
|
|
||||||
std::copy_n(NGHTTP2_CLIENT_CONNECTION_PREFACE,
|
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN, std::begin(wb_));
|
|
||||||
wblen_ = NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN;
|
|
||||||
|
|
||||||
do_write();
|
do_write();
|
||||||
do_read();
|
do_read();
|
||||||
|
|
||||||
|
|
|
@ -202,12 +202,6 @@ void Http2Session::on_connect() {
|
||||||
extra_connection_window);
|
extra_connection_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &wb = client_->wb;
|
|
||||||
assert(wb.wleft() >= NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN);
|
|
||||||
|
|
||||||
wb.write(NGHTTP2_CLIENT_CONNECTION_PREFACE,
|
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN);
|
|
||||||
|
|
||||||
client_->signal_write();
|
client_->signal_write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -962,9 +962,6 @@ int HttpClient::connection_made() {
|
||||||
request_done(stream_user_data);
|
request_done(stream_user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Send connection header here
|
|
||||||
wb.write(NGHTTP2_CLIENT_CONNECTION_PREFACE,
|
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN);
|
|
||||||
// If upgrade succeeds, the SETTINGS value sent with
|
// If upgrade succeeds, the SETTINGS value sent with
|
||||||
// HTTP2-Settings header field has already been submitted to
|
// HTTP2-Settings header field has already been submitted to
|
||||||
// session object.
|
// session object.
|
||||||
|
|
|
@ -904,7 +904,7 @@ void fill_default_config() {
|
||||||
|
|
||||||
nghttp2_option_new(&mod_config()->http2_option);
|
nghttp2_option_new(&mod_config()->http2_option);
|
||||||
nghttp2_option_set_no_auto_window_update(get_config()->http2_option, 1);
|
nghttp2_option_set_no_auto_window_update(get_config()->http2_option, 1);
|
||||||
nghttp2_option_set_no_recv_client_preface(get_config()->http2_option, 1);
|
nghttp2_option_set_no_recv_client_magic(get_config()->http2_option, 1);
|
||||||
|
|
||||||
nghttp2_option_new(&mod_config()->http2_client_option);
|
nghttp2_option_new(&mod_config()->http2_client_option);
|
||||||
nghttp2_option_set_no_auto_window_update(get_config()->http2_client_option,
|
nghttp2_option_set_no_auto_window_update(get_config()->http2_client_option,
|
||||||
|
|
|
@ -279,8 +279,7 @@ int ClientHandler::upstream_write() {
|
||||||
|
|
||||||
int ClientHandler::upstream_http2_connhd_read() {
|
int ClientHandler::upstream_http2_connhd_read() {
|
||||||
auto nread = std::min(left_connhd_len_, rb_.rleft());
|
auto nread = std::min(left_connhd_len_, rb_.rleft());
|
||||||
if (memcmp(NGHTTP2_CLIENT_CONNECTION_PREFACE +
|
if (memcmp(NGHTTP2_CLIENT_MAGIC + NGHTTP2_CLIENT_MAGIC_LEN - left_connhd_len_,
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN - left_connhd_len_,
|
|
||||||
rb_.pos, nread) != 0) {
|
rb_.pos, nread) != 0) {
|
||||||
// There is no downgrade path here. Just drop the connection.
|
// There is no downgrade path here. Just drop the connection.
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
@ -309,8 +308,7 @@ int ClientHandler::upstream_http2_connhd_read() {
|
||||||
|
|
||||||
int ClientHandler::upstream_http1_connhd_read() {
|
int ClientHandler::upstream_http1_connhd_read() {
|
||||||
auto nread = std::min(left_connhd_len_, rb_.rleft());
|
auto nread = std::min(left_connhd_len_, rb_.rleft());
|
||||||
if (memcmp(NGHTTP2_CLIENT_CONNECTION_PREFACE +
|
if (memcmp(NGHTTP2_CLIENT_MAGIC + NGHTTP2_CLIENT_MAGIC_LEN - left_connhd_len_,
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN - left_connhd_len_,
|
|
||||||
rb_.pos, nread) != 0) {
|
rb_.pos, nread) != 0) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
CLOG(INFO, this) << "This is HTTP/1.1 connection, "
|
CLOG(INFO, this) << "This is HTTP/1.1 connection, "
|
||||||
|
@ -318,7 +316,7 @@ int ClientHandler::upstream_http1_connhd_read() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset header length for later HTTP/2 upgrade
|
// Reset header length for later HTTP/2 upgrade
|
||||||
left_connhd_len_ = NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN;
|
left_connhd_len_ = NGHTTP2_CLIENT_MAGIC_LEN;
|
||||||
on_read_ = &ClientHandler::upstream_read;
|
on_read_ = &ClientHandler::upstream_read;
|
||||||
on_write_ = &ClientHandler::upstream_write;
|
on_write_ = &ClientHandler::upstream_write;
|
||||||
|
|
||||||
|
@ -362,7 +360,7 @@ ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
|
||||||
get_config()->read_burst, writecb, readcb, timeoutcb, this),
|
get_config()->read_burst, writecb, readcb, timeoutcb, this),
|
||||||
ipaddr_(ipaddr), port_(port), worker_(worker),
|
ipaddr_(ipaddr), port_(port), worker_(worker),
|
||||||
http2session_(worker_->next_http2_session()),
|
http2session_(worker_->next_http2_session()),
|
||||||
left_connhd_len_(NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN),
|
left_connhd_len_(NGHTTP2_CLIENT_MAGIC_LEN),
|
||||||
should_close_after_write_(false) {
|
should_close_after_write_(false) {
|
||||||
|
|
||||||
++worker_->get_worker_stat()->num_connections;
|
++worker_->get_worker_stat()->num_connections;
|
||||||
|
|
|
@ -1278,13 +1278,6 @@ int Http2Session::connection_made() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto nwrite = wb_.write(NGHTTP2_CLIENT_CONNECTION_PREFACE,
|
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN);
|
|
||||||
if (nwrite != NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN) {
|
|
||||||
SSLOG(FATAL, this) << "buffer is too small to send connection preface";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto must_terminate = !get_config()->downstream_no_tls &&
|
auto must_terminate = !get_config()->downstream_no_tls &&
|
||||||
!ssl::check_http2_requirement(conn_.tls.ssl);
|
!ssl::check_http2_requirement(conn_.tls.ssl);
|
||||||
|
|
||||||
|
|
|
@ -769,7 +769,7 @@ int Http2Upstream::on_read() {
|
||||||
if (rb->rleft()) {
|
if (rb->rleft()) {
|
||||||
rv = nghttp2_session_mem_recv(session_, rb->pos, rb->rleft());
|
rv = nghttp2_session_mem_recv(session_, rb->pos, rb->rleft());
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
if (rv != NGHTTP2_ERR_BAD_PREFACE) {
|
if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
|
||||||
ULOG(ERROR, this) << "nghttp2_session_recv() returned error: "
|
ULOG(ERROR, this) << "nghttp2_session_recv() returned error: "
|
||||||
<< nghttp2_strerror(rv);
|
<< nghttp2_strerror(rv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#include "nghttp2_helper_test.h"
|
#include "nghttp2_helper_test.h"
|
||||||
#include "nghttp2_buf_test.h"
|
#include "nghttp2_buf_test.h"
|
||||||
|
|
||||||
extern int nghttp2_enable_strict_connection_preface_check;
|
extern int nghttp2_enable_strict_preface;
|
||||||
|
|
||||||
static int init_suite1(void) { return 0; }
|
static int init_suite1(void) { return 0; }
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ int main(int argc _U_, char *argv[] _U_) {
|
||||||
CU_pSuite pSuite = NULL;
|
CU_pSuite pSuite = NULL;
|
||||||
unsigned int num_tests_failed;
|
unsigned int num_tests_failed;
|
||||||
|
|
||||||
nghttp2_enable_strict_connection_preface_check = 0;
|
nghttp2_enable_strict_preface = 0;
|
||||||
|
|
||||||
/* initialize the CUnit test registry */
|
/* initialize the CUnit test registry */
|
||||||
if (CUE_SUCCESS != CU_initialize_registry())
|
if (CUE_SUCCESS != CU_initialize_registry())
|
||||||
|
@ -250,8 +250,8 @@ int main(int argc _U_, char *argv[] _U_) {
|
||||||
test_nghttp2_session_graceful_shutdown) ||
|
test_nghttp2_session_graceful_shutdown) ||
|
||||||
!CU_add_test(pSuite, "session_on_header_temporal_failure",
|
!CU_add_test(pSuite, "session_on_header_temporal_failure",
|
||||||
test_nghttp2_session_on_header_temporal_failure) ||
|
test_nghttp2_session_on_header_temporal_failure) ||
|
||||||
!CU_add_test(pSuite, "session_recv_client_preface",
|
!CU_add_test(pSuite, "session_recv_client_magic",
|
||||||
test_nghttp2_session_recv_client_preface) ||
|
test_nghttp2_session_recv_client_magic) ||
|
||||||
!CU_add_test(pSuite, "session_delete_data_item",
|
!CU_add_test(pSuite, "session_delete_data_item",
|
||||||
test_nghttp2_session_delete_data_item) ||
|
test_nghttp2_session_delete_data_item) ||
|
||||||
!CU_add_test(pSuite, "session_open_idle_stream",
|
!CU_add_test(pSuite, "session_open_idle_stream",
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#include "nghttp2_test_helper.h"
|
#include "nghttp2_test_helper.h"
|
||||||
#include "nghttp2_priority_spec.h"
|
#include "nghttp2_priority_spec.h"
|
||||||
|
|
||||||
extern int nghttp2_enable_strict_connection_preface_check;
|
extern int nghttp2_enable_strict_preface;
|
||||||
|
|
||||||
#define OB_CTRL(ITEM) nghttp2_outbound_item_get_ctrl_frame(ITEM)
|
#define OB_CTRL(ITEM) nghttp2_outbound_item_get_ctrl_frame(ITEM)
|
||||||
#define OB_CTRL_TYPE(ITEM) nghttp2_outbound_item_get_ctrl_frame_type(ITEM)
|
#define OB_CTRL_TYPE(ITEM) nghttp2_outbound_item_get_ctrl_frame_type(ITEM)
|
||||||
|
@ -6722,27 +6722,25 @@ void test_nghttp2_session_on_header_temporal_failure(void) {
|
||||||
nghttp2_session_del(session);
|
nghttp2_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_nghttp2_session_recv_client_preface(void) {
|
void test_nghttp2_session_recv_client_magic(void) {
|
||||||
nghttp2_session *session;
|
nghttp2_session *session;
|
||||||
nghttp2_session_callbacks callbacks;
|
nghttp2_session_callbacks callbacks;
|
||||||
ssize_t rv;
|
ssize_t rv;
|
||||||
nghttp2_frame ping_frame;
|
nghttp2_frame ping_frame;
|
||||||
uint8_t buf[16];
|
uint8_t buf[16];
|
||||||
|
|
||||||
/* enable global nghttp2_enable_strict_connection_preface_check
|
/* enable global nghttp2_enable_strict_preface here */
|
||||||
here */
|
nghttp2_enable_strict_preface = 1;
|
||||||
nghttp2_enable_strict_connection_preface_check = 1;
|
|
||||||
|
|
||||||
memset(&callbacks, 0, sizeof(callbacks));
|
memset(&callbacks, 0, sizeof(callbacks));
|
||||||
|
|
||||||
/* Check success case */
|
/* Check success case */
|
||||||
nghttp2_session_server_new(&session, &callbacks, NULL);
|
nghttp2_session_server_new(&session, &callbacks, NULL);
|
||||||
|
|
||||||
rv = nghttp2_session_mem_recv(
|
rv = nghttp2_session_mem_recv(session, (const uint8_t *)NGHTTP2_CLIENT_MAGIC,
|
||||||
session, (const uint8_t *)NGHTTP2_CLIENT_CONNECTION_PREFACE,
|
NGHTTP2_CLIENT_MAGIC_LEN);
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN);
|
|
||||||
|
|
||||||
CU_ASSERT(rv == NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN);
|
CU_ASSERT(rv == NGHTTP2_CLIENT_MAGIC_LEN);
|
||||||
CU_ASSERT(NGHTTP2_IB_READ_FIRST_SETTINGS == session->iframe.state);
|
CU_ASSERT(NGHTTP2_IB_READ_FIRST_SETTINGS == session->iframe.state);
|
||||||
|
|
||||||
/* Receiving PING is error because we want SETTINGS. */
|
/* Receiving PING is error because we want SETTINGS. */
|
||||||
|
@ -6762,24 +6760,22 @@ void test_nghttp2_session_recv_client_preface(void) {
|
||||||
/* Check bad case */
|
/* Check bad case */
|
||||||
nghttp2_session_server_new(&session, &callbacks, NULL);
|
nghttp2_session_server_new(&session, &callbacks, NULL);
|
||||||
|
|
||||||
/* Feed preface with one byte less */
|
/* Feed magic with one byte less */
|
||||||
rv = nghttp2_session_mem_recv(
|
rv = nghttp2_session_mem_recv(session, (const uint8_t *)NGHTTP2_CLIENT_MAGIC,
|
||||||
session, (const uint8_t *)NGHTTP2_CLIENT_CONNECTION_PREFACE,
|
NGHTTP2_CLIENT_MAGIC_LEN - 1);
|
||||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN - 1);
|
|
||||||
|
|
||||||
CU_ASSERT(rv == NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN - 1);
|
CU_ASSERT(rv == NGHTTP2_CLIENT_MAGIC_LEN - 1);
|
||||||
CU_ASSERT(NGHTTP2_IB_READ_CLIENT_PREFACE == session->iframe.state);
|
CU_ASSERT(NGHTTP2_IB_READ_CLIENT_MAGIC == session->iframe.state);
|
||||||
CU_ASSERT(1 == session->iframe.payloadleft);
|
CU_ASSERT(1 == session->iframe.payloadleft);
|
||||||
|
|
||||||
rv = nghttp2_session_mem_recv(session, (const uint8_t *)"\0", 1);
|
rv = nghttp2_session_mem_recv(session, (const uint8_t *)"\0", 1);
|
||||||
|
|
||||||
CU_ASSERT(NGHTTP2_ERR_BAD_PREFACE == rv);
|
CU_ASSERT(NGHTTP2_ERR_BAD_CLIENT_MAGIC == rv);
|
||||||
|
|
||||||
nghttp2_session_del(session);
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
/* disable global nghttp2_enable_strict_connection_preface_check
|
/* disable global nghttp2_enable_strict_preface here */
|
||||||
here */
|
nghttp2_enable_strict_preface = 0;
|
||||||
nghttp2_enable_strict_connection_preface_check = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_nghttp2_session_delete_data_item(void) {
|
void test_nghttp2_session_delete_data_item(void) {
|
||||||
|
|
|
@ -118,7 +118,7 @@ void test_nghttp2_session_detach_idle_stream(void);
|
||||||
void test_nghttp2_session_large_dep_tree(void);
|
void test_nghttp2_session_large_dep_tree(void);
|
||||||
void test_nghttp2_session_graceful_shutdown(void);
|
void test_nghttp2_session_graceful_shutdown(void);
|
||||||
void test_nghttp2_session_on_header_temporal_failure(void);
|
void test_nghttp2_session_on_header_temporal_failure(void);
|
||||||
void test_nghttp2_session_recv_client_preface(void);
|
void test_nghttp2_session_recv_client_magic(void);
|
||||||
void test_nghttp2_session_delete_data_item(void);
|
void test_nghttp2_session_delete_data_item(void);
|
||||||
void test_nghttp2_session_open_idle_stream(void);
|
void test_nghttp2_session_open_idle_stream(void);
|
||||||
void test_nghttp2_session_cancel_reserved_remote(void);
|
void test_nghttp2_session_cancel_reserved_remote(void);
|
||||||
|
|
Loading…
Reference in New Issue