Update doc

This commit is contained in:
Tatsuhiro Tsujikawa 2014-01-18 00:17:15 +09:00
parent 16bc89e743
commit 8ce9042a25
10 changed files with 321 additions and 222 deletions

View File

@ -836,13 +836,12 @@ Types (structs, unions and typedefs)
If the application uses `nghttp2_session_mem_recv()`, it can return If the application uses `nghttp2_session_mem_recv()`, it can return
:macro:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()` :macro:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
return without processing further input bytes. The *frame* return without processing further input bytes. The memory by
parameter is retained until `nghttp2_session_continue()` is pointed by the *data* is retained until
`nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is
called. The application must retain the input bytes which was used called. The application must retain the input bytes which was used
to produce the *frame* parameter, because it may refer to the to produce the *data* parameter, because it may refer to the memory
memory region included in the input bytes. The application which region included in the input bytes.
returns :macro:`NGHTTP2_ERR_PAUSE` must call
`nghttp2_session_continue()` before `nghttp2_session_mem_recv()`.
The implementation of this function must return 0 if it The implementation of this function must return 0 if it
succeeds. If nonzero is returned, it is treated as fatal error and succeeds. If nonzero is returned, it is treated as fatal error and
@ -1006,14 +1005,12 @@ Types (structs, unions and typedefs)
If the application uses `nghttp2_session_mem_recv()`, it can return If the application uses `nghttp2_session_mem_recv()`, it can return
:macro:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()` :macro:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
return without processing further input bytes. The *frame*, return without processing further input bytes. The memory pointed
*name*, *namelen*, *value* and *valuelen* parameters are retained by *frame*, *name* and *value* parameters are retained until
until `nghttp2_session_continue()` is called. The application must `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is
retain the input bytes which was used to produce the *frame* called. The application must retain the input bytes which was used
parameter, because it may refer to the memory region included in to produce these parameters, because it may refer to the memory
the input bytes. The application which returns region included in the input bytes.
:macro:`NGHTTP2_ERR_PAUSE` must call `nghttp2_session_continue()`
before `nghttp2_session_mem_recv()`.
The implementation of this function must return 0 if it The implementation of this function must return 0 if it
succeeds. It may return :macro:`NGHTTP2_ERR_PAUSE`. If the other succeeds. It may return :macro:`NGHTTP2_ERR_PAUSE`. If the other
@ -1340,7 +1337,7 @@ Functions
In the current implementation, this function always tries to In the current implementation, this function always tries to
processes all input data unless either an error occurs or processes all input data unless either an error occurs or
:macro:`NGHTTP2_ERR_PAUSE` is returned from :macro:`NGHTTP2_ERR_PAUSE` is returned from
:member:`nghttp2_session_callbacks.on_frame_recv_callback` or :member:`nghttp2_session_callbacks.on_header_callback` or
:member:`nghttp2_session_callbacks.on_data_chunk_recv_callback`. :member:`nghttp2_session_callbacks.on_data_chunk_recv_callback`.
If :macro:`NGHTTP2_ERR_PAUSE` is used, the return value includes the If :macro:`NGHTTP2_ERR_PAUSE` is used, the return value includes the
number of bytes which was used to produce the data or frame for the number of bytes which was used to produce the data or frame for the
@ -1354,31 +1351,6 @@ Functions
:macro:`NGHTTP2_ERR_CALLBACK_FAILURE` :macro:`NGHTTP2_ERR_CALLBACK_FAILURE`
The callback function failed. The callback function failed.
.. function:: int nghttp2_session_continue(nghttp2_session *session)
Perform post-processing after `nghttp2_session_mem_recv()` was
paused by :macro:`NGHTTP2_ERR_PAUSE` from
:member:`nghttp2_session_callbacks.on_frame_recv_callback` or
:member:`nghttp2_session_callbacks.on_data_chunk_recv_callback`.
This function frees resources associated with paused frames. It
may also call additional callbacks, such as
:member:`nghttp2_session_callbacks.on_stream_close_callback`.
If this function succeeds, the application can call
`nghttp2_session_mem_recv()` again.
This function returns 0 if it succeeds, or one of the following
negative error codes:
:macro:`NGHTTP2_ERR_NOMEM`
Out of memory.
:macro:`NGHTTP2_ERR_CALLBACK_FAILURE`
The callback function failed.
.. function:: int nghttp2_session_resume_data(nghttp2_session *session, int32_t stream_id) .. function:: int nghttp2_session_resume_data(nghttp2_session *session, int32_t stream_id)
@ -1642,8 +1614,7 @@ Functions
negative error codes: negative error codes:
:macro:`NGHTTP2_ERR_INVALID_ARGUMENT` :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
The *pri* is invalid; or the *nva* includes empty name, or name The *pri* is invalid
which contains invalid characters.
:macro:`NGHTTP2_ERR_NOMEM` :macro:`NGHTTP2_ERR_NOMEM`
Out of memory. Out of memory.
@ -1681,9 +1652,6 @@ Functions
This function returns 0 if it succeeds, or one of the following This function returns 0 if it succeeds, or one of the following
negative error codes: negative error codes:
:macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
The *nva* includes empty name or name which contains invalid
characters.
:macro:`NGHTTP2_ERR_NOMEM` :macro:`NGHTTP2_ERR_NOMEM`
Out of memory. Out of memory.
@ -1733,8 +1701,7 @@ Functions
negative error codes: negative error codes:
:macro:`NGHTTP2_ERR_INVALID_ARGUMENT` :macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
The *pri* is invalid; or the *nva* includes empty name, or name The *pri* is invalid
which contains invalid characters.
:macro:`NGHTTP2_ERR_NOMEM` :macro:`NGHTTP2_ERR_NOMEM`
Out of memory. Out of memory.
@ -1855,9 +1822,6 @@ Functions
This function returns 0 if it succeeds, or one of the following This function returns 0 if it succeeds, or one of the following
negative error codes: negative error codes:
:macro:`NGHTTP2_ERR_INVALID_ARGUMENT`
The *nva* includes empty name, or name which contains invalid
characters.
:macro:`NGHTTP2_ERR_NOMEM` :macro:`NGHTTP2_ERR_NOMEM`
Out of memory. Out of memory.

View File

@ -163,11 +163,13 @@ finished successfully. We first initialize nghttp2 session object in
callbacks.on_frame_recv_callback = on_frame_recv_callback; callbacks.on_frame_recv_callback = on_frame_recv_callback;
callbacks.on_data_chunk_recv_callback = on_data_chunk_recv_callback; callbacks.on_data_chunk_recv_callback = on_data_chunk_recv_callback;
callbacks.on_stream_close_callback = on_stream_close_callback; callbacks.on_stream_close_callback = on_stream_close_callback;
callbacks.on_header_callback = on_header_callback;
callbacks.on_end_headers_callback = on_end_headers_callback;
nghttp2_session_client_new(&session_data->session, &callbacks, session_data); nghttp2_session_client_new(&session_data->session, &callbacks, session_data);
} }
Since we are creating client, we use `nghttp2_session_client_new()` to Since we are creating client, we use `nghttp2_session_client_new()` to
initialize nghttp2 session object. We setup 5 callbacks for the initialize nghttp2 session object. We setup 7 callbacks for the
nghttp2 session. We'll explain these callbacks later. nghttp2 session. We'll explain these callbacks later.
The `delete_http2_session_data()` destroys ``session_data`` and frees The `delete_http2_session_data()` destroys ``session_data`` and frees
@ -395,9 +397,8 @@ received from the remote peer::
case NGHTTP2_HEADERS: case NGHTTP2_HEADERS:
if(frame->headers.cat == NGHTTP2_HCAT_RESPONSE && if(frame->headers.cat == NGHTTP2_HCAT_RESPONSE &&
session_data->stream_data->stream_id == frame->hd.stream_id) { session_data->stream_data->stream_id == frame->hd.stream_id) {
/* Print response headers for the initiated request. */ fprintf(stderr, "Response headers for stream ID=%d:\n",
fprintf(stderr, "Response headers:\n"); frame->hd.stream_id);
print_headers(stderr, frame->headers.nva, frame->headers.nvlen);
} }
break; break;
} }
@ -409,6 +410,53 @@ HEADERS. We check te frame type and its category (it should be
:macro:`NGHTTP2_HCAT_RESPONSE` for HTTP response HEADERS). Also check :macro:`NGHTTP2_HCAT_RESPONSE` for HTTP response HEADERS). Also check
its stream ID. its stream ID.
Each request header name/value pair is emitted via
``on_header_callback`` function::
static int on_header_callback(nghttp2_session *session,
const nghttp2_frame *frame,
const uint8_t *name, size_t namelen,
const uint8_t *value, size_t valuelen,
void *user_data)
{
http2_session_data *session_data = (http2_session_data*)user_data;
switch(frame->hd.type) {
case NGHTTP2_HEADERS:
if(frame->headers.cat == NGHTTP2_HCAT_RESPONSE &&
session_data->stream_data->stream_id == frame->hd.stream_id) {
/* Print response headers for the initiated request. */
print_header(stderr, name, namelen, value, valuelen);
break;
}
}
return 0;
}
In this turotial, we just print the name/value pair.
After all name/value pairs are emitted for a frame,
``on_end_headers_callback`` function is called::
static int on_end_headers_callback(nghttp2_session *session,
const nghttp2_frame *frame,
nghttp2_error_code error_code,
void *user_data)
{
http2_session_data *session_data = (http2_session_data*)user_data;
switch(frame->hd.type) {
case NGHTTP2_HEADERS:
if(frame->headers.cat == NGHTTP2_HCAT_RESPONSE &&
session_data->stream_data->stream_id == frame->hd.stream_id) {
fprintf(stderr, "All headers received with error_code=%d\n", error_code);
}
break;
}
return 0;
}
This callback may be called prematurely because of errors (e.g.,
header decompression failure) which is indicated by ``error_code``.
The ``on_data_chunk_recv_callback()`` function is invoked when a chunk The ``on_data_chunk_recv_callback()`` function is invoked when a chunk
of data is received from the remote peer:: of data is received from the remote peer::

View File

@ -243,11 +243,12 @@ We initialize nghttp2 session object which is done in
callbacks.on_frame_recv_callback = on_frame_recv_callback; callbacks.on_frame_recv_callback = on_frame_recv_callback;
callbacks.on_request_recv_callback = on_request_recv_callback; callbacks.on_request_recv_callback = on_request_recv_callback;
callbacks.on_stream_close_callback = on_stream_close_callback; callbacks.on_stream_close_callback = on_stream_close_callback;
callbacks.on_header_callback = on_header_callback;
nghttp2_session_server_new(&session_data->session, &callbacks, session_data); nghttp2_session_server_new(&session_data->session, &callbacks, session_data);
} }
Since we are creating server, nghttp2 session object is created using Since we are creating server, nghttp2 session object is created using
`nghttp2_session_server_new()` function. We registers 4 callbacks to `nghttp2_session_server_new()` function. We registers 5 callbacks to
nghttp2 session object. We'll talk about these callbacks later. nghttp2 session object. We'll talk about these callbacks later.
After initialization of nghttp2 session object, we are going to send After initialization of nghttp2 session object, we are going to send
@ -421,8 +422,6 @@ received from the remote peer::
{ {
http2_session_data *session_data = (http2_session_data*)user_data; http2_session_data *session_data = (http2_session_data*)user_data;
http2_stream_data *stream_data; http2_stream_data *stream_data;
size_t i;
const char PATH[] = ":path";
switch(frame->hd.type) { switch(frame->hd.type) {
case NGHTTP2_HEADERS: case NGHTTP2_HEADERS:
if(frame->headers.cat != NGHTTP2_HCAT_REQUEST) { if(frame->headers.cat != NGHTTP2_HCAT_REQUEST) {
@ -431,16 +430,6 @@ received from the remote peer::
stream_data = create_http2_stream_data(session_data, frame->hd.stream_id); stream_data = create_http2_stream_data(session_data, frame->hd.stream_id);
nghttp2_session_set_stream_user_data(session, frame->hd.stream_id, nghttp2_session_set_stream_user_data(session, frame->hd.stream_id,
stream_data); stream_data);
for(i = 0; i < frame->headers.nvlen; ++i) {
nghttp2_nv *nv = &frame->headers.nva[i];
if(nv->namelen == sizeof(PATH) - 1 &&
memcmp(PATH, nv->name, nv->namelen) == 0) {
size_t j;
for(j = 0; j < nv->valuelen && nv->value[j] != '?'; ++j);
stream_data->request_path = percent_decode(nv->value, j);
break;
}
}
break; break;
default: default:
break; break;
@ -457,13 +446,47 @@ in nghttp2 session object using `nghttp2_set_stream_user_data()` in
order to get the object without searching through doubly linked list. order to get the object without searching through doubly linked list.
In this example server, we want to serve files relative to the current In this example server, we want to serve files relative to the current
working directory the program was invoked. We search ``:path`` header working directory the program was invoked. Each header name/value pair
field in request headers and keep the requested path in is emitted via ``on_header_callback`` function, which is called after
``http2_stream_data`` object. In this example program, we ignore ``on_frame_recv_callback()``::
``:method`` header field and always treat the request as GET request.
It is ok for the server to start sending response in this callback. In static int on_header_callback(nghttp2_session *session,
this example, we defer it to ``on_request_recv_callback()`` function. const nghttp2_frame *frame,
const uint8_t *name, size_t namelen,
const uint8_t *value, size_t valuelen,
void *user_data)
{
http2_stream_data *stream_data;
const char PATH[] = ":path";
switch(frame->hd.type) {
case NGHTTP2_HEADERS:
if(frame->headers.cat != NGHTTP2_HCAT_REQUEST) {
break;
}
stream_data = nghttp2_session_get_stream_user_data(session,
frame->hd.stream_id);
if(stream_data->request_path) {
break;
}
if(namelen == sizeof(PATH) - 1 && memcmp(PATH, name, namelen) == 0) {
size_t j;
for(j = 0; j < valuelen && value[j] != '?'; ++j);
stream_data->request_path = percent_decode(value, j);
}
break;
}
return 0;
}
We search ``:path`` header field in request headers and keep the
requested path in ``http2_stream_data`` object. In this example
program, we ignore ``:method`` header field and always treat the
request as GET request.
It is ok for the server to start sending response in this callback (or
in `nghttp2_on_end_headers_callback()`, which is not used in this
tutorial). In this example, we defer it to
``on_request_recv_callback()`` function.
The ``on_request_recv_callback()`` function is invoked when all HTTP The ``on_request_recv_callback()`` function is invoked when all HTTP
request, including entity body, was received:: request, including entity body, was received::

View File

@ -1343,13 +1343,12 @@ third argument passed in to the call to
<a class="reference internal" href="#nghttp2_session_client_new" title="nghttp2_session_client_new"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_client_new()</span></tt></a> or <a class="reference internal" href="#nghttp2_session_server_new" title="nghttp2_session_server_new"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_server_new()</span></tt></a>.</p> <a class="reference internal" href="#nghttp2_session_client_new" title="nghttp2_session_client_new"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_client_new()</span></tt></a> or <a class="reference internal" href="#nghttp2_session_server_new" title="nghttp2_session_server_new"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_server_new()</span></tt></a>.</p>
<p>If the application uses <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a>, it can return <p>If the application uses <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a>, it can return
<a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a> to make <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a> <a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a> to make <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a>
return without processing further input bytes. The <em>frame</em> return without processing further input bytes. The memory by
parameter is retained until <a class="reference internal" href="#nghttp2_session_continue" title="nghttp2_session_continue"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_continue()</span></tt></a> is pointed by the <em>data</em> is retained until
<a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a> or <a class="reference internal" href="#nghttp2_session_recv" title="nghttp2_session_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_recv()</span></tt></a> is
called. The application must retain the input bytes which was used called. The application must retain the input bytes which was used
to produce the <em>frame</em> parameter, because it may refer to the to produce the <em>data</em> parameter, because it may refer to the memory
memory region included in the input bytes. The application which region included in the input bytes.</p>
returns <a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a> must call
<a class="reference internal" href="#nghttp2_session_continue" title="nghttp2_session_continue"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_continue()</span></tt></a> before <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a>.</p>
<p>The implementation of this function must return 0 if it <p>The implementation of this function must return 0 if it
succeeds. If nonzero is returned, it is treated as fatal error and succeeds. If nonzero is returned, it is treated as fatal error and
<a class="reference internal" href="#nghttp2_session_recv" title="nghttp2_session_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_recv()</span></tt></a> and <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a> functions <a class="reference internal" href="#nghttp2_session_recv" title="nghttp2_session_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_recv()</span></tt></a> and <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a> functions
@ -1511,14 +1510,12 @@ application returns nonzero value from this callback.</p>
can be said about the <em>value</em>.</p> can be said about the <em>value</em>.</p>
<p>If the application uses <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a>, it can return <p>If the application uses <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a>, it can return
<a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a> to make <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a> <a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a> to make <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a>
return without processing further input bytes. The <em>frame</em>, return without processing further input bytes. The memory pointed
<em>name</em>, <em>namelen</em>, <em>value</em> and <em>valuelen</em> parameters are retained by <em>frame</em>, <em>name</em> and <em>value</em> parameters are retained until
until <a class="reference internal" href="#nghttp2_session_continue" title="nghttp2_session_continue"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_continue()</span></tt></a> is called. The application must <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a> or <a class="reference internal" href="#nghttp2_session_recv" title="nghttp2_session_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_recv()</span></tt></a> is
retain the input bytes which was used to produce the <em>frame</em> called. The application must retain the input bytes which was used
parameter, because it may refer to the memory region included in to produce these parameters, because it may refer to the memory
the input bytes. The application which returns region included in the input bytes.</p>
<a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a> must call <a class="reference internal" href="#nghttp2_session_continue" title="nghttp2_session_continue"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_continue()</span></tt></a>
before <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a>.</p>
<p>The implementation of this function must return 0 if it <p>The implementation of this function must return 0 if it
succeeds. It may return <a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a>. If the other succeeds. It may return <a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a>. If the other
nonzero value is returned, it is treated as fatal error and nonzero value is returned, it is treated as fatal error and
@ -1901,7 +1898,7 @@ other callbacks are called in the same way as they are in
<p>In the current implementation, this function always tries to <p>In the current implementation, this function always tries to
processes all input data unless either an error occurs or processes all input data unless either an error occurs or
<a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a> is returned from <a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a> is returned from
<a class="reference internal" href="#nghttp2_session_callbacks.on_frame_recv_callback" title="nghttp2_session_callbacks.on_frame_recv_callback"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_session_callbacks.on_frame_recv_callback</span></tt></a> or <a class="reference internal" href="#nghttp2_session_callbacks.on_header_callback" title="nghttp2_session_callbacks.on_header_callback"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_session_callbacks.on_header_callback</span></tt></a> or
<a class="reference internal" href="#nghttp2_session_callbacks.on_data_chunk_recv_callback" title="nghttp2_session_callbacks.on_data_chunk_recv_callback"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_session_callbacks.on_data_chunk_recv_callback</span></tt></a>. <a class="reference internal" href="#nghttp2_session_callbacks.on_data_chunk_recv_callback" title="nghttp2_session_callbacks.on_data_chunk_recv_callback"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_session_callbacks.on_data_chunk_recv_callback</span></tt></a>.
If <a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a> is used, the return value includes the If <a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a> is used, the return value includes the
number of bytes which was used to produce the data or frame for the number of bytes which was used to produce the data or frame for the
@ -1916,28 +1913,6 @@ following negative error codes:</p>
</dl> </dl>
</dd></dl> </dd></dl>
<dl class="function">
<dt id="nghttp2_session_continue">
int <tt class="descname">nghttp2_session_continue</tt><big>(</big><a class="reference internal" href="#nghttp2_session" title="nghttp2_session">nghttp2_session</a><em>&nbsp;*session</em><big>)</big><a class="headerlink" href="#nghttp2_session_continue" title="Permalink to this definition"></a></dt>
<dd><p>Perform post-processing after <a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a> was
paused by <a class="reference internal" href="#NGHTTP2_ERR_PAUSE" title="NGHTTP2_ERR_PAUSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PAUSE</span></tt></a> from
<a class="reference internal" href="#nghttp2_session_callbacks.on_frame_recv_callback" title="nghttp2_session_callbacks.on_frame_recv_callback"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_session_callbacks.on_frame_recv_callback</span></tt></a> or
<a class="reference internal" href="#nghttp2_session_callbacks.on_data_chunk_recv_callback" title="nghttp2_session_callbacks.on_data_chunk_recv_callback"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_session_callbacks.on_data_chunk_recv_callback</span></tt></a>.</p>
<p>This function frees resources associated with paused frames. It
may also call additional callbacks, such as
<a class="reference internal" href="#nghttp2_session_callbacks.on_stream_close_callback" title="nghttp2_session_callbacks.on_stream_close_callback"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_session_callbacks.on_stream_close_callback</span></tt></a>.</p>
<p>If this function succeeds, the application can call
<a class="reference internal" href="#nghttp2_session_mem_recv" title="nghttp2_session_mem_recv"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_mem_recv()</span></tt></a> again.</p>
<p>This function returns 0 if it succeeds, or one of the following
negative error codes:</p>
<dl class="docutils">
<dt><a class="reference internal" href="#NGHTTP2_ERR_NOMEM" title="NGHTTP2_ERR_NOMEM"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_NOMEM</span></tt></a></dt>
<dd>Out of memory.</dd>
<dt><a class="reference internal" href="#NGHTTP2_ERR_CALLBACK_FAILURE" title="NGHTTP2_ERR_CALLBACK_FAILURE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_CALLBACK_FAILURE</span></tt></a></dt>
<dd>The callback function failed.</dd>
</dl>
</dd></dl>
<dl class="function"> <dl class="function">
<dt id="nghttp2_session_resume_data"> <dt id="nghttp2_session_resume_data">
int <tt class="descname">nghttp2_session_resume_data</tt><big>(</big><a class="reference internal" href="#nghttp2_session" title="nghttp2_session">nghttp2_session</a><em>&nbsp;*session</em>, int32_t<em>&nbsp;stream_id</em><big>)</big><a class="headerlink" href="#nghttp2_session_resume_data" title="Permalink to this definition"></a></dt> int <tt class="descname">nghttp2_session_resume_data</tt><big>(</big><a class="reference internal" href="#nghttp2_session" title="nghttp2_session">nghttp2_session</a><em>&nbsp;*session</em>, int32_t<em>&nbsp;stream_id</em><big>)</big><a class="headerlink" href="#nghttp2_session_resume_data" title="Permalink to this definition"></a></dt>
@ -2194,8 +2169,7 @@ the stream is already opened,
negative error codes:</p> negative error codes:</p>
<dl class="docutils"> <dl class="docutils">
<dt><a class="reference internal" href="#NGHTTP2_ERR_INVALID_ARGUMENT" title="NGHTTP2_ERR_INVALID_ARGUMENT"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_INVALID_ARGUMENT</span></tt></a></dt> <dt><a class="reference internal" href="#NGHTTP2_ERR_INVALID_ARGUMENT" title="NGHTTP2_ERR_INVALID_ARGUMENT"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_INVALID_ARGUMENT</span></tt></a></dt>
<dd>The <em>pri</em> is invalid; or the <em>nva</em> includes empty name, or name <dd>The <em>pri</em> is invalid</dd>
which contains invalid characters.</dd>
<dt><a class="reference internal" href="#NGHTTP2_ERR_NOMEM" title="NGHTTP2_ERR_NOMEM"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_NOMEM</span></tt></a></dt> <dt><a class="reference internal" href="#NGHTTP2_ERR_NOMEM" title="NGHTTP2_ERR_NOMEM"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_NOMEM</span></tt></a></dt>
<dd>Out of memory.</dd> <dd>Out of memory.</dd>
</dl> </dl>
@ -2229,9 +2203,6 @@ must be reserved using <a class="reference internal" href="#nghttp2_submit_push_
<p>This function returns 0 if it succeeds, or one of the following <p>This function returns 0 if it succeeds, or one of the following
negative error codes:</p> negative error codes:</p>
<dl class="docutils"> <dl class="docutils">
<dt><a class="reference internal" href="#NGHTTP2_ERR_INVALID_ARGUMENT" title="NGHTTP2_ERR_INVALID_ARGUMENT"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_INVALID_ARGUMENT</span></tt></a></dt>
<dd>The <em>nva</em> includes empty name or name which contains invalid
characters.</dd>
<dt><a class="reference internal" href="#NGHTTP2_ERR_NOMEM" title="NGHTTP2_ERR_NOMEM"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_NOMEM</span></tt></a></dt> <dt><a class="reference internal" href="#NGHTTP2_ERR_NOMEM" title="NGHTTP2_ERR_NOMEM"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_NOMEM</span></tt></a></dt>
<dd>Out of memory.</dd> <dd>Out of memory.</dd>
</dl> </dl>
@ -2276,8 +2247,7 @@ specify flags directly. For usual HTTP request,
negative error codes:</p> negative error codes:</p>
<dl class="docutils"> <dl class="docutils">
<dt><a class="reference internal" href="#NGHTTP2_ERR_INVALID_ARGUMENT" title="NGHTTP2_ERR_INVALID_ARGUMENT"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_INVALID_ARGUMENT</span></tt></a></dt> <dt><a class="reference internal" href="#NGHTTP2_ERR_INVALID_ARGUMENT" title="NGHTTP2_ERR_INVALID_ARGUMENT"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_INVALID_ARGUMENT</span></tt></a></dt>
<dd>The <em>pri</em> is invalid; or the <em>nva</em> includes empty name, or name <dd>The <em>pri</em> is invalid</dd>
which contains invalid characters.</dd>
<dt><a class="reference internal" href="#NGHTTP2_ERR_NOMEM" title="NGHTTP2_ERR_NOMEM"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_NOMEM</span></tt></a></dt> <dt><a class="reference internal" href="#NGHTTP2_ERR_NOMEM" title="NGHTTP2_ERR_NOMEM"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_NOMEM</span></tt></a></dt>
<dd>Out of memory.</dd> <dd>Out of memory.</dd>
</dl> </dl>
@ -2391,9 +2361,6 @@ server. But in normal HTTP usage, the server may treat it error.</p>
<p>This function returns 0 if it succeeds, or one of the following <p>This function returns 0 if it succeeds, or one of the following
negative error codes:</p> negative error codes:</p>
<dl class="docutils"> <dl class="docutils">
<dt><a class="reference internal" href="#NGHTTP2_ERR_INVALID_ARGUMENT" title="NGHTTP2_ERR_INVALID_ARGUMENT"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_INVALID_ARGUMENT</span></tt></a></dt>
<dd>The <em>nva</em> includes empty name, or name which contains invalid
characters.</dd>
<dt><a class="reference internal" href="#NGHTTP2_ERR_NOMEM" title="NGHTTP2_ERR_NOMEM"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_NOMEM</span></tt></a></dt> <dt><a class="reference internal" href="#NGHTTP2_ERR_NOMEM" title="NGHTTP2_ERR_NOMEM"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_NOMEM</span></tt></a></dt>
<dd>Out of memory.</dd> <dd>Out of memory.</dd>
</dl> </dl>

View File

@ -614,12 +614,12 @@
<dt><a href="apiref.html#nghttp2_on_frame_not_send_callback">nghttp2_on_frame_not_send_callback (C type)</a> <dt><a href="apiref.html#nghttp2_on_frame_not_send_callback">nghttp2_on_frame_not_send_callback (C type)</a>
</dt> </dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="apiref.html#nghttp2_on_frame_recv_callback">nghttp2_on_frame_recv_callback (C type)</a> <dt><a href="apiref.html#nghttp2_on_frame_recv_callback">nghttp2_on_frame_recv_callback (C type)</a>
</dt> </dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="apiref.html#nghttp2_on_frame_recv_parse_error_callback">nghttp2_on_frame_recv_parse_error_callback (C type)</a> <dt><a href="apiref.html#nghttp2_on_frame_recv_parse_error_callback">nghttp2_on_frame_recv_parse_error_callback (C type)</a>
</dt> </dt>
@ -869,10 +869,6 @@
</dt> </dt>
<dt><a href="apiref.html#nghttp2_session_continue">nghttp2_session_continue (C function)</a>
</dt>
<dt><a href="apiref.html#nghttp2_session_del">nghttp2_session_del (C function)</a> <dt><a href="apiref.html#nghttp2_session_del">nghttp2_session_del (C function)</a>
</dt> </dt>

View File

@ -1051,13 +1051,12 @@
<span class="cm"> *</span> <span class="cm"> *</span>
<span class="cm"> * If the application uses `nghttp2_session_mem_recv()`, it can return</span> <span class="cm"> * If the application uses `nghttp2_session_mem_recv()`, it can return</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`</span> <span class="cm"> * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`</span>
<span class="cm"> * return without processing further input bytes. The |frame|</span> <span class="cm"> * return without processing further input bytes. The memory by</span>
<span class="cm"> * parameter is retained until `nghttp2_session_continue()` is</span> <span class="cm"> * pointed by the |data| is retained until</span>
<span class="cm"> * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is</span>
<span class="cm"> * called. The application must retain the input bytes which was used</span> <span class="cm"> * called. The application must retain the input bytes which was used</span>
<span class="cm"> * to produce the |frame| parameter, because it may refer to the</span> <span class="cm"> * to produce the |data| parameter, because it may refer to the memory</span>
<span class="cm"> * memory region included in the input bytes. The application which</span> <span class="cm"> * region included in the input bytes.</span>
<span class="cm"> * returns :enum:`NGHTTP2_ERR_PAUSE` must call</span>
<span class="cm"> * `nghttp2_session_continue()` before `nghttp2_session_mem_recv()`.</span>
<span class="cm"> *</span> <span class="cm"> *</span>
<span class="cm"> * The implementation of this function must return 0 if it</span> <span class="cm"> * The implementation of this function must return 0 if it</span>
<span class="cm"> * succeeds. If nonzero is returned, it is treated as fatal error and</span> <span class="cm"> * succeeds. If nonzero is returned, it is treated as fatal error and</span>
@ -1262,14 +1261,12 @@
<span class="cm"> *</span> <span class="cm"> *</span>
<span class="cm"> * If the application uses `nghttp2_session_mem_recv()`, it can return</span> <span class="cm"> * If the application uses `nghttp2_session_mem_recv()`, it can return</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`</span> <span class="cm"> * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`</span>
<span class="cm"> * return without processing further input bytes. The |frame|,</span> <span class="cm"> * return without processing further input bytes. The memory pointed</span>
<span class="cm"> * |name|, |namelen|, |value| and |valuelen| parameters are retained</span> <span class="cm"> * by |frame|, |name| and |value| parameters are retained until</span>
<span class="cm"> * until `nghttp2_session_continue()` is called. The application must</span> <span class="cm"> * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is</span>
<span class="cm"> * retain the input bytes which was used to produce the |frame|</span> <span class="cm"> * called. The application must retain the input bytes which was used</span>
<span class="cm"> * parameter, because it may refer to the memory region included in</span> <span class="cm"> * to produce these parameters, because it may refer to the memory</span>
<span class="cm"> * the input bytes. The application which returns</span> <span class="cm"> * region included in the input bytes.</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_PAUSE` must call `nghttp2_session_continue()`</span>
<span class="cm"> * before `nghttp2_session_mem_recv()`.</span>
<span class="cm"> *</span> <span class="cm"> *</span>
<span class="cm"> * The implementation of this function must return 0 if it</span> <span class="cm"> * The implementation of this function must return 0 if it</span>
<span class="cm"> * succeeds. It may return :enum:`NGHTTP2_ERR_PAUSE`. If the other</span> <span class="cm"> * succeeds. It may return :enum:`NGHTTP2_ERR_PAUSE`. If the other</span>
@ -1686,7 +1683,7 @@
<span class="cm"> * In the current implementation, this function always tries to</span> <span class="cm"> * In the current implementation, this function always tries to</span>
<span class="cm"> * processes all input data unless either an error occurs or</span> <span class="cm"> * processes all input data unless either an error occurs or</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_PAUSE` is returned from</span> <span class="cm"> * :enum:`NGHTTP2_ERR_PAUSE` is returned from</span>
<span class="cm"> * :member:`nghttp2_session_callbacks.on_frame_recv_callback` or</span> <span class="cm"> * :member:`nghttp2_session_callbacks.on_header_callback` or</span>
<span class="cm"> * :member:`nghttp2_session_callbacks.on_data_chunk_recv_callback`.</span> <span class="cm"> * :member:`nghttp2_session_callbacks.on_data_chunk_recv_callback`.</span>
<span class="cm"> * If :enum:`NGHTTP2_ERR_PAUSE` is used, the return value includes the</span> <span class="cm"> * If :enum:`NGHTTP2_ERR_PAUSE` is used, the return value includes the</span>
<span class="cm"> * number of bytes which was used to produce the data or frame for the</span> <span class="cm"> * number of bytes which was used to produce the data or frame for the</span>
@ -1703,33 +1700,6 @@
<span class="kt">ssize_t</span> <span class="nf">nghttp2_session_mem_recv</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span> <span class="kt">ssize_t</span> <span class="nf">nghttp2_session_mem_recv</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span>
<span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">in</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">inlen</span><span class="p">);</span> <span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">in</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">inlen</span><span class="p">);</span>
<span class="cm">/**</span>
<span class="cm"> * @function</span>
<span class="cm"> *</span>
<span class="cm"> * Perform post-processing after `nghttp2_session_mem_recv()` was</span>
<span class="cm"> * paused by :enum:`NGHTTP2_ERR_PAUSE` from</span>
<span class="cm"> * :member:`nghttp2_session_callbacks.on_frame_recv_callback` or</span>
<span class="cm"> * :member:`nghttp2_session_callbacks.on_data_chunk_recv_callback`.</span>
<span class="cm"> *</span>
<span class="cm"> * This function frees resources associated with paused frames. It</span>
<span class="cm"> * may also call additional callbacks, such as</span>
<span class="cm"> * :member:`nghttp2_session_callbacks.on_stream_close_callback`.</span>
<span class="cm"> *</span>
<span class="cm"> * If this function succeeds, the application can call</span>
<span class="cm"> * `nghttp2_session_mem_recv()` again.</span>
<span class="cm"> *</span>
<span class="cm"> * This function returns 0 if it succeeds, or one of the following</span>
<span class="cm"> * negative error codes:</span>
<span class="cm"> *</span>
<span class="cm"> *</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_NOMEM`</span>
<span class="cm"> * Out of memory.</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`</span>
<span class="cm"> * The callback function failed.</span>
<span class="cm"> *</span>
<span class="cm"> */</span>
<span class="kt">int</span> <span class="nf">nghttp2_session_continue</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">);</span>
<span class="cm">/**</span> <span class="cm">/**</span>
<span class="cm"> * @function</span> <span class="cm"> * @function</span>
<span class="cm"> *</span> <span class="cm"> *</span>
@ -2035,8 +2005,7 @@
<span class="cm"> * negative error codes:</span> <span class="cm"> * negative error codes:</span>
<span class="cm"> *</span> <span class="cm"> *</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`</span> <span class="cm"> * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`</span>
<span class="cm"> * The |pri| is invalid; or the |nva| includes empty name, or name</span> <span class="cm"> * The |pri| is invalid</span>
<span class="cm"> * which contains invalid characters.</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_NOMEM`</span> <span class="cm"> * :enum:`NGHTTP2_ERR_NOMEM`</span>
<span class="cm"> * Out of memory.</span> <span class="cm"> * Out of memory.</span>
<span class="cm"> */</span> <span class="cm"> */</span>
@ -2079,9 +2048,6 @@
<span class="cm"> * This function returns 0 if it succeeds, or one of the following</span> <span class="cm"> * This function returns 0 if it succeeds, or one of the following</span>
<span class="cm"> * negative error codes:</span> <span class="cm"> * negative error codes:</span>
<span class="cm"> *</span> <span class="cm"> *</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`</span>
<span class="cm"> * The |nva| includes empty name or name which contains invalid</span>
<span class="cm"> * characters.</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_NOMEM`</span> <span class="cm"> * :enum:`NGHTTP2_ERR_NOMEM`</span>
<span class="cm"> * Out of memory.</span> <span class="cm"> * Out of memory.</span>
<span class="cm"> */</span> <span class="cm"> */</span>
@ -2136,8 +2102,7 @@
<span class="cm"> * negative error codes:</span> <span class="cm"> * negative error codes:</span>
<span class="cm"> *</span> <span class="cm"> *</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`</span> <span class="cm"> * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`</span>
<span class="cm"> * The |pri| is invalid; or the |nva| includes empty name, or name</span> <span class="cm"> * The |pri| is invalid</span>
<span class="cm"> * which contains invalid characters.</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_NOMEM`</span> <span class="cm"> * :enum:`NGHTTP2_ERR_NOMEM`</span>
<span class="cm"> * Out of memory.</span> <span class="cm"> * Out of memory.</span>
<span class="cm"> */</span> <span class="cm"> */</span>
@ -2278,9 +2243,6 @@
<span class="cm"> * This function returns 0 if it succeeds, or one of the following</span> <span class="cm"> * This function returns 0 if it succeeds, or one of the following</span>
<span class="cm"> * negative error codes:</span> <span class="cm"> * negative error codes:</span>
<span class="cm"> *</span> <span class="cm"> *</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`</span>
<span class="cm"> * The |nva| includes empty name, or name which contains invalid</span>
<span class="cm"> * characters.</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_NOMEM`</span> <span class="cm"> * :enum:`NGHTTP2_ERR_NOMEM`</span>
<span class="cm"> * Out of memory.</span> <span class="cm"> * Out of memory.</span>
<span class="cm"> */</span> <span class="cm"> */</span>

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -292,12 +292,14 @@ finished successfully. We first initialize nghttp2 session object in
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_frame_recv_callback</span> <span class="o">=</span> <span class="n">on_frame_recv_callback</span><span class="p">;</span> <span class="n">callbacks</span><span class="p">.</span><span class="n">on_frame_recv_callback</span> <span class="o">=</span> <span class="n">on_frame_recv_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_data_chunk_recv_callback</span> <span class="o">=</span> <span class="n">on_data_chunk_recv_callback</span><span class="p">;</span> <span class="n">callbacks</span><span class="p">.</span><span class="n">on_data_chunk_recv_callback</span> <span class="o">=</span> <span class="n">on_data_chunk_recv_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_stream_close_callback</span> <span class="o">=</span> <span class="n">on_stream_close_callback</span><span class="p">;</span> <span class="n">callbacks</span><span class="p">.</span><span class="n">on_stream_close_callback</span> <span class="o">=</span> <span class="n">on_stream_close_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_header_callback</span> <span class="o">=</span> <span class="n">on_header_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_end_headers_callback</span> <span class="o">=</span> <span class="n">on_end_headers_callback</span><span class="p">;</span>
<span class="n">nghttp2_session_client_new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">session_data</span><span class="o">-&gt;</span><span class="n">session</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">callbacks</span><span class="p">,</span> <span class="n">session_data</span><span class="p">);</span> <span class="n">nghttp2_session_client_new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">session_data</span><span class="o">-&gt;</span><span class="n">session</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">callbacks</span><span class="p">,</span> <span class="n">session_data</span><span class="p">);</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</div> </div>
<p>Since we are creating client, we use <a class="reference internal" href="apiref.html#nghttp2_session_client_new" title="nghttp2_session_client_new"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_client_new()</span></tt></a> to <p>Since we are creating client, we use <a class="reference internal" href="apiref.html#nghttp2_session_client_new" title="nghttp2_session_client_new"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_client_new()</span></tt></a> to
initialize nghttp2 session object. We setup 5 callbacks for the initialize nghttp2 session object. We setup 7 callbacks for the
nghttp2 session. We&#8217;ll explain these callbacks later.</p> nghttp2 session. We&#8217;ll explain these callbacks later.</p>
<p>The <tt class="xref c c-func docutils literal"><span class="pre">delete_http2_session_data()</span></tt> destroys <tt class="docutils literal"><span class="pre">session_data</span></tt> and frees <p>The <tt class="xref c c-func docutils literal"><span class="pre">delete_http2_session_data()</span></tt> destroys <tt class="docutils literal"><span class="pre">session_data</span></tt> and frees
its bufferevent, so it closes underlying connection as well. It also its bufferevent, so it closes underlying connection as well. It also
@ -516,9 +518,8 @@ received from the remote peer:</p>
<span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>: <span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>:
<span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">==</span> <span class="n">NGHTTP2_HCAT_RESPONSE</span> <span class="o">&amp;&amp;</span> <span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">==</span> <span class="n">NGHTTP2_HCAT_RESPONSE</span> <span class="o">&amp;&amp;</span>
<span class="n">session_data</span><span class="o">-&gt;</span><span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">stream_id</span> <span class="o">==</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">)</span> <span class="p">{</span> <span class="n">session_data</span><span class="o">-&gt;</span><span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">stream_id</span> <span class="o">==</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">)</span> <span class="p">{</span>
<span class="cm">/* Print response headers for the initiated request. */</span> <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Response headers for stream ID=%d:</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Response headers:</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">);</span>
<span class="n">print_headers</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">nva</span><span class="p">,</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">nvlen</span><span class="p">);</span>
<span class="p">}</span> <span class="p">}</span>
<span class="k">break</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span> <span class="p">}</span>
@ -530,6 +531,51 @@ received from the remote peer:</p>
HEADERS. We check te frame type and its category (it should be HEADERS. We check te frame type and its category (it should be
<a class="reference internal" href="apiref.html#NGHTTP2_HCAT_RESPONSE" title="NGHTTP2_HCAT_RESPONSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_HCAT_RESPONSE</span></tt></a> for HTTP response HEADERS). Also check <a class="reference internal" href="apiref.html#NGHTTP2_HCAT_RESPONSE" title="NGHTTP2_HCAT_RESPONSE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_HCAT_RESPONSE</span></tt></a> for HTTP response HEADERS). Also check
its stream ID.</p> its stream ID.</p>
<p>Each request header name/value pair is emitted via
<tt class="docutils literal"><span class="pre">on_header_callback</span></tt> function:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">int</span> <span class="nf">on_header_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_frame</span> <span class="o">*</span><span class="n">frame</span><span class="p">,</span>
<span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">name</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">namelen</span><span class="p">,</span>
<span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">value</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">valuelen</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">user_data</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">http2_session_data</span> <span class="o">*</span><span class="n">session_data</span> <span class="o">=</span> <span class="p">(</span><span class="n">http2_session_data</span><span class="o">*</span><span class="p">)</span><span class="n">user_data</span><span class="p">;</span>
<span class="k">switch</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>:
<span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">==</span> <span class="n">NGHTTP2_HCAT_RESPONSE</span> <span class="o">&amp;&amp;</span>
<span class="n">session_data</span><span class="o">-&gt;</span><span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">stream_id</span> <span class="o">==</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">)</span> <span class="p">{</span>
<span class="cm">/* Print response headers for the initiated request. */</span>
<span class="n">print_header</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">namelen</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">valuelen</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In this turotial, we just print the name/value pair.</p>
<p>After all name/value pairs are emitted for a frame,
<tt class="docutils literal"><span class="pre">on_end_headers_callback</span></tt> function is called:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">int</span> <span class="nf">on_end_headers_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_frame</span> <span class="o">*</span><span class="n">frame</span><span class="p">,</span>
<span class="n">nghttp2_error_code</span> <span class="n">error_code</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">user_data</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">http2_session_data</span> <span class="o">*</span><span class="n">session_data</span> <span class="o">=</span> <span class="p">(</span><span class="n">http2_session_data</span><span class="o">*</span><span class="p">)</span><span class="n">user_data</span><span class="p">;</span>
<span class="k">switch</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>:
<span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">==</span> <span class="n">NGHTTP2_HCAT_RESPONSE</span> <span class="o">&amp;&amp;</span>
<span class="n">session_data</span><span class="o">-&gt;</span><span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">stream_id</span> <span class="o">==</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">)</span> <span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;All headers received with error_code=%d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">error_code</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>This callback may be called prematurely because of errors (e.g.,
header decompression failure) which is indicated by <tt class="docutils literal"><span class="pre">error_code</span></tt>.</p>
<p>The <tt class="docutils literal"><span class="pre">on_data_chunk_recv_callback()</span></tt> function is invoked when a chunk <p>The <tt class="docutils literal"><span class="pre">on_data_chunk_recv_callback()</span></tt> function is invoked when a chunk
of data is received from the remote peer:</p> of data is received from the remote peer:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">int</span> <span class="nf">on_data_chunk_recv_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">flags</span><span class="p">,</span> <div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">int</span> <span class="nf">on_data_chunk_recv_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span> <span class="kt">uint8_t</span> <span class="n">flags</span><span class="p">,</span>
@ -733,6 +779,16 @@ here.</p>
<span class="n">free</span><span class="p">(</span><span class="n">session_data</span><span class="p">);</span> <span class="n">free</span><span class="p">(</span><span class="n">session_data</span><span class="p">);</span>
<span class="p">}</span> <span class="p">}</span>
<span class="k">static</span> <span class="kt">void</span> <span class="nf">print_header</span><span class="p">(</span><span class="kt">FILE</span> <span class="o">*</span><span class="n">f</span><span class="p">,</span>
<span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">name</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">namelen</span><span class="p">,</span>
<span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">value</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">valuelen</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">fwrite</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">namelen</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">f</span><span class="p">);</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s">&quot;: &quot;</span><span class="p">);</span>
<span class="n">fwrite</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">valuelen</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">f</span><span class="p">);</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Print HTTP headers to |f|. Please note that this function does not</span> <span class="cm">/* Print HTTP headers to |f|. Please note that this function does not</span>
<span class="cm"> take into account that header name and value are sequence of</span> <span class="cm"> take into account that header name and value are sequence of</span>
<span class="cm"> octets, therefore they may contain non-printable characters. */</span> <span class="cm"> octets, therefore they may contain non-printable characters. */</span>
@ -740,12 +796,11 @@ here.</p>
<span class="p">{</span> <span class="p">{</span>
<span class="kt">size_t</span> <span class="n">i</span><span class="p">;</span> <span class="kt">size_t</span> <span class="n">i</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">nvlen</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span><span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">nvlen</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
<span class="n">fwrite</span><span class="p">(</span><span class="n">nva</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">name</span><span class="p">,</span> <span class="n">nva</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">namelen</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">stderr</span><span class="p">);</span> <span class="n">print_header</span><span class="p">(</span><span class="n">f</span><span class="p">,</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;: &quot;</span><span class="p">);</span> <span class="n">nva</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">name</span><span class="p">,</span> <span class="n">nva</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">namelen</span><span class="p">,</span>
<span class="n">fwrite</span><span class="p">(</span><span class="n">nva</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">value</span><span class="p">,</span> <span class="n">nva</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">valuelen</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">stderr</span><span class="p">);</span> <span class="n">nva</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">value</span><span class="p">,</span> <span class="n">nva</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">valuelen</span><span class="p">);</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="p">}</span> <span class="p">}</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span> <span class="n">fprintf</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="p">}</span> <span class="p">}</span>
<span class="cm">/* nghttp2_send_callback. Here we transmit the |data|, |length| bytes,</span> <span class="cm">/* nghttp2_send_callback. Here we transmit the |data|, |length| bytes,</span>
@ -783,6 +838,47 @@ here.</p>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span> <span class="p">}</span>
<span class="cm">/* nghttp2_on_header_callback: Called when nghttp2 library emits</span>
<span class="cm"> single header name/value pair. */</span>
<span class="k">static</span> <span class="kt">int</span> <span class="nf">on_header_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_frame</span> <span class="o">*</span><span class="n">frame</span><span class="p">,</span>
<span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">name</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">namelen</span><span class="p">,</span>
<span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">value</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">valuelen</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">user_data</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">http2_session_data</span> <span class="o">*</span><span class="n">session_data</span> <span class="o">=</span> <span class="p">(</span><span class="n">http2_session_data</span><span class="o">*</span><span class="p">)</span><span class="n">user_data</span><span class="p">;</span>
<span class="k">switch</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>:
<span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">==</span> <span class="n">NGHTTP2_HCAT_RESPONSE</span> <span class="o">&amp;&amp;</span>
<span class="n">session_data</span><span class="o">-&gt;</span><span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">stream_id</span> <span class="o">==</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">)</span> <span class="p">{</span>
<span class="cm">/* Print response headers for the initiated request. */</span>
<span class="n">print_header</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">namelen</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">valuelen</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* nghttp2_on_end_headers_callback: Called when nghttp2 library emits</span>
<span class="cm"> all header name/value pairs, or may be called prematurely because</span>
<span class="cm"> of errors which is indicated by |error_code|. */</span>
<span class="k">static</span> <span class="kt">int</span> <span class="nf">on_end_headers_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_frame</span> <span class="o">*</span><span class="n">frame</span><span class="p">,</span>
<span class="n">nghttp2_error_code</span> <span class="n">error_code</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">user_data</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">http2_session_data</span> <span class="o">*</span><span class="n">session_data</span> <span class="o">=</span> <span class="p">(</span><span class="n">http2_session_data</span><span class="o">*</span><span class="p">)</span><span class="n">user_data</span><span class="p">;</span>
<span class="k">switch</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>:
<span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">==</span> <span class="n">NGHTTP2_HCAT_RESPONSE</span> <span class="o">&amp;&amp;</span>
<span class="n">session_data</span><span class="o">-&gt;</span><span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">stream_id</span> <span class="o">==</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">)</span> <span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;All headers received with error_code=%d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">error_code</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* nghttp2_on_frame_recv_callback: Called when nghttp2 library</span> <span class="cm">/* nghttp2_on_frame_recv_callback: Called when nghttp2 library</span>
<span class="cm"> received a frame from the remote peer. */</span> <span class="cm"> received a frame from the remote peer. */</span>
<span class="k">static</span> <span class="kt">int</span> <span class="nf">on_frame_recv_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span> <span class="k">static</span> <span class="kt">int</span> <span class="nf">on_frame_recv_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span>
@ -793,9 +889,8 @@ here.</p>
<span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>: <span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>:
<span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">==</span> <span class="n">NGHTTP2_HCAT_RESPONSE</span> <span class="o">&amp;&amp;</span> <span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">==</span> <span class="n">NGHTTP2_HCAT_RESPONSE</span> <span class="o">&amp;&amp;</span>
<span class="n">session_data</span><span class="o">-&gt;</span><span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">stream_id</span> <span class="o">==</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">)</span> <span class="p">{</span> <span class="n">session_data</span><span class="o">-&gt;</span><span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">stream_id</span> <span class="o">==</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">)</span> <span class="p">{</span>
<span class="cm">/* Print response headers for the initiated request. */</span> <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Response headers for stream ID=%d:</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;Response headers:</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">);</span>
<span class="n">print_headers</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">nva</span><span class="p">,</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">nvlen</span><span class="p">);</span>
<span class="p">}</span> <span class="p">}</span>
<span class="k">break</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span> <span class="p">}</span>
@ -893,6 +988,8 @@ here.</p>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_frame_recv_callback</span> <span class="o">=</span> <span class="n">on_frame_recv_callback</span><span class="p">;</span> <span class="n">callbacks</span><span class="p">.</span><span class="n">on_frame_recv_callback</span> <span class="o">=</span> <span class="n">on_frame_recv_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_data_chunk_recv_callback</span> <span class="o">=</span> <span class="n">on_data_chunk_recv_callback</span><span class="p">;</span> <span class="n">callbacks</span><span class="p">.</span><span class="n">on_data_chunk_recv_callback</span> <span class="o">=</span> <span class="n">on_data_chunk_recv_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_stream_close_callback</span> <span class="o">=</span> <span class="n">on_stream_close_callback</span><span class="p">;</span> <span class="n">callbacks</span><span class="p">.</span><span class="n">on_stream_close_callback</span> <span class="o">=</span> <span class="n">on_stream_close_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_header_callback</span> <span class="o">=</span> <span class="n">on_header_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_end_headers_callback</span> <span class="o">=</span> <span class="n">on_end_headers_callback</span><span class="p">;</span>
<span class="n">nghttp2_session_client_new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">session_data</span><span class="o">-&gt;</span><span class="n">session</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">callbacks</span><span class="p">,</span> <span class="n">session_data</span><span class="p">);</span> <span class="n">nghttp2_session_client_new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">session_data</span><span class="o">-&gt;</span><span class="n">session</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">callbacks</span><span class="p">,</span> <span class="n">session_data</span><span class="p">);</span>
<span class="p">}</span> <span class="p">}</span>

View File

@ -369,12 +369,13 @@ these 2 functions later.</p>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_frame_recv_callback</span> <span class="o">=</span> <span class="n">on_frame_recv_callback</span><span class="p">;</span> <span class="n">callbacks</span><span class="p">.</span><span class="n">on_frame_recv_callback</span> <span class="o">=</span> <span class="n">on_frame_recv_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_request_recv_callback</span> <span class="o">=</span> <span class="n">on_request_recv_callback</span><span class="p">;</span> <span class="n">callbacks</span><span class="p">.</span><span class="n">on_request_recv_callback</span> <span class="o">=</span> <span class="n">on_request_recv_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_stream_close_callback</span> <span class="o">=</span> <span class="n">on_stream_close_callback</span><span class="p">;</span> <span class="n">callbacks</span><span class="p">.</span><span class="n">on_stream_close_callback</span> <span class="o">=</span> <span class="n">on_stream_close_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_header_callback</span> <span class="o">=</span> <span class="n">on_header_callback</span><span class="p">;</span>
<span class="n">nghttp2_session_server_new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">session_data</span><span class="o">-&gt;</span><span class="n">session</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">callbacks</span><span class="p">,</span> <span class="n">session_data</span><span class="p">);</span> <span class="n">nghttp2_session_server_new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">session_data</span><span class="o">-&gt;</span><span class="n">session</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">callbacks</span><span class="p">,</span> <span class="n">session_data</span><span class="p">);</span>
<span class="p">}</span> <span class="p">}</span>
</pre></div> </pre></div>
</div> </div>
<p>Since we are creating server, nghttp2 session object is created using <p>Since we are creating server, nghttp2 session object is created using
<a class="reference internal" href="apiref.html#nghttp2_session_server_new" title="nghttp2_session_server_new"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_server_new()</span></tt></a> function. We registers 4 callbacks to <a class="reference internal" href="apiref.html#nghttp2_session_server_new" title="nghttp2_session_server_new"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_server_new()</span></tt></a> function. We registers 5 callbacks to
nghttp2 session object. We&#8217;ll talk about these callbacks later.</p> nghttp2 session object. We&#8217;ll talk about these callbacks later.</p>
<p>After initialization of nghttp2 session object, we are going to send <p>After initialization of nghttp2 session object, we are going to send
server connection header in <tt class="docutils literal"><span class="pre">send_server_connection_header()</span></tt>:</p> server connection header in <tt class="docutils literal"><span class="pre">send_server_connection_header()</span></tt>:</p>
@ -540,8 +541,6 @@ received from the remote peer:</p>
<span class="p">{</span> <span class="p">{</span>
<span class="n">http2_session_data</span> <span class="o">*</span><span class="n">session_data</span> <span class="o">=</span> <span class="p">(</span><span class="n">http2_session_data</span><span class="o">*</span><span class="p">)</span><span class="n">user_data</span><span class="p">;</span> <span class="n">http2_session_data</span> <span class="o">*</span><span class="n">session_data</span> <span class="o">=</span> <span class="p">(</span><span class="n">http2_session_data</span><span class="o">*</span><span class="p">)</span><span class="n">user_data</span><span class="p">;</span>
<span class="n">http2_stream_data</span> <span class="o">*</span><span class="n">stream_data</span><span class="p">;</span> <span class="n">http2_stream_data</span> <span class="o">*</span><span class="n">stream_data</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">i</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">char</span> <span class="n">PATH</span><span class="p">[]</span> <span class="o">=</span> <span class="s">&quot;:path&quot;</span><span class="p">;</span>
<span class="k">switch</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">type</span><span class="p">)</span> <span class="p">{</span> <span class="k">switch</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>: <span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>:
<span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">!=</span> <span class="n">NGHTTP2_HCAT_REQUEST</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">!=</span> <span class="n">NGHTTP2_HCAT_REQUEST</span><span class="p">)</span> <span class="p">{</span>
@ -550,16 +549,6 @@ received from the remote peer:</p>
<span class="n">stream_data</span> <span class="o">=</span> <span class="n">create_http2_stream_data</span><span class="p">(</span><span class="n">session_data</span><span class="p">,</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">);</span> <span class="n">stream_data</span> <span class="o">=</span> <span class="n">create_http2_stream_data</span><span class="p">(</span><span class="n">session_data</span><span class="p">,</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">);</span>
<span class="n">nghttp2_session_set_stream_user_data</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">,</span> <span class="n">nghttp2_session_set_stream_user_data</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">,</span>
<span class="n">stream_data</span><span class="p">);</span> <span class="n">stream_data</span><span class="p">);</span>
<span class="k">for</span><span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">nvlen</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
<span class="n">nghttp2_nv</span> <span class="o">*</span><span class="n">nv</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">nva</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<span class="k">if</span><span class="p">(</span><span class="n">nv</span><span class="o">-&gt;</span><span class="n">namelen</span> <span class="o">==</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PATH</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span>
<span class="n">memcmp</span><span class="p">(</span><span class="n">PATH</span><span class="p">,</span> <span class="n">nv</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">,</span> <span class="n">nv</span><span class="o">-&gt;</span><span class="n">namelen</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">size_t</span> <span class="n">j</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">nv</span><span class="o">-&gt;</span><span class="n">valuelen</span> <span class="o">&amp;&amp;</span> <span class="n">nv</span><span class="o">-&gt;</span><span class="n">value</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">&#39;?&#39;</span><span class="p">;</span> <span class="o">++</span><span class="n">j</span><span class="p">);</span>
<span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">request_path</span> <span class="o">=</span> <span class="n">percent_decode</span><span class="p">(</span><span class="n">nv</span><span class="o">-&gt;</span><span class="n">value</span><span class="p">,</span> <span class="n">j</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
<span class="nl">default:</span> <span class="nl">default:</span>
<span class="k">break</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
@ -576,12 +565,46 @@ data. We associate created <tt class="docutils literal"><span class="pre">http2_
in nghttp2 session object using <tt class="xref c c-func docutils literal"><span class="pre">nghttp2_set_stream_user_data()</span></tt> in in nghttp2 session object using <tt class="xref c c-func docutils literal"><span class="pre">nghttp2_set_stream_user_data()</span></tt> in
order to get the object without searching through doubly linked list.</p> order to get the object without searching through doubly linked list.</p>
<p>In this example server, we want to serve files relative to the current <p>In this example server, we want to serve files relative to the current
working directory the program was invoked. We search <tt class="docutils literal"><span class="pre">:path</span></tt> header working directory the program was invoked. Each header name/value pair
field in request headers and keep the requested path in is emitted via <tt class="docutils literal"><span class="pre">on_header_callback</span></tt> function, which is called after
<tt class="docutils literal"><span class="pre">http2_stream_data</span></tt> object. In this example program, we ignore <tt class="docutils literal"><span class="pre">on_frame_recv_callback()</span></tt>:</p>
<tt class="docutils literal"><span class="pre">:method</span></tt> header field and always treat the request as GET request.</p> <div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">int</span> <span class="nf">on_header_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span>
<p>It is ok for the server to start sending response in this callback. In <span class="k">const</span> <span class="n">nghttp2_frame</span> <span class="o">*</span><span class="n">frame</span><span class="p">,</span>
this example, we defer it to <tt class="docutils literal"><span class="pre">on_request_recv_callback()</span></tt> function.</p> <span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">name</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">namelen</span><span class="p">,</span>
<span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">value</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">valuelen</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">user_data</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">http2_stream_data</span> <span class="o">*</span><span class="n">stream_data</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">char</span> <span class="n">PATH</span><span class="p">[]</span> <span class="o">=</span> <span class="s">&quot;:path&quot;</span><span class="p">;</span>
<span class="k">switch</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>:
<span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">!=</span> <span class="n">NGHTTP2_HCAT_REQUEST</span><span class="p">)</span> <span class="p">{</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">stream_data</span> <span class="o">=</span> <span class="n">nghttp2_session_get_stream_user_data</span><span class="p">(</span><span class="n">session</span><span class="p">,</span>
<span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">request_path</span><span class="p">)</span> <span class="p">{</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="n">namelen</span> <span class="o">==</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PATH</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="n">memcmp</span><span class="p">(</span><span class="n">PATH</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">namelen</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">size_t</span> <span class="n">j</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">valuelen</span> <span class="o">&amp;&amp;</span> <span class="n">value</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">&#39;?&#39;</span><span class="p">;</span> <span class="o">++</span><span class="n">j</span><span class="p">);</span>
<span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">request_path</span> <span class="o">=</span> <span class="n">percent_decode</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">j</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>We search <tt class="docutils literal"><span class="pre">:path</span></tt> header field in request headers and keep the
requested path in <tt class="docutils literal"><span class="pre">http2_stream_data</span></tt> object. In this example
program, we ignore <tt class="docutils literal"><span class="pre">:method</span></tt> header field and always treat the
request as GET request.</p>
<p>It is ok for the server to start sending response in this callback (or
in <a class="reference internal" href="apiref.html#nghttp2_on_end_headers_callback" title="nghttp2_on_end_headers_callback"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_on_end_headers_callback()</span></tt></a>, which is not used in this
tutorial). In this example, we defer it to
<tt class="docutils literal"><span class="pre">on_request_recv_callback()</span></tt> function.</p>
<p>The <tt class="docutils literal"><span class="pre">on_request_recv_callback()</span></tt> function is invoked when all HTTP <p>The <tt class="docutils literal"><span class="pre">on_request_recv_callback()</span></tt> function is invoked when all HTTP
request, including entity body, was received:</p> request, including entity body, was received:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">int</span> <span class="nf">on_request_recv_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span> <div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">int</span> <span class="nf">on_request_recv_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span>
@ -1033,13 +1056,41 @@ stream is about to close and we no longer use that object.</p>
<span class="k">return</span> <span class="n">res</span><span class="p">;</span> <span class="k">return</span> <span class="n">res</span><span class="p">;</span>
<span class="p">}</span> <span class="p">}</span>
<span class="cm">/* nghttp2_on_header_callback: Called when nghttp2 library emits</span>
<span class="cm"> single header name/value pair. */</span>
<span class="k">static</span> <span class="kt">int</span> <span class="nf">on_header_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_frame</span> <span class="o">*</span><span class="n">frame</span><span class="p">,</span>
<span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">name</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">namelen</span><span class="p">,</span>
<span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">value</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">valuelen</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">user_data</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">http2_stream_data</span> <span class="o">*</span><span class="n">stream_data</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">char</span> <span class="n">PATH</span><span class="p">[]</span> <span class="o">=</span> <span class="s">&quot;:path&quot;</span><span class="p">;</span>
<span class="k">switch</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>:
<span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">!=</span> <span class="n">NGHTTP2_HCAT_REQUEST</span><span class="p">)</span> <span class="p">{</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">stream_data</span> <span class="o">=</span> <span class="n">nghttp2_session_get_stream_user_data</span><span class="p">(</span><span class="n">session</span><span class="p">,</span>
<span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">request_path</span><span class="p">)</span> <span class="p">{</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="n">namelen</span> <span class="o">==</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PATH</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="n">memcmp</span><span class="p">(</span><span class="n">PATH</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">namelen</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">size_t</span> <span class="n">j</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">valuelen</span> <span class="o">&amp;&amp;</span> <span class="n">value</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">&#39;?&#39;</span><span class="p">;</span> <span class="o">++</span><span class="n">j</span><span class="p">);</span>
<span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">request_path</span> <span class="o">=</span> <span class="n">percent_decode</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">j</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">static</span> <span class="kt">int</span> <span class="nf">on_frame_recv_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span> <span class="k">static</span> <span class="kt">int</span> <span class="nf">on_frame_recv_callback</span><span class="p">(</span><span class="n">nghttp2_session</span> <span class="o">*</span><span class="n">session</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_frame</span> <span class="o">*</span><span class="n">frame</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">user_data</span><span class="p">)</span> <span class="k">const</span> <span class="n">nghttp2_frame</span> <span class="o">*</span><span class="n">frame</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">user_data</span><span class="p">)</span>
<span class="p">{</span> <span class="p">{</span>
<span class="n">http2_session_data</span> <span class="o">*</span><span class="n">session_data</span> <span class="o">=</span> <span class="p">(</span><span class="n">http2_session_data</span><span class="o">*</span><span class="p">)</span><span class="n">user_data</span><span class="p">;</span> <span class="n">http2_session_data</span> <span class="o">*</span><span class="n">session_data</span> <span class="o">=</span> <span class="p">(</span><span class="n">http2_session_data</span><span class="o">*</span><span class="p">)</span><span class="n">user_data</span><span class="p">;</span>
<span class="n">http2_stream_data</span> <span class="o">*</span><span class="n">stream_data</span><span class="p">;</span> <span class="n">http2_stream_data</span> <span class="o">*</span><span class="n">stream_data</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">i</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">char</span> <span class="n">PATH</span><span class="p">[]</span> <span class="o">=</span> <span class="s">&quot;:path&quot;</span><span class="p">;</span>
<span class="k">switch</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">type</span><span class="p">)</span> <span class="p">{</span> <span class="k">switch</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>: <span class="k">case</span> <span class="n">NGHTTP2_HEADERS</span>:
<span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">!=</span> <span class="n">NGHTTP2_HCAT_REQUEST</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span><span class="p">(</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">cat</span> <span class="o">!=</span> <span class="n">NGHTTP2_HCAT_REQUEST</span><span class="p">)</span> <span class="p">{</span>
@ -1048,16 +1099,6 @@ stream is about to close and we no longer use that object.</p>
<span class="n">stream_data</span> <span class="o">=</span> <span class="n">create_http2_stream_data</span><span class="p">(</span><span class="n">session_data</span><span class="p">,</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">);</span> <span class="n">stream_data</span> <span class="o">=</span> <span class="n">create_http2_stream_data</span><span class="p">(</span><span class="n">session_data</span><span class="p">,</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">);</span>
<span class="n">nghttp2_session_set_stream_user_data</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">,</span> <span class="n">nghttp2_session_set_stream_user_data</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">hd</span><span class="p">.</span><span class="n">stream_id</span><span class="p">,</span>
<span class="n">stream_data</span><span class="p">);</span> <span class="n">stream_data</span><span class="p">);</span>
<span class="k">for</span><span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">nvlen</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
<span class="n">nghttp2_nv</span> <span class="o">*</span><span class="n">nv</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">frame</span><span class="o">-&gt;</span><span class="n">headers</span><span class="p">.</span><span class="n">nva</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<span class="k">if</span><span class="p">(</span><span class="n">nv</span><span class="o">-&gt;</span><span class="n">namelen</span> <span class="o">==</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PATH</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span>
<span class="n">memcmp</span><span class="p">(</span><span class="n">PATH</span><span class="p">,</span> <span class="n">nv</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">,</span> <span class="n">nv</span><span class="o">-&gt;</span><span class="n">namelen</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">size_t</span> <span class="n">j</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">nv</span><span class="o">-&gt;</span><span class="n">valuelen</span> <span class="o">&amp;&amp;</span> <span class="n">nv</span><span class="o">-&gt;</span><span class="n">value</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">&#39;?&#39;</span><span class="p">;</span> <span class="o">++</span><span class="n">j</span><span class="p">);</span>
<span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">request_path</span> <span class="o">=</span> <span class="n">percent_decode</span><span class="p">(</span><span class="n">nv</span><span class="o">-&gt;</span><span class="n">value</span><span class="p">,</span> <span class="n">j</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
<span class="nl">default:</span> <span class="nl">default:</span>
<span class="k">break</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
@ -1211,6 +1252,7 @@ stream is about to close and we no longer use that object.</p>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_frame_recv_callback</span> <span class="o">=</span> <span class="n">on_frame_recv_callback</span><span class="p">;</span> <span class="n">callbacks</span><span class="p">.</span><span class="n">on_frame_recv_callback</span> <span class="o">=</span> <span class="n">on_frame_recv_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_request_recv_callback</span> <span class="o">=</span> <span class="n">on_request_recv_callback</span><span class="p">;</span> <span class="n">callbacks</span><span class="p">.</span><span class="n">on_request_recv_callback</span> <span class="o">=</span> <span class="n">on_request_recv_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_stream_close_callback</span> <span class="o">=</span> <span class="n">on_stream_close_callback</span><span class="p">;</span> <span class="n">callbacks</span><span class="p">.</span><span class="n">on_stream_close_callback</span> <span class="o">=</span> <span class="n">on_stream_close_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">on_header_callback</span> <span class="o">=</span> <span class="n">on_header_callback</span><span class="p">;</span>
<span class="n">nghttp2_session_server_new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">session_data</span><span class="o">-&gt;</span><span class="n">session</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">callbacks</span><span class="p">,</span> <span class="n">session_data</span><span class="p">);</span> <span class="n">nghttp2_session_server_new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">session_data</span><span class="o">-&gt;</span><span class="n">session</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">callbacks</span><span class="p">,</span> <span class="n">session_data</span><span class="p">);</span>
<span class="p">}</span> <span class="p">}</span>