Update doc

This commit is contained in:
Tatsuhiro Tsujikawa 2014-05-08 00:34:01 +09:00
parent 60589ebe0f
commit bb67fb0e37
6 changed files with 80 additions and 242 deletions

View File

@ -1836,30 +1836,6 @@ inclusive. Choosing number not in this range will be treated as
<a class="reference internal" href="#c.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>.</p>
</dd></dl>
<dl class="type">
<dt id="c.nghttp2_adjust_priority_callback">
typedef int <tt class="descname">(*nghttp2_adjust_priority_callback)</tt><big>(</big><a class="reference internal" href="#c.nghttp2_session" title="nghttp2_session">nghttp2_session</a><em>&nbsp;*session</em>, const <a class="reference internal" href="#c.nghttp2_frame" title="nghttp2_frame">nghttp2_frame</a><em>&nbsp;*frame</em>, <a class="reference internal" href="#c.nghttp2_priority_spec" title="nghttp2_priority_spec">nghttp2_priority_spec</a><em>&nbsp;*pri_spec</em>, void<em>&nbsp;*user_data</em><big>)</big><a class="headerlink" href="#c.nghttp2_adjust_priority_callback" title="Permalink to this definition"></a></dt>
<dd><p>Callback function invoked to adjust priority value for request
HEADERS. This callback is called only for request HEADERS (which
means, <tt class="xref c c-func docutils literal"><span class="pre">frame-&gt;hd.type</span> <span class="pre">==</span> <span class="pre">NGHTTP2_HEADERS</span> <span class="pre">&amp;&amp;</span> <span class="pre">frame-&gt;headers.cat</span> <span class="pre">==</span>
<span class="pre">NGHTTP2_HCAT_REQUEST()</span></tt> hold) and before
<tt class="xref c c-type docutils literal"><span class="pre">nghttp2_before_frame_send_callback()</span></tt>. The application can
adjust priority value <em>pri_spec</em>. Initially, <em>pri_spec</em> is filled
with the current priority value, which is equal to
<tt class="xref c c-func docutils literal"><span class="pre">frame-&gt;headers.pri_spec()</span></tt>. If the application doesn&#8217;t alter
priority value, just return 0 without updating <em>pri_spec</em>.</p>
<p>Since the application doesn&#8217;t know stream ID when it submits
requests, it may not be able to add correct priority value to
HEADERS frame and forced to use follwing PRIORITY frame. The
purpose of this callback is give the chance to the application to
adjust priority value with the latest information it has just
before transmission so that correct priority is included in HEADERS
frame and it doesn&#8217;t have to send additional PRIORITY frame.</p>
<p>Returning <a class="reference internal" href="#c.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> will make
<a class="reference internal" href="#c.nghttp2_session_send" title="nghttp2_session_send"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_send()</span></tt></a> function immediately return
<a class="reference internal" href="#c.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>.</p>
</dd></dl>
<dl class="type">
<dt id="c.nghttp2_session_callbacks">
<tt class="descname">nghttp2_session_callbacks</tt><a class="headerlink" href="#c.nghttp2_session_callbacks" title="Permalink to this definition"></a></dt>
@ -1957,13 +1933,6 @@ many padding bytes are required for the transmission of the given
frame.</p>
</dd></dl>
<dl class="member">
<dt id="c.nghttp2_session_callbacks.adjust_priority_callback">
<a class="reference internal" href="#c.nghttp2_adjust_priority_callback" title="nghttp2_adjust_priority_callback">nghttp2_adjust_priority_callback</a> <tt class="descname">adjust_priority_callback</tt><a class="headerlink" href="#c.nghttp2_session_callbacks.adjust_priority_callback" title="Permalink to this definition"></a></dt>
<dd><p>Callback function invoked to adjust priority value just before
request HEADERS is serialized to the wire format.</p>
</dd></dl>
</dd></dl>
<dl class="type">
@ -2143,9 +2112,6 @@ which tells when each callback is invoked:</p>
are not met (e.g., request HEADERS cannot be sent after GOAWAY),
<a class="reference internal" href="#c.nghttp2_session_callbacks.on_frame_not_send_callback" title="nghttp2_session_callbacks.on_frame_not_send_callback"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_session_callbacks.on_frame_not_send_callback</span></tt></a>
is invoked. Abort the following steps.</li>
<li>If the frame is request HEADERS,
<a class="reference internal" href="#c.nghttp2_session_callbacks.adjust_priority_callback" title="nghttp2_session_callbacks.adjust_priority_callback"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_session_callbacks.adjust_priority_callback</span></tt></a> is
invoked.</li>
<li>If the frame is HEADERS, PUSH_PROMISE or DATA,
<a class="reference internal" href="#c.nghttp2_session_callbacks.select_padding_callback" title="nghttp2_session_callbacks.select_padding_callback"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_session_callbacks.select_padding_callback</span></tt></a> is
invoked.</li>
@ -2541,7 +2507,7 @@ int <tt class="descname">nghttp2_priority_spec_check_default</tt><big>(</big>con
<dl class="function">
<dt id="c.nghttp2_submit_request">
int <tt class="descname">nghttp2_submit_request</tt><big>(</big><a class="reference internal" href="#c.nghttp2_session" title="nghttp2_session">nghttp2_session</a><em>&nbsp;*session</em>, const <a class="reference internal" href="#c.nghttp2_priority_spec" title="nghttp2_priority_spec">nghttp2_priority_spec</a><em>&nbsp;*pri_spec</em>, const <a class="reference internal" href="#c.nghttp2_nv" title="nghttp2_nv">nghttp2_nv</a><em>&nbsp;*nva</em>, size_t<em>&nbsp;nvlen</em>, const <a class="reference internal" href="#c.nghttp2_data_provider" title="nghttp2_data_provider">nghttp2_data_provider</a><em>&nbsp;*data_prd</em>, void<em>&nbsp;*stream_user_data</em><big>)</big><a class="headerlink" href="#c.nghttp2_submit_request" title="Permalink to this definition"></a></dt>
int32_t <tt class="descname">nghttp2_submit_request</tt><big>(</big><a class="reference internal" href="#c.nghttp2_session" title="nghttp2_session">nghttp2_session</a><em>&nbsp;*session</em>, const <a class="reference internal" href="#c.nghttp2_priority_spec" title="nghttp2_priority_spec">nghttp2_priority_spec</a><em>&nbsp;*pri_spec</em>, const <a class="reference internal" href="#c.nghttp2_nv" title="nghttp2_nv">nghttp2_nv</a><em>&nbsp;*nva</em>, size_t<em>&nbsp;nvlen</em>, const <a class="reference internal" href="#c.nghttp2_data_provider" title="nghttp2_data_provider">nghttp2_data_provider</a><em>&nbsp;*data_prd</em>, void<em>&nbsp;*stream_user_data</em><big>)</big><a class="headerlink" href="#c.nghttp2_submit_request" title="Permalink to this definition"></a></dt>
<dd><p>Submits HEADERS frame and optionally one or more DATA frames.</p>
<p>The <em>pri_spec</em> is priority specification of this request. <tt class="docutils literal"><span class="pre">NULL</span></tt>
means the default priority (see
@ -2574,22 +2540,14 @@ HEADERS have END_STREAM set. The <em>stream_user_data</em> is data
associated to the stream opened by this request and can be an
arbitrary pointer, which can be retrieved later by
<a class="reference internal" href="#c.nghttp2_session_get_stream_user_data" title="nghttp2_session_get_stream_user_data"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_get_stream_user_data()</span></tt></a>.</p>
<p>Since the library reorders the frames and tries to send the highest
prioritized one first and the HTTP/2 specification requires the
stream ID must be strictly increasing, the stream ID of this
request cannot be known until it is about to sent. To know the
stream ID of the request, the application can use
<a class="reference internal" href="#c.nghttp2_session_callbacks.before_frame_send_callback" title="nghttp2_session_callbacks.before_frame_send_callback"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_session_callbacks.before_frame_send_callback</span></tt></a>.
This callback is called just before the frame is sent. For HEADERS
frame, the argument frame has the stream ID assigned. Also since
the stream is already opened,
<a class="reference internal" href="#c.nghttp2_session_get_stream_user_data" title="nghttp2_session_get_stream_user_data"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_get_stream_user_data()</span></tt></a> can be used to get
<em>stream_user_data</em> to identify which HEADERS we are processing.</p>
<p>This function returns 0 if it succeeds, or one of the following
negative error codes:</p>
<p>This function returns assigned stream ID if it succeeds, or one of
the following negative error codes:</p>
<dl class="docutils">
<dt><a class="reference internal" href="#c.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="#c.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE" title="NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE</span></tt></a></dt>
<dd>No stream ID is available because maximum stream ID was
reached.</dd>
</dl>
</dd></dl>
@ -2628,7 +2586,7 @@ negative error codes:</p>
<dl class="function">
<dt id="c.nghttp2_submit_headers">
int <tt class="descname">nghttp2_submit_headers</tt><big>(</big><a class="reference internal" href="#c.nghttp2_session" title="nghttp2_session">nghttp2_session</a><em>&nbsp;*session</em>, uint8_t<em>&nbsp;flags</em>, int32_t<em>&nbsp;stream_id</em>, const <a class="reference internal" href="#c.nghttp2_priority_spec" title="nghttp2_priority_spec">nghttp2_priority_spec</a><em>&nbsp;*pri_spec</em>, const <a class="reference internal" href="#c.nghttp2_nv" title="nghttp2_nv">nghttp2_nv</a><em>&nbsp;*nva</em>, size_t<em>&nbsp;nvlen</em>, void<em>&nbsp;*stream_user_data</em><big>)</big><a class="headerlink" href="#c.nghttp2_submit_headers" title="Permalink to this definition"></a></dt>
int32_t <tt class="descname">nghttp2_submit_headers</tt><big>(</big><a class="reference internal" href="#c.nghttp2_session" title="nghttp2_session">nghttp2_session</a><em>&nbsp;*session</em>, uint8_t<em>&nbsp;flags</em>, int32_t<em>&nbsp;stream_id</em>, const <a class="reference internal" href="#c.nghttp2_priority_spec" title="nghttp2_priority_spec">nghttp2_priority_spec</a><em>&nbsp;*pri_spec</em>, const <a class="reference internal" href="#c.nghttp2_nv" title="nghttp2_nv">nghttp2_nv</a><em>&nbsp;*nva</em>, size_t<em>&nbsp;nvlen</em>, void<em>&nbsp;*stream_user_data</em><big>)</big><a class="headerlink" href="#c.nghttp2_submit_headers" title="Permalink to this definition"></a></dt>
<dd><p>Submits HEADERS frame. The <em>flags</em> is bitwise OR of the
following values:</p>
<ul class="simple">
@ -2641,8 +2599,8 @@ correctly sets END_HEADERS to the last sequence of the PUSH_PROMISE
or CONTINUATION frame.</p>
<p>If the <em>stream_id</em> is -1, this frame is assumed as request (i.e.,
request HEADERS frame which opens new stream). In this case, the
actual stream ID is assigned just before the frame is sent. For
response, specify stream ID in <em>stream_id</em>.</p>
assigned stream ID will be returned. Otherwise, specify stream ID
in <em>stream_id</em>.</p>
<p>The <em>pri_spec</em> is priority specification of this request. <tt class="docutils literal"><span class="pre">NULL</span></tt>
means the default priority (see
<a class="reference internal" href="#c.nghttp2_priority_spec_default_init" title="nghttp2_priority_spec_default_init"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_priority_spec_default_init()</span></tt></a>). To specify the priority,
@ -2668,11 +2626,15 @@ stream state from idle or reserved to open.</p>
<p>This function is low-level in a sense that the application code can
specify flags directly. For usual HTTP request,
<a class="reference internal" href="#c.nghttp2_submit_request" title="nghttp2_submit_request"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_submit_request()</span></tt></a> is useful.</p>
<p>This function returns 0 if it succeeds, or one of the following
negative error codes:</p>
<p>This function returns newly assigned stream ID if it succeeds and
<em>stream_id</em> is -1. Otherwise, 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="#c.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="#c.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE" title="NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE</span></tt></a></dt>
<dd>No stream ID is available because maximum stream ID was
reached.</dd>
</dl>
</dd></dl>
@ -2769,7 +2731,7 @@ without ACK flag set.</dd>
<dl class="function">
<dt id="c.nghttp2_submit_push_promise">
int <tt class="descname">nghttp2_submit_push_promise</tt><big>(</big><a class="reference internal" href="#c.nghttp2_session" title="nghttp2_session">nghttp2_session</a><em>&nbsp;*session</em>, uint8_t<em>&nbsp;flags</em>, int32_t<em>&nbsp;stream_id</em>, const <a class="reference internal" href="#c.nghttp2_nv" title="nghttp2_nv">nghttp2_nv</a><em>&nbsp;*nva</em>, size_t<em>&nbsp;nvlen</em>, void<em>&nbsp;*promised_stream_user_data</em><big>)</big><a class="headerlink" href="#c.nghttp2_submit_push_promise" title="Permalink to this definition"></a></dt>
int32_t <tt class="descname">nghttp2_submit_push_promise</tt><big>(</big><a class="reference internal" href="#c.nghttp2_session" title="nghttp2_session">nghttp2_session</a><em>&nbsp;*session</em>, uint8_t<em>&nbsp;flags</em>, int32_t<em>&nbsp;stream_id</em>, const <a class="reference internal" href="#c.nghttp2_nv" title="nghttp2_nv">nghttp2_nv</a><em>&nbsp;*nva</em>, size_t<em>&nbsp;nvlen</em>, void<em>&nbsp;*promised_stream_user_data</em><big>)</big><a class="headerlink" href="#c.nghttp2_submit_push_promise" title="Permalink to this definition"></a></dt>
<dd><p>Submits PUSH_PROMISE frame.</p>
<p>The <em>flags</em> is currently ignored. The library handles the
CONTINUATION frame internally and it correctly sets END_HEADERS to
@ -2789,24 +2751,18 @@ make it in reserved state. It is available using
<a class="reference internal" href="#c.nghttp2_session_get_stream_user_data" title="nghttp2_session_get_stream_user_data"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_get_stream_user_data()</span></tt></a>. The application can
access it in <a class="reference internal" href="#c.nghttp2_before_frame_send_callback" title="nghttp2_before_frame_send_callback"><tt class="xref c c-type docutils literal"><span class="pre">nghttp2_before_frame_send_callback</span></tt></a> and
<a class="reference internal" href="#c.nghttp2_on_frame_send_callback" title="nghttp2_on_frame_send_callback"><tt class="xref c c-type docutils literal"><span class="pre">nghttp2_on_frame_send_callback</span></tt></a> of this frame.</p>
<p>Since the library reorders the frames and tries to send the highest
prioritized one first and the HTTP/2 specification requires the
stream ID must be strictly increasing, the promised stream ID
cannot be known until it is about to sent. To know the promised
stream ID, the application can use
<a class="reference internal" href="#c.nghttp2_session_callbacks.before_frame_send_callback" title="nghttp2_session_callbacks.before_frame_send_callback"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_session_callbacks.before_frame_send_callback</span></tt></a>.
This callback is called just before the frame is sent. For
PUSH_PROMISE frame, the argument frame has the promised stream ID
assigned.</p>
<p>The client side is not allowed to use this function.</p>
<p>This function returns 0 if it succeeds, or one of the following
negative error codes:</p>
<p>This function returns assigned promised stream ID if it succeeds,
or one of the following negative error codes:</p>
<dl class="docutils">
<dt><a class="reference internal" href="#c.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="#c.NGHTTP2_ERR_PROTO" title="NGHTTP2_ERR_PROTO"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_PROTO</span></tt></a></dt>
<dd>This function was invoked when <em>session</em> is initialized as
client.</dd>
<dt><a class="reference internal" href="#c.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE" title="NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE</span></tt></a></dt>
<dd>No stream ID is available because maximum stream ID was
reached.</dd>
</dl>
</dd></dl>

View File

@ -167,10 +167,6 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="apiref.html#c.nghttp2_adjust_priority_callback">nghttp2_adjust_priority_callback (C type)</a>
</dt>
<dt><a href="apiref.html#c.NGHTTP2_ALTSVC">NGHTTP2_ALTSVC (C macro)</a>
</dt>
@ -1025,10 +1021,6 @@
</dt>
<dt><a href="apiref.html#c.nghttp2_session_callbacks.adjust_priority_callback">nghttp2_session_callbacks.adjust_priority_callback (C member)</a>
</dt>
<dt><a href="apiref.html#c.nghttp2_session_callbacks.before_frame_send_callback">nghttp2_session_callbacks.before_frame_send_callback (C member)</a>
</dt>

View File

@ -1576,37 +1576,6 @@
<span class="kt">size_t</span> <span class="n">max_payloadlen</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="cm">/**</span>
<span class="cm"> * @functypedef</span>
<span class="cm"> *</span>
<span class="cm"> * Callback function invoked to adjust priority value for request</span>
<span class="cm"> * HEADERS. This callback is called only for request HEADERS (which</span>
<span class="cm"> * means, `frame-&gt;hd.type == NGHTTP2_HEADERS &amp;&amp; frame-&gt;headers.cat ==</span>
<span class="cm"> * NGHTTP2_HCAT_REQUEST` hold) and before</span>
<span class="cm"> * :type:`nghttp2_before_frame_send_callback()`. The application can</span>
<span class="cm"> * adjust priority value |pri_spec|. Initially, |pri_spec| is filled</span>
<span class="cm"> * with the current priority value, which is equal to</span>
<span class="cm"> * `frame-&gt;headers.pri_spec`. If the application doesn&#39;t alter</span>
<span class="cm"> * priority value, just return 0 without updating |pri_spec|.</span>
<span class="cm"> *</span>
<span class="cm"> * Since the application doesn&#39;t know stream ID when it submits</span>
<span class="cm"> * requests, it may not be able to add correct priority value to</span>
<span class="cm"> * HEADERS frame and forced to use follwing PRIORITY frame. The</span>
<span class="cm"> * purpose of this callback is give the chance to the application to</span>
<span class="cm"> * adjust priority value with the latest information it has just</span>
<span class="cm"> * before transmission so that correct priority is included in HEADERS</span>
<span class="cm"> * frame and it doesn&#39;t have to send additional PRIORITY frame.</span>
<span class="cm"> *</span>
<span class="cm"> * Returning :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will make</span>
<span class="cm"> * `nghttp2_session_send()` function immediately return</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.</span>
<span class="cm"> */</span>
<span class="k">typedef</span> <span class="nf">int</span> <span class="p">(</span><span class="o">*</span><span class="n">nghttp2_adjust_priority_callback</span><span class="p">)</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_priority_spec</span> <span class="o">*</span><span class="n">pri_spec</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="cm">/**</span>
<span class="cm"> * @struct</span>
<span class="cm"> *</span>
@ -1680,11 +1649,6 @@
<span class="cm"> * frame.</span>
<span class="cm"> */</span>
<span class="n">nghttp2_select_padding_callback</span> <span class="n">select_padding_callback</span><span class="p">;</span>
<span class="cm">/**</span>
<span class="cm"> * Callback function invoked to adjust priority value just before</span>
<span class="cm"> * request HEADERS is serialized to the wire format.</span>
<span class="cm"> */</span>
<span class="n">nghttp2_adjust_priority_callback</span> <span class="n">adjust_priority_callback</span><span class="p">;</span>
<span class="p">}</span> <span class="n">nghttp2_session_callbacks</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">nghttp2_option</span><span class="p">;</span>
@ -1891,23 +1855,20 @@
<span class="cm"> * are not met (e.g., request HEADERS cannot be sent after GOAWAY),</span>
<span class="cm"> * :member:`nghttp2_session_callbacks.on_frame_not_send_callback`</span>
<span class="cm"> * is invoked. Abort the following steps.</span>
<span class="cm"> * 4. If the frame is request HEADERS,</span>
<span class="cm"> * :member:`nghttp2_session_callbacks.adjust_priority_callback` is</span>
<span class="cm"> * invoked.</span>
<span class="cm"> * 5. If the frame is HEADERS, PUSH_PROMISE or DATA,</span>
<span class="cm"> * 4. If the frame is HEADERS, PUSH_PROMISE or DATA,</span>
<span class="cm"> * :member:`nghttp2_session_callbacks.select_padding_callback` is</span>
<span class="cm"> * invoked.</span>
<span class="cm"> * 6. If the frame is request HEADERS, the stream is opened here.</span>
<span class="cm"> * 7. :member:`nghttp2_session_callbacks.before_frame_send_callback` is</span>
<span class="cm"> * 5. If the frame is request HEADERS, the stream is opened here.</span>
<span class="cm"> * 6. :member:`nghttp2_session_callbacks.before_frame_send_callback` is</span>
<span class="cm"> * invoked.</span>
<span class="cm"> * 8. :member:`nghttp2_session_callbacks.send_callback` is invoked one</span>
<span class="cm"> * 7. :member:`nghttp2_session_callbacks.send_callback` is invoked one</span>
<span class="cm"> * or more times to send the frame.</span>
<span class="cm"> * 9. :member:`nghttp2_session_callbacks.on_frame_send_callback` is</span>
<span class="cm"> * 8. :member:`nghttp2_session_callbacks.on_frame_send_callback` is</span>
<span class="cm"> * invoked.</span>
<span class="cm"> * 9. If the transmission of the frame triggers closure of the stream,</span>
<span class="cm"> * the stream is closed and</span>
<span class="cm"> * :member:`nghttp2_session_callbacks.on_stream_close_callback` is</span>
<span class="cm"> * invoked.</span>
<span class="cm"> * 10. If the transmission of the frame triggers closure of the stream,</span>
<span class="cm"> * the stream is closed and</span>
<span class="cm"> * :member:`nghttp2_session_callbacks.on_stream_close_callback` is</span>
<span class="cm"> * invoked.</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>
@ -2392,29 +2353,20 @@
<span class="cm"> * arbitrary pointer, which can be retrieved later by</span>
<span class="cm"> * `nghttp2_session_get_stream_user_data()`.</span>
<span class="cm"> *</span>
<span class="cm"> * Since the library reorders the frames and tries to send the highest</span>
<span class="cm"> * prioritized one first and the HTTP/2 specification requires the</span>
<span class="cm"> * stream ID must be strictly increasing, the stream ID of this</span>
<span class="cm"> * request cannot be known until it is about to sent. To know the</span>
<span class="cm"> * stream ID of the request, the application can use</span>
<span class="cm"> * :member:`nghttp2_session_callbacks.before_frame_send_callback`.</span>
<span class="cm"> * This callback is called just before the frame is sent. For HEADERS</span>
<span class="cm"> * frame, the argument frame has the stream ID assigned. Also since</span>
<span class="cm"> * the stream is already opened,</span>
<span class="cm"> * `nghttp2_session_get_stream_user_data()` can be used to get</span>
<span class="cm"> * |stream_user_data| to identify which HEADERS we are processing.</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"> * This function returns assigned stream ID if it succeeds, or one of</span>
<span class="cm"> * the following negative error codes:</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_STREAM_ID_NOT_AVAILABLE`</span>
<span class="cm"> * No stream ID is available because maximum stream ID was</span>
<span class="cm"> * reached.</span>
<span class="cm"> */</span>
<span class="kt">int</span> <span class="nf">nghttp2_submit_request</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_priority_spec</span> <span class="o">*</span><span class="n">pri_spec</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_nv</span> <span class="o">*</span><span class="n">nva</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">nvlen</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_data_provider</span> <span class="o">*</span><span class="n">data_prd</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">stream_user_data</span><span class="p">);</span>
<span class="kt">int32_t</span> <span class="nf">nghttp2_submit_request</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_priority_spec</span> <span class="o">*</span><span class="n">pri_spec</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_nv</span> <span class="o">*</span><span class="n">nva</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">nvlen</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_data_provider</span> <span class="o">*</span><span class="n">data_prd</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">stream_user_data</span><span class="p">);</span>
<span class="cm">/**</span>
<span class="cm"> * @function</span>
@ -2475,8 +2427,8 @@
<span class="cm"> *</span>
<span class="cm"> * If the |stream_id| is -1, this frame is assumed as request (i.e.,</span>
<span class="cm"> * request HEADERS frame which opens new stream). In this case, the</span>
<span class="cm"> * actual stream ID is assigned just before the frame is sent. For</span>
<span class="cm"> * response, specify stream ID in |stream_id|.</span>
<span class="cm"> * assigned stream ID will be returned. Otherwise, specify stream ID</span>
<span class="cm"> * in |stream_id|.</span>
<span class="cm"> *</span>
<span class="cm"> * The |pri_spec| is priority specification of this request. ``NULL``</span>
<span class="cm"> * means the default priority (see</span>
@ -2509,17 +2461,21 @@
<span class="cm"> * specify flags directly. For usual HTTP request,</span>
<span class="cm"> * `nghttp2_submit_request()` is useful.</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"> * This function returns newly assigned stream ID if it succeeds and</span>
<span class="cm"> * |stream_id| is -1. Otherwise, this function returns 0 if it</span>
<span class="cm"> * succeeds, or one of the following negative error codes:</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_STREAM_ID_NOT_AVAILABLE`</span>
<span class="cm"> * No stream ID is available because maximum stream ID was</span>
<span class="cm"> * reached.</span>
<span class="cm"> */</span>
<span class="kt">int</span> <span class="nf">nghttp2_submit_headers</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>
<span class="kt">int32_t</span> <span class="n">stream_id</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_priority_spec</span> <span class="o">*</span><span class="n">pri_spec</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_nv</span> <span class="o">*</span><span class="n">nva</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">nvlen</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">stream_user_data</span><span class="p">);</span>
<span class="kt">int32_t</span> <span class="nf">nghttp2_submit_headers</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>
<span class="kt">int32_t</span> <span class="n">stream_id</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_priority_spec</span> <span class="o">*</span><span class="n">pri_spec</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_nv</span> <span class="o">*</span><span class="n">nva</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">nvlen</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">stream_user_data</span><span class="p">);</span>
<span class="cm">/**</span>
<span class="cm"> * @function</span>
@ -2661,31 +2617,24 @@
<span class="cm"> * access it in :type:`nghttp2_before_frame_send_callback` and</span>
<span class="cm"> * :type:`nghttp2_on_frame_send_callback` of this frame.</span>
<span class="cm"> *</span>
<span class="cm"> * Since the library reorders the frames and tries to send the highest</span>
<span class="cm"> * prioritized one first and the HTTP/2 specification requires the</span>
<span class="cm"> * stream ID must be strictly increasing, the promised stream ID</span>
<span class="cm"> * cannot be known until it is about to sent. To know the promised</span>
<span class="cm"> * stream ID, the application can use</span>
<span class="cm"> * :member:`nghttp2_session_callbacks.before_frame_send_callback`.</span>
<span class="cm"> * This callback is called just before the frame is sent. For</span>
<span class="cm"> * PUSH_PROMISE frame, the argument frame has the promised stream ID</span>
<span class="cm"> * assigned.</span>
<span class="cm"> *</span>
<span class="cm"> * The client side is not allowed to use this function.</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"> * This function returns assigned promised stream ID if it succeeds,</span>
<span class="cm"> * or one of the following negative error codes:</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_PROTO`</span>
<span class="cm"> * This function was invoked when |session| is initialized as</span>
<span class="cm"> * client.</span>
<span class="cm"> * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`</span>
<span class="cm"> * No stream ID is available because maximum stream ID was</span>
<span class="cm"> * reached.</span>
<span class="cm"> */</span>
<span class="kt">int</span> <span class="nf">nghttp2_submit_push_promise</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>
<span class="kt">int32_t</span> <span class="n">stream_id</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_nv</span> <span class="o">*</span><span class="n">nva</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">nvlen</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">promised_stream_user_data</span><span class="p">);</span>
<span class="kt">int32_t</span> <span class="nf">nghttp2_submit_push_promise</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>
<span class="kt">int32_t</span> <span class="n">stream_id</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_nv</span> <span class="o">*</span><span class="n">nva</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">nvlen</span><span class="p">,</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">promised_stream_user_data</span><span class="p">);</span>
<span class="cm">/**</span>
<span class="cm"> * @function</span>

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -312,7 +312,6 @@ finished successfully. We first initialize nghttp2 session object in
<span class="n">nghttp2_session_callbacks</span> <span class="n">callbacks</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">send_callback</span> <span class="o">=</span> <span class="n">send_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">before_frame_send_callback</span> <span class="o">=</span> <span class="n">before_frame_send_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_stream_close_callback</span> <span class="o">=</span> <span class="n">on_stream_close_callback</span><span class="p">;</span>
@ -363,7 +362,7 @@ used, which is described about later.</p>
request in <tt class="docutils literal"><span class="pre">submit_request()</span></tt> function:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">void</span> <span class="nf">submit_request</span><span class="p">(</span><span class="n">http2_session_data</span> <span class="o">*</span><span class="n">session_data</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">rv</span><span class="p">;</span>
<span class="kt">int32_t</span> <span class="n">stream_id</span><span class="p">;</span>
<span class="n">http2_stream_data</span> <span class="o">*</span><span class="n">stream_data</span> <span class="o">=</span> <span class="n">session_data</span><span class="o">-&gt;</span><span class="n">stream_data</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">uri</span> <span class="o">=</span> <span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">uri</span><span class="p">;</span>
<span class="k">const</span> <span class="k">struct</span> <span class="n">http_parser_url</span> <span class="o">*</span><span class="n">u</span> <span class="o">=</span> <span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">u</span><span class="p">;</span>
@ -376,11 +375,13 @@ request in <tt class="docutils literal"><span class="pre">submit_request()</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;Request headers:</span><span class="se">\n</span><span class="s">&quot;</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">hdrs</span><span class="p">,</span> <span class="n">ARRLEN</span><span class="p">(</span><span class="n">hdrs</span><span class="p">));</span>
<span class="n">rv</span> <span class="o">=</span> <span class="n">nghttp2_submit_request</span><span class="p">(</span><span class="n">session_data</span><span class="o">-&gt;</span><span class="n">session</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span>
<span class="n">hdrs</span><span class="p">,</span> <span class="n">ARRLEN</span><span class="p">(</span><span class="n">hdrs</span><span class="p">),</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">stream_data</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">rv</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">errx</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s">&quot;Could not submit HTTP request: %s&quot;</span><span class="p">,</span> <span class="n">nghttp2_strerror</span><span class="p">(</span><span class="n">rv</span><span class="p">));</span>
<span class="n">stream_id</span> <span class="o">=</span> <span class="n">nghttp2_submit_request</span><span class="p">(</span><span class="n">session_data</span><span class="o">-&gt;</span><span class="n">session</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span>
<span class="n">hdrs</span><span class="p">,</span> <span class="n">ARRLEN</span><span class="p">(</span><span class="n">hdrs</span><span class="p">),</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">stream_data</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">stream_id</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">errx</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s">&quot;Could not submit HTTP request: %s&quot;</span><span class="p">,</span> <span class="n">nghttp2_strerror</span><span class="p">(</span><span class="n">stream_id</span><span class="p">));</span>
<span class="p">}</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">stream_id</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
@ -389,7 +390,9 @@ request in <tt class="docutils literal"><span class="pre">submit_request()</span
<tt class="docutils literal"><span class="pre">:scheme</span></tt>, <tt class="docutils literal"><span class="pre">:authority</span></tt> and <tt class="docutils literal"><span class="pre">:path</span></tt>. To queue this HTTP request,
we use <a class="reference internal" href="apiref.html#c.nghttp2_submit_request" title="nghttp2_submit_request"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_submit_request()</span></tt></a> function. The <tt class="xref c c-func docutils literal"><span class="pre">stream_data()</span></tt> is
passed in <em>stream_user_data</em> parameter. It is used in nghttp2
callbacks which we&#8217;ll describe about later.</p>
callbacks which we&#8217;ll describe about later.
<a class="reference internal" href="apiref.html#c.nghttp2_submit_request" title="nghttp2_submit_request"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_submit_request()</span></tt></a> returns the newly assigned stream ID for
this request.</p>
<p>The next bufferevent callback is <tt class="docutils literal"><span class="pre">readcb()</span></tt>, which is invoked when
data is available to read in the bufferevent input buffer:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">void</span> <span class="nf">readcb</span><span class="p">(</span><span class="k">struct</span> <span class="n">bufferevent</span> <span class="o">*</span><span class="n">bev</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">ptr</span><span class="p">)</span>
@ -491,47 +494,6 @@ conditions are met, we drop connection.</p>
<p>We have already described about nghttp2 callback <tt class="docutils literal"><span class="pre">send_callback()</span></tt>.
Let&#8217;s describe remaining nghttp2 callbacks we setup in
<tt class="docutils literal"><span class="pre">initialize_nghttp2_setup()</span></tt> function.</p>
<p>The <tt class="xref c c-func docutils literal"><span class="pre">before_frame_send_callback()</span></tt> function is invoked when a frame is
about to be sent:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">int</span> <span class="nf">before_frame_send_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="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="k">if</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="o">==</span> <span class="n">NGHTTP2_HEADERS</span> <span class="o">&amp;&amp;</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="n">stream_data</span> <span class="o">=</span>
<span class="p">(</span><span class="n">http2_stream_data</span><span class="o">*</span><span class="p">)</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">==</span> <span class="n">session_data</span><span class="o">-&gt;</span><span class="n">stream_data</span><span class="p">)</span> <span class="p">{</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="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Remember that we have not get stream ID when we submit HTTP request
using <a class="reference internal" href="apiref.html#c.nghttp2_submit_request" title="nghttp2_submit_request"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_submit_request()</span></tt></a>. Since nghttp2 library reorders the
request based on priority and stream ID must be monotonically
increased, the stream ID is not assigned just before transmission.
The one of the purpose of this callback is get the stream ID assigned
to the frame. First we check that the frame is HEADERS frame. Since
HEADERS has several meanings in HTTP/2, we check that it is request
HEADERS (which means that the first HEADERS frame to create a stream).
The assigned stream ID is <tt class="docutils literal"><span class="pre">frame-&gt;hd.stream_id</span></tt>. Recall that we
passed <tt class="docutils literal"><span class="pre">stream_data</span></tt> in the <em>stream_user_data</em> parameter of
<a class="reference internal" href="apiref.html#c.nghttp2_submit_request" title="nghttp2_submit_request"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_submit_request()</span></tt></a> function. We can get it using
<a class="reference internal" href="apiref.html#c.nghttp2_session_get_stream_user_data" title="nghttp2_session_get_stream_user_data"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_get_stream_user_data()</span></tt></a> function. To really sure that
this HEADERS frame is the request HEADERS we have queued, we check
that <tt class="docutils literal"><span class="pre">session_data-&gt;stream_data</span></tt> and <tt class="docutils literal"><span class="pre">stream_data</span></tt> returned from
<a class="reference internal" href="apiref.html#c.nghttp2_session_get_stream_user_data" title="nghttp2_session_get_stream_user_data"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_session_get_stream_user_data()</span></tt></a> are pointing the same
location. In this example program, we just only uses 1 stream, it is
unnecessary to compare them, but real applications surely deal with
multiple streams, and <em>stream_user_data</em> is very handy to identify
which HEADERS we are seeing in the callback. Therefore we just show
how to use it here.</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>
@ -818,28 +780,6 @@ here.</p>
<span class="k">return</span> <span class="n">length</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* nghttp2_before_frame_send_callback: Called when nghttp2 library is</span>
<span class="cm"> about to send a frame. We use this callback to get stream ID of new</span>
<span class="cm"> stream. Since HEADERS in HTTP/2 has several roles, we check that</span>
<span class="cm"> it is a HTTP request HEADERS. */</span>
<span class="k">static</span> <span class="kt">int</span> <span class="nf">before_frame_send_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="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="k">if</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="o">==</span> <span class="n">NGHTTP2_HEADERS</span> <span class="o">&amp;&amp;</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="n">stream_data</span> <span class="o">=</span>
<span class="p">(</span><span class="n">http2_stream_data</span><span class="o">*</span><span class="p">)</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">==</span> <span class="n">session_data</span><span class="o">-&gt;</span><span class="n">stream_data</span><span class="p">)</span> <span class="p">{</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="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_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>
@ -987,7 +927,6 @@ here.</p>
<span class="n">memset</span><span class="p">(</span><span class="o">&amp;</span><span class="n">callbacks</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">callbacks</span><span class="p">));</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">send_callback</span> <span class="o">=</span> <span class="n">send_callback</span><span class="p">;</span>
<span class="n">callbacks</span><span class="p">.</span><span class="n">before_frame_send_callback</span> <span class="o">=</span> <span class="n">before_frame_send_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_stream_close_callback</span> <span class="o">=</span> <span class="n">on_stream_close_callback</span><span class="p">;</span>
@ -1024,7 +963,7 @@ here.</p>
<span class="cm">/* Send HTTP request to the remote peer */</span>
<span class="k">static</span> <span class="kt">void</span> <span class="nf">submit_request</span><span class="p">(</span><span class="n">http2_session_data</span> <span class="o">*</span><span class="n">session_data</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">rv</span><span class="p">;</span>
<span class="kt">int32_t</span> <span class="n">stream_id</span><span class="p">;</span>
<span class="n">http2_stream_data</span> <span class="o">*</span><span class="n">stream_data</span> <span class="o">=</span> <span class="n">session_data</span><span class="o">-&gt;</span><span class="n">stream_data</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">uri</span> <span class="o">=</span> <span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">uri</span><span class="p">;</span>
<span class="k">const</span> <span class="k">struct</span> <span class="n">http_parser_url</span> <span class="o">*</span><span class="n">u</span> <span class="o">=</span> <span class="n">stream_data</span><span class="o">-&gt;</span><span class="n">u</span><span class="p">;</span>
@ -1037,11 +976,13 @@ here.</p>
<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;Request headers:</span><span class="se">\n</span><span class="s">&quot;</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">hdrs</span><span class="p">,</span> <span class="n">ARRLEN</span><span class="p">(</span><span class="n">hdrs</span><span class="p">));</span>
<span class="n">rv</span> <span class="o">=</span> <span class="n">nghttp2_submit_request</span><span class="p">(</span><span class="n">session_data</span><span class="o">-&gt;</span><span class="n">session</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span>
<span class="n">hdrs</span><span class="p">,</span> <span class="n">ARRLEN</span><span class="p">(</span><span class="n">hdrs</span><span class="p">),</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">stream_data</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">rv</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">errx</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s">&quot;Could not submit HTTP request: %s&quot;</span><span class="p">,</span> <span class="n">nghttp2_strerror</span><span class="p">(</span><span class="n">rv</span><span class="p">));</span>
<span class="n">stream_id</span> <span class="o">=</span> <span class="n">nghttp2_submit_request</span><span class="p">(</span><span class="n">session_data</span><span class="o">-&gt;</span><span class="n">session</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span>
<span class="n">hdrs</span><span class="p">,</span> <span class="n">ARRLEN</span><span class="p">(</span><span class="n">hdrs</span><span class="p">),</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">stream_data</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">stream_id</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">errx</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s">&quot;Could not submit HTTP request: %s&quot;</span><span class="p">,</span> <span class="n">nghttp2_strerror</span><span class="p">(</span><span class="n">stream_id</span><span class="p">));</span>
<span class="p">}</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">stream_id</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* Serialize the frame and send (or buffer) the data to</span>