nghttp2/tutorial-hpack.html

554 lines
48 KiB
HTML

<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tutorial: HPACK API &mdash; nghttp2 0.4.2-DEV documentation</title>
<link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="top" title="nghttp2 0.4.2-DEV documentation" href="index.html"/>
<link rel="next" title="nghttpx - HTTP/2 proxy - HOW-TO" href="nghttpx-howto.html"/>
<link rel="prev" title="Tutorial: HTTP/2 server" href="tutorial-server.html"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-nav-search">
<a href="index.html" class="fa fa-home"> nghttp2</a>
<div role="search">
<form id ="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="package_README.html">nghttp2 - HTTP/2 C Library</a><ul>
<li class="toctree-l2"><a class="reference internal" href="package_README.html#development-status">Development Status</a></li>
<li class="toctree-l2"><a class="reference internal" href="package_README.html#public-test-server">Public Test Server</a></li>
<li class="toctree-l2"><a class="reference internal" href="package_README.html#requirements">Requirements</a></li>
<li class="toctree-l2"><a class="reference internal" href="package_README.html#build-from-git">Build from git</a></li>
<li class="toctree-l2"><a class="reference internal" href="package_README.html#building-documentation">Building documentation</a></li>
<li class="toctree-l2"><a class="reference internal" href="package_README.html#client-server-and-proxy-programs">Client, Server and Proxy programs</a></li>
<li class="toctree-l2"><a class="reference internal" href="package_README.html#benchmarking-tool">Benchmarking tool</a></li>
<li class="toctree-l2"><a class="reference internal" href="package_README.html#hpack-tools">HPACK tools</a></li>
<li class="toctree-l2"><a class="reference internal" href="package_README.html#python-bindings">Python bindings</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="tutorial-client.html">Tutorial: HTTP/2 client</a><ul>
<li class="toctree-l2"><a class="reference internal" href="tutorial-client.html#libevent-client-c">libevent-client.c</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="tutorial-server.html">Tutorial: HTTP/2 server</a><ul>
<li class="toctree-l2"><a class="reference internal" href="tutorial-server.html#libevent-server-c">libevent-server.c</a></li>
</ul>
</li>
<li class="toctree-l1 current"><a class="current reference internal" href="">Tutorial: HPACK API</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#deflating-encoding-headers">Deflating (encoding) headers</a></li>
<li class="toctree-l2"><a class="reference internal" href="#inflating-decoding-headers">Inflating (decoding) headers</a></li>
<li class="toctree-l2"><a class="reference internal" href="#deflate-c">deflate.c</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="nghttpx-howto.html">nghttpx - HTTP/2 proxy - HOW-TO</a><ul>
<li class="toctree-l2"><a class="reference internal" href="nghttpx-howto.html#default-mode">Default mode</a></li>
<li class="toctree-l2"><a class="reference internal" href="nghttpx-howto.html#http-2-proxy-mode">HTTP/2 proxy mode</a></li>
<li class="toctree-l2"><a class="reference internal" href="nghttpx-howto.html#client-mode">Client mode</a></li>
<li class="toctree-l2"><a class="reference internal" href="nghttpx-howto.html#client-proxy-mode">Client proxy mode</a></li>
<li class="toctree-l2"><a class="reference internal" href="nghttpx-howto.html#http-2-bridge-mode">HTTP/2 bridge mode</a></li>
<li class="toctree-l2"><a class="reference internal" href="nghttpx-howto.html#disable-ssl-tls">Disable SSL/TLS</a></li>
<li class="toctree-l2"><a class="reference internal" href="nghttpx-howto.html#specifying-additional-ca-certificate">Specifying additional CA certificate</a></li>
<li class="toctree-l2"><a class="reference internal" href="nghttpx-howto.html#read-write-rate-limit">Read/write rate limit</a></li>
<li class="toctree-l2"><a class="reference internal" href="nghttpx-howto.html#rewriting-location-header-field">Rewriting location header field</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="h2load-howto.html">h2load - HTTP/2 benchmarking tool - HOW-TO</a><ul>
<li class="toctree-l2"><a class="reference internal" href="h2load-howto.html#basic-usage">Basic Usage</a></li>
<li class="toctree-l2"><a class="reference internal" href="h2load-howto.html#flow-control">Flow Control</a></li>
<li class="toctree-l2"><a class="reference internal" href="h2load-howto.html#multi-threading">Multi-Threading</a></li>
<li class="toctree-l2"><a class="reference internal" href="h2load-howto.html#selecting-protocol-for-clear-text">Selecting protocol for clear text</a></li>
<li class="toctree-l2"><a class="reference internal" href="h2load-howto.html#multiple-uris">Multiple URIs</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="apiref.html">API Reference</a><ul>
<li class="toctree-l2"><a class="reference internal" href="apiref.html#includes">Includes</a></li>
<li class="toctree-l2"><a class="reference internal" href="apiref.html#remarks">Remarks</a></li>
<li class="toctree-l2"><a class="reference internal" href="apiref.html#macros">Macros</a></li>
<li class="toctree-l2"><a class="reference internal" href="apiref.html#enums">Enums</a></li>
<li class="toctree-l2"><a class="reference internal" href="apiref.html#types-structs-unions-and-typedefs">Types (structs, unions and typedefs)</a></li>
<li class="toctree-l2"><a class="reference internal" href="apiref.html#functions">Functions</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="python-apiref.html">Python API Reference</a><ul>
<li class="toctree-l2"><a class="reference internal" href="python-apiref.html#hpack-api">HPACK API</a></li>
<li class="toctree-l2"><a class="reference internal" href="python-apiref.html#http-2-servers">HTTP/2 servers</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="nghttp2.h.html">nghttp2.h</a></li>
<li class="toctree-l1"><a class="reference internal" href="nghttp2ver.h.html">nghttp2ver.h</a></li>
<li class="toctree-l1"><a class="reference external" href="https://github.com/tatsuhiro-t/nghttp2">Source</a></li>
<li class="toctree-l1"><a class="reference external" href="https://github.com/tatsuhiro-t/nghttp2/issues">Issues</a></li>
</ul>
</div>
&nbsp;
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">nghttp2</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html">Docs</a> &raquo;</li>
<li>Tutorial: HPACK API</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main">
<div class="section" id="tutorial-hpack-api">
<h1>Tutorial: HPACK API<a class="headerlink" href="#tutorial-hpack-api" title="Permalink to this headline"></a></h1>
<p>In this tutorial, we describe basic use of HPACK API in nghttp2
library. We briefly describe APIs for deflating and inflating header
fields. The example of using these APIs are presented as complete
source code <a class="reference internal" href="#deflate-c">deflate.c</a>.</p>
<div class="section" id="deflating-encoding-headers">
<h2>Deflating (encoding) headers<a class="headerlink" href="#deflating-encoding-headers" title="Permalink to this headline"></a></h2>
<p>First we need to initialize <a class="reference internal" href="apiref.html#c.nghttp2_hd_deflater" title="nghttp2_hd_deflater"><tt class="xref c c-type docutils literal"><span class="pre">nghttp2_hd_deflater</span></tt></a> object using
<a class="reference internal" href="apiref.html#c.nghttp2_hd_deflate_new" title="nghttp2_hd_deflate_new"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_deflate_new()</span></tt></a> function:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="kt">int</span> <span class="nf">nghttp2_hd_deflate_new</span><span class="p">(</span><span class="n">nghttp2_hd_deflater</span> <span class="o">**</span><span class="n">deflater_ptr</span><span class="p">,</span>
<span class="kt">size_t</span> <span class="n">deflate_hd_table_bufsize_max</span><span class="p">);</span>
</pre></div>
</div>
<p>This function allocates <a class="reference internal" href="apiref.html#c.nghttp2_hd_deflater" title="nghttp2_hd_deflater"><tt class="xref c c-type docutils literal"><span class="pre">nghttp2_hd_deflater</span></tt></a> object and
initializes it and assigns its pointer to <tt class="docutils literal"><span class="pre">*deflater_ptr</span></tt> passed by
parameter. The <em>deflate_hd_table_bufsize_max</em> is the upper bound of
header table size the deflater will use. This will limit the memory
usage in deflater object for dynamic header table. If you doubt, just
specify 4096 here, which is the default upper bound of dynamic header
table buffer size.</p>
<p>To encode header fields, <a class="reference internal" href="apiref.html#c.nghttp2_hd_deflate_hd" title="nghttp2_hd_deflate_hd"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_deflate_hd()</span></tt></a> function:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="kt">ssize_t</span> <span class="nf">nghttp2_hd_deflate_hd</span><span class="p">(</span><span class="n">nghttp2_hd_deflater</span> <span class="o">*</span><span class="n">deflater</span><span class="p">,</span>
<span class="kt">uint8_t</span> <span class="o">*</span><span class="n">buf</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">buflen</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>
</pre></div>
</div>
<p>The <em>deflater</em> is the deflater object initialized by
<a class="reference internal" href="apiref.html#c.nghttp2_hd_deflate_new" title="nghttp2_hd_deflate_new"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_deflate_new()</span></tt></a> function described above. The <em>buf</em> is a
pointer to buffer to store encoded byte string. The <em>buflen</em> is
capacity of <em>buf</em>. The <em>nva</em> is a pointer to <a class="reference internal" href="apiref.html#c.nghttp2_nv" title="nghttp2_nv"><tt class="xref c c-type docutils literal"><span class="pre">nghttp2_nv</span></tt></a>,
which is an array of header fields to deflate. The <em>nvlen</em> is the
number of header fields which <em>nva</em> contains.</p>
<p>It is important to initialize and assign all members of
<a class="reference internal" href="apiref.html#c.nghttp2_nv" title="nghttp2_nv"><tt class="xref c c-type docutils literal"><span class="pre">nghttp2_nv</span></tt></a>. If a header field should not be inserted in
dynamic header table for a security reason, set
<a class="reference internal" href="apiref.html#c.NGHTTP2_NV_FLAG_NO_INDEX" title="NGHTTP2_NV_FLAG_NO_INDEX"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_NV_FLAG_NO_INDEX</span></tt></a> flag in <a class="reference internal" href="apiref.html#c.nghttp2_nv.flags" title="nghttp2_nv.flags"><tt class="xref c c-member docutils literal"><span class="pre">nghttp2_nv.flags</span></tt></a>.</p>
<p><a class="reference internal" href="apiref.html#c.nghttp2_hd_deflate_hd" title="nghttp2_hd_deflate_hd"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_deflate_hd()</span></tt></a> processes all headers given in <em>nva</em>. The
<em>nva</em> must include all request or response header fields to be sent in
one HEADERS (or optionally following (multiple) CONTINUATION
frame(s)). The <em>buf</em> must have enough space to store the encoded
result. Otherwise, the function will fail. To estimate the upper
bound of encoded result, use <a class="reference internal" href="apiref.html#c.nghttp2_hd_deflate_bound" title="nghttp2_hd_deflate_bound"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_deflate_bound()</span></tt></a> function:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="kt">size_t</span> <span class="nf">nghttp2_hd_deflate_bound</span><span class="p">(</span><span class="n">nghttp2_hd_deflater</span> <span class="o">*</span><span class="n">deflater</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>
</pre></div>
</div>
<p>Pass this function with the same paramters <em>deflater</em>, <em>nva</em> and
<em>nvlen</em> which will be passed to <a class="reference internal" href="apiref.html#c.nghttp2_hd_deflate_hd" title="nghttp2_hd_deflate_hd"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_deflate_hd()</span></tt></a>.</p>
<p>The subsequent call of <a class="reference internal" href="apiref.html#c.nghttp2_hd_deflate_hd" title="nghttp2_hd_deflate_hd"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_deflate_hd()</span></tt></a> will use current
encoder state and perform differential encoding which is the
fundamental compression gain for HPACK.</p>
<p>Once <a class="reference internal" href="apiref.html#c.nghttp2_hd_deflate_hd" title="nghttp2_hd_deflate_hd"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_deflate_hd()</span></tt></a> fails, it cannot be undone and its
further call with the same deflater object shall fail. So it is very
important to use <a class="reference internal" href="apiref.html#c.nghttp2_hd_deflate_bound" title="nghttp2_hd_deflate_bound"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_deflate_bound()</span></tt></a> to know the required
size of buffer.</p>
<p>To delete <a class="reference internal" href="apiref.html#c.nghttp2_hd_deflater" title="nghttp2_hd_deflater"><tt class="xref c c-type docutils literal"><span class="pre">nghttp2_hd_deflater</span></tt></a> object, use <a class="reference internal" href="apiref.html#c.nghttp2_hd_deflate_del" title="nghttp2_hd_deflate_del"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_deflate_del()</span></tt></a>
function.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Generally, the order of header fields passed to
<a class="reference internal" href="apiref.html#c.nghttp2_hd_deflate_hd" title="nghttp2_hd_deflate_hd"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_deflate_hd()</span></tt></a> function is not preserved. It is known
that the relative ordering of header fields which do not share the
same name is insignificant. But some header fields sharing the
same name require the explicit ordering. To preserve this
ordering, those header values are concatenated into single header
field value using NULL (0x00) as delimiter. This is transparent to
HPACK API. Therefore, the application should examine the inflated
header values and split into multiple header field values by NULL.</p>
</div>
</div>
<div class="section" id="inflating-decoding-headers">
<h2>Inflating (decoding) headers<a class="headerlink" href="#inflating-decoding-headers" title="Permalink to this headline"></a></h2>
<p>We use <a class="reference internal" href="apiref.html#c.nghttp2_hd_inflater" title="nghttp2_hd_inflater"><tt class="xref c c-type docutils literal"><span class="pre">nghttp2_hd_inflater</span></tt></a> object to inflate compressed header
data. To initialize the object, use <a class="reference internal" href="apiref.html#c.nghttp2_hd_inflate_new" title="nghttp2_hd_inflate_new"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_inflate_new()</span></tt></a>:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="kt">int</span> <span class="nf">nghttp2_hd_inflate_new</span><span class="p">(</span><span class="n">nghttp2_hd_inflater</span> <span class="o">**</span><span class="n">inflater_ptr</span><span class="p">);</span>
</pre></div>
</div>
<p>To inflate header data, use <a class="reference internal" href="apiref.html#c.nghttp2_hd_inflate_hd" title="nghttp2_hd_inflate_hd"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_inflate_hd()</span></tt></a> function:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="kt">ssize_t</span> <span class="nf">nghttp2_hd_inflate_hd</span><span class="p">(</span><span class="n">nghttp2_hd_inflater</span> <span class="o">*</span><span class="n">inflater</span><span class="p">,</span>
<span class="n">nghttp2_nv</span> <span class="o">*</span><span class="n">nv_out</span><span class="p">,</span> <span class="kt">int</span> <span class="o">*</span><span class="n">inflate_flags</span><span class="p">,</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="kt">int</span> <span class="n">in_final</span><span class="p">);</span>
</pre></div>
</div>
<p>The <em>inflater</em> is the inflater object initialized above. The <em>nv_out</em>
is a pointer to <a class="reference internal" href="apiref.html#c.nghttp2_nv" title="nghttp2_nv"><tt class="xref c c-type docutils literal"><span class="pre">nghttp2_nv</span></tt></a> to store the result. The <em>in</em> is a
pointer to input data and <em>inlen</em> is its length. The caller is not
required to specify whole deflated header data to <em>in</em> at once. It
can call this function multiple times for portion of the data in
streaming way. If <em>in_final</em> is nonzero, it tells the function that
the passed data is the final sequence of deflated header data. The
<em>inflate_flags</em> is output parameter and successful call of this
function stores a set of flags in it. It will be described later.</p>
<p>This function returns when each header field is inflated. When this
happens, the function sets <a class="reference internal" href="apiref.html#c.NGHTTP2_HD_INFLATE_EMIT" title="NGHTTP2_HD_INFLATE_EMIT"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_HD_INFLATE_EMIT</span></tt></a> flag to
<em>inflate_flag</em> parameter and header field is stored in <em>nv_out</em>. The
return value indicates the number of data read from <em>in</em> to processed
so far. It may be less than <em>inlen</em>. The caller should call the
function repeatedly until all data are processed by adjusting <em>in</em> and
<em>inlen</em> with the processed bytes.</p>
<p>If <em>in_final</em> is nonzero and all given data was processed, the
function sets <a class="reference internal" href="apiref.html#c.NGHTTP2_HD_INFLATE_FINAL" title="NGHTTP2_HD_INFLATE_FINAL"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_HD_INFLATE_FINAL</span></tt></a> flag to
<em>inflate_flag</em>. If the caller sees this flag set, call
<a class="reference internal" href="apiref.html#c.nghttp2_hd_inflate_end_headers" title="nghttp2_hd_inflate_end_headers"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_inflate_end_headers()</span></tt></a> function.</p>
<p>If <em>in_final</em> is zero and <a class="reference internal" href="apiref.html#c.NGHTTP2_HD_INFLATE_EMIT" title="NGHTTP2_HD_INFLATE_EMIT"><tt class="xref c c-macro docutils literal"><span class="pre">NGHTTP2_HD_INFLATE_EMIT</span></tt></a> flag is not
set, it indicates that all given data was processed. The caller is
required to pass subsequent data.</p>
<p>It is important to note that the function may produce one or more
header fields even if <em>inlen</em> is 0 when <em>in_final</em> is nonzero, due to
differential encoding.</p>
<p>The example use of <a class="reference internal" href="apiref.html#c.nghttp2_hd_inflate_hd" title="nghttp2_hd_inflate_hd"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_inflate_hd()</span></tt></a> is shown in
<tt class="xref c c-func docutils literal"><span class="pre">inflate_header_block()</span></tt> function in <a class="reference internal" href="#deflate-c">deflate.c</a>.</p>
<p>To delete <a class="reference internal" href="apiref.html#c.nghttp2_hd_inflater" title="nghttp2_hd_inflater"><tt class="xref c c-type docutils literal"><span class="pre">nghttp2_hd_inflater</span></tt></a> object, use <a class="reference internal" href="apiref.html#c.nghttp2_hd_inflate_del" title="nghttp2_hd_inflate_del"><tt class="xref c c-func docutils literal"><span class="pre">nghttp2_hd_inflate_del()</span></tt></a>
function.</p>
</div>
<div class="section" id="deflate-c">
<h2>deflate.c<a class="headerlink" href="#deflate-c" title="Permalink to this headline"></a></h2>
<div class="highlight-c"><div class="highlight"><pre><span class="cm">/*</span>
<span class="cm"> * nghttp2 - HTTP/2 C Library</span>
<span class="cm"> *</span>
<span class="cm"> * Copyright (c) 2014 Tatsuhiro Tsujikawa</span>
<span class="cm"> *</span>
<span class="cm"> * Permission is hereby granted, free of charge, to any person obtaining</span>
<span class="cm"> * a copy of this software and associated documentation files (the</span>
<span class="cm"> * &quot;Software&quot;), to deal in the Software without restriction, including</span>
<span class="cm"> * without limitation the rights to use, copy, modify, merge, publish,</span>
<span class="cm"> * distribute, sublicense, and/or sell copies of the Software, and to</span>
<span class="cm"> * permit persons to whom the Software is furnished to do so, subject to</span>
<span class="cm"> * the following conditions:</span>
<span class="cm"> *</span>
<span class="cm"> * The above copyright notice and this permission notice shall be</span>
<span class="cm"> * included in all copies or substantial portions of the Software.</span>
<span class="cm"> *</span>
<span class="cm"> * THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,</span>
<span class="cm"> * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF</span>
<span class="cm"> * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND</span>
<span class="cm"> * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE</span>
<span class="cm"> * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION</span>
<span class="cm"> * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION</span>
<span class="cm"> * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</span>
<span class="cm"> */</span>
<span class="cp">#include &lt;stdio.h&gt;</span>
<span class="cp">#include &lt;string.h&gt;</span>
<span class="cp">#include &lt;nghttp2/nghttp2.h&gt;</span>
<span class="cp">#define MAKE_NV(K, V) \</span>
<span class="cp"> { (uint8_t*)K, (uint8_t*)V, sizeof(K) - 1, sizeof(V) - 1, \</span>
<span class="cp"> NGHTTP2_NV_FLAG_NONE }</span>
<span class="k">static</span> <span class="kt">void</span> <span class="nf">deflate</span><span class="p">(</span><span class="n">nghttp2_hd_deflater</span> <span class="o">*</span><span class="n">deflater</span><span class="p">,</span>
<span class="n">nghttp2_hd_inflater</span> <span class="o">*</span><span class="n">inflater</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_nv</span> <span class="o">*</span> <span class="k">const</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">static</span> <span class="kt">int</span> <span class="nf">inflate_header_block</span><span class="p">(</span><span class="n">nghttp2_hd_inflater</span> <span class="o">*</span><span class="n">inflater</span><span class="p">,</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="kt">int</span> <span class="n">final</span><span class="p">);</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="n">argv</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="n">nghttp2_hd_deflater</span> <span class="o">*</span><span class="n">deflater</span><span class="p">;</span>
<span class="n">nghttp2_hd_inflater</span> <span class="o">*</span><span class="n">inflater</span><span class="p">;</span>
<span class="cm">/* Define 1st header set. This is looks like a HTTP request. */</span>
<span class="n">nghttp2_nv</span> <span class="n">nva1</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span>
<span class="n">MAKE_NV</span><span class="p">(</span><span class="s">&quot;:scheme&quot;</span><span class="p">,</span> <span class="s">&quot;https&quot;</span><span class="p">),</span>
<span class="n">MAKE_NV</span><span class="p">(</span><span class="s">&quot;:authority&quot;</span><span class="p">,</span> <span class="s">&quot;example.org&quot;</span><span class="p">),</span>
<span class="n">MAKE_NV</span><span class="p">(</span><span class="s">&quot;:path&quot;</span><span class="p">,</span> <span class="s">&quot;/&quot;</span><span class="p">),</span>
<span class="n">MAKE_NV</span><span class="p">(</span><span class="s">&quot;user-agent&quot;</span><span class="p">,</span> <span class="s">&quot;libnghttp2&quot;</span><span class="p">),</span>
<span class="n">MAKE_NV</span><span class="p">(</span><span class="s">&quot;accept-encoding&quot;</span><span class="p">,</span> <span class="s">&quot;gzip, deflate&quot;</span><span class="p">)</span>
<span class="p">};</span>
<span class="cm">/* Define 2nd header set */</span>
<span class="n">nghttp2_nv</span> <span class="n">nva2</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span>
<span class="n">MAKE_NV</span><span class="p">(</span><span class="s">&quot;:scheme&quot;</span><span class="p">,</span> <span class="s">&quot;https&quot;</span><span class="p">),</span>
<span class="n">MAKE_NV</span><span class="p">(</span><span class="s">&quot;:authority&quot;</span><span class="p">,</span> <span class="s">&quot;example.org&quot;</span><span class="p">),</span>
<span class="n">MAKE_NV</span><span class="p">(</span><span class="s">&quot;:path&quot;</span><span class="p">,</span> <span class="s">&quot;/stylesheet/style.css&quot;</span><span class="p">),</span>
<span class="n">MAKE_NV</span><span class="p">(</span><span class="s">&quot;user-agent&quot;</span><span class="p">,</span> <span class="s">&quot;libnghttp2&quot;</span><span class="p">),</span>
<span class="n">MAKE_NV</span><span class="p">(</span><span class="s">&quot;accept-encoding&quot;</span><span class="p">,</span> <span class="s">&quot;gzip, deflate&quot;</span><span class="p">),</span>
<span class="n">MAKE_NV</span><span class="p">(</span><span class="s">&quot;referer&quot;</span><span class="p">,</span> <span class="s">&quot;https://example.org&quot;</span><span class="p">)</span>
<span class="p">};</span>
<span class="n">rv</span> <span class="o">=</span> <span class="n">nghttp2_hd_deflate_new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">deflater</span><span class="p">,</span> <span class="mi">4096</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">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;nghttp2_hd_deflate_init failed with error: %s</span><span class="se">\n</span><span class="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">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">rv</span> <span class="o">=</span> <span class="n">nghttp2_hd_inflate_new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">inflater</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">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&quot;nghttp2_hd_inflate_init failed with error: %s</span><span class="se">\n</span><span class="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">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Encode and decode 1st header set */</span>
<span class="n">deflate</span><span class="p">(</span><span class="n">deflater</span><span class="p">,</span> <span class="n">inflater</span><span class="p">,</span> <span class="n">nva1</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">nva1</span><span class="p">)</span> <span class="o">/</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">nva1</span><span class="p">[</span><span class="mi">0</span><span class="p">]));</span>
<span class="cm">/* Encode and decode 2nd header set, using differential encoding</span>
<span class="cm"> using state after encoding 1st header set. */</span>
<span class="n">deflate</span><span class="p">(</span><span class="n">deflater</span><span class="p">,</span> <span class="n">inflater</span><span class="p">,</span> <span class="n">nva2</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">nva2</span><span class="p">)</span> <span class="o">/</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">nva2</span><span class="p">[</span><span class="mi">0</span><span class="p">]));</span>
<span class="n">nghttp2_hd_inflate_del</span><span class="p">(</span><span class="n">inflater</span><span class="p">);</span>
<span class="n">nghttp2_hd_deflate_del</span><span class="p">(</span><span class="n">deflater</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">void</span> <span class="nf">deflate</span><span class="p">(</span><span class="n">nghttp2_hd_deflater</span> <span class="o">*</span><span class="n">deflater</span><span class="p">,</span>
<span class="n">nghttp2_hd_inflater</span> <span class="o">*</span><span class="n">inflater</span><span class="p">,</span>
<span class="k">const</span> <span class="n">nghttp2_nv</span> <span class="o">*</span> <span class="k">const</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="p">{</span>
<span class="kt">ssize_t</span> <span class="n">rv</span><span class="p">;</span>
<span class="kt">uint8_t</span> <span class="o">*</span><span class="n">buf</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">buflen</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">outlen</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">sum</span><span class="p">;</span>
<span class="n">sum</span> <span class="o">=</span> <span class="mi">0</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">sum</span> <span class="o">+=</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="o">+</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="p">}</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;Input (%zu byte(s)):</span><span class="se">\n\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">sum</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">stdout</span><span class="p">);</span>
<span class="n">printf</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">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">stdout</span><span class="p">);</span>
<span class="n">printf</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="n">buflen</span> <span class="o">=</span> <span class="n">nghttp2_hd_deflate_bound</span><span class="p">(</span><span class="n">deflater</span><span class="p">,</span> <span class="n">nva</span><span class="p">,</span> <span class="n">nvlen</span><span class="p">);</span>
<span class="n">buf</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="n">buflen</span><span class="p">);</span>
<span class="n">rv</span> <span class="o">=</span> <span class="n">nghttp2_hd_deflate_hd</span><span class="p">(</span><span class="n">deflater</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="n">buflen</span><span class="p">,</span> <span class="n">nva</span><span class="p">,</span> <span class="n">nvlen</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">rv</span> <span class="o">&lt;</span> <span class="mi">0</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;nghttp2_hd_deflate_hd() failed with error: %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">nghttp2_strerror</span><span class="p">((</span><span class="kt">int</span><span class="p">)</span><span class="n">rv</span><span class="p">));</span>
<span class="n">free</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">outlen</span> <span class="o">=</span> <span class="n">rv</span><span class="p">;</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">Deflate (%zu byte(s), ratio %.02f):</span><span class="se">\n\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">outlen</span><span class="p">,</span> <span class="p">(</span><span class="kt">double</span><span class="p">)</span><span class="n">outlen</span> <span class="o">/</span> <span class="n">sum</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">outlen</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">if</span><span class="p">((</span><span class="n">i</span> <span class="o">&amp;</span> <span class="mh">0x0fu</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;%08zX: &quot;</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;%02X &quot;</span><span class="p">,</span> <span class="n">buf</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">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x0fu</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">printf</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">printf</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n\n</span><span class="s">Inflate:</span><span class="se">\n\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="cm">/* We pass 1 to final parameter, because buf contains whole deflated</span>
<span class="cm"> header data. */</span>
<span class="n">rv</span> <span class="o">=</span> <span class="n">inflate_header_block</span><span class="p">(</span><span class="n">inflater</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="n">outlen</span><span class="p">,</span> <span class="mi">1</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">free</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="n">EXIT_FAILURE</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">-----------------------------------------------------------&quot;</span>
<span class="s">&quot;--------------------</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">inflate_header_block</span><span class="p">(</span><span class="n">nghttp2_hd_inflater</span> <span class="o">*</span><span class="n">inflater</span><span class="p">,</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="kt">int</span> <span class="n">final</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">ssize_t</span> <span class="n">rv</span><span class="p">;</span>
<span class="k">for</span><span class="p">(;;)</span> <span class="p">{</span>
<span class="n">nghttp2_nv</span> <span class="n">nv</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">inflate_flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">proclen</span><span class="p">;</span>
<span class="n">rv</span> <span class="o">=</span> <span class="n">nghttp2_hd_inflate_hd</span><span class="p">(</span><span class="n">inflater</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">nv</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">inflate_flags</span><span class="p">,</span>
<span class="n">in</span><span class="p">,</span> <span class="n">inlen</span><span class="p">,</span> <span class="n">final</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">rv</span> <span class="o">&lt;</span> <span class="mi">0</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;inflate failed with error code %zd&quot;</span><span class="p">,</span> <span class="n">rv</span><span class="p">);</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">proclen</span> <span class="o">=</span> <span class="n">rv</span><span class="p">;</span>
<span class="n">in</span> <span class="o">+=</span> <span class="n">proclen</span><span class="p">;</span>
<span class="n">inlen</span> <span class="o">-=</span> <span class="n">proclen</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span><span class="n">inflate_flags</span> <span class="o">&amp;</span> <span class="n">NGHTTP2_HD_INFLATE_EMIT</span><span class="p">)</span> <span class="p">{</span>
<span class="n">fwrite</span><span class="p">(</span><span class="n">nv</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="n">nv</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">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">fwrite</span><span class="p">(</span><span class="n">nv</span><span class="p">.</span><span class="n">value</span><span class="p">,</span> <span class="n">nv</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">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="k">if</span><span class="p">(</span><span class="n">inflate_flags</span> <span class="o">&amp;</span> <span class="n">NGHTTP2_HD_INFLATE_FINAL</span><span class="p">)</span> <span class="p">{</span>
<span class="n">nghttp2_hd_inflate_end_headers</span><span class="p">(</span><span class="n">inflater</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">inflate_flags</span> <span class="o">&amp;</span> <span class="n">NGHTTP2_HD_INFLATE_EMIT</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span>
<span class="n">inlen</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</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>
</div>
</div>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href="nghttpx-howto.html" class="btn btn-neutral float-right" title="nghttpx - HTTP/2 proxy - HOW-TO">Next <span class="fa fa-arrow-circle-right"></span></a>
<a href="tutorial-server.html" class="btn btn-neutral" title="Tutorial: HTTP/2 server"><span class="fa fa-arrow-circle-left"></span> Previous</a>
</div>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2012, 2014, Tatsuhiro Tsujikawa.
</p>
</div>
<a href="https://github.com/snide/sphinx_rtd_theme">Sphinx theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'./',
VERSION:'0.4.2-DEV',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: false
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
});
</script>
</body>
</html>