-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathhttp.html
311 lines (287 loc) · 22.7 KB
/
http.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>HTTP implementation — cpp-netlib v0.10.0</title>
<link rel="stylesheet" href="../_static/pyramid.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.10.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</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>
<link rel="top" title="cpp-netlib v0.10.0" href="../index.html" />
<link rel="up" title="An in-depth look at the cpp-netlib" href="../in_depth.html" />
<link rel="next" title="Techniques" href="../techniques.html" />
<link rel="prev" title="The URI class" href="uri.html" />
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Neuton&subset=latin" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Nobile:regular,italic,bold,bolditalic&subset=latin" type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet" href="../_static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../techniques.html" title="Techniques"
accesskey="N">next</a></li>
<li class="right" >
<a href="uri.html" title="The URI class"
accesskey="P">previous</a> |</li>
<li><a href="../contents.html">cpp-netlib v0.10.0</a> »</li>
<li><a href="../in_depth.html" accesskey="U">An in-depth look at the <tt class="docutils literal docutils literal docutils literal docutils literal"><span class="pre">cpp-netlib</span></tt></a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="http-implementation">
<h1>HTTP implementation<a class="headerlink" href="#http-implementation" title="Permalink to this headline">¶</a></h1>
<div class="section" id="http-client">
<h2>HTTP client<a class="headerlink" href="#http-client" title="Permalink to this headline">¶</a></h2>
<p>At the heart of the HTTP client implementation is a single class aptly named
<tt class="docutils literal"><span class="pre">basic_client</span></tt>, which is also a template. The template <tt class="docutils literal"><span class="pre">basic_client</span></tt> takes
three template parameters:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span> <span class="k">namespace</span> <span class="n">http</span> <span class="p">{</span>
<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Tag</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">version_major</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">version_minor</span><span class="o">></span>
<span class="k">struct</span> <span class="n">basic_client</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace http</span>
<span class="p">}</span> <span class="c1">// namespace boost</span>
</pre></div>
</div>
<p>The <tt class="docutils literal"><span class="pre">Tag</span></tt> template parameter follows the same tag-dispatch mechanism to
determine the behavior of the <tt class="docutils literal"><span class="pre">basic_client</span></tt>. The interface of
<tt class="docutils literal"><span class="pre">basic_client</span></tt> may change depending on certain properties defined for the tag
you provide. Below is a table of predefined supported tags you can use in your
overload of the <tt class="docutils literal"><span class="pre">basic_client</span></tt>:</p>
<hr class="docutils" />
<table border="1" class="docutils">
<colgroup>
<col width="42%" />
<col width="58%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Tag</th>
<th class="head">Description</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>http_default_8bit_tcp_resolve</td>
<td>This is the default HTTP implementation tag
that resolves addresses with a TCP resolver
and provides a synchronous/blocking HTTP
client interface.</td>
</tr>
<tr class="row-odd"><td>http_default_8bit_udp_resolve</td>
<td>This is similar to the above tag except that
it specifies the HTTP client to use a UDP
resolver. It also provides a synchronous/
blocking HTTP client interface.</td>
</tr>
<tr class="row-even"><td>http_keepalive_8bit_tcp_resolve</td>
<td>This tag specifies that the HTTP client by
default will keep connections to the server
alive. It only makes sense if the
<tt class="docutils literal"><span class="pre">version_major</span></tt> and <tt class="docutils literal"><span class="pre">version_minor</span></tt> are
both <tt class="docutils literal"><span class="pre">1</span></tt>, to indicate HTTP 1.1. This tag
causes the HTTP client to resolve using a
TCP resolver and provides a synchronous/
blocking HTTP client interface.</td>
</tr>
<tr class="row-odd"><td>http_keepalive_8bit_udp_resolve</td>
<td>This is similar to the above tag except that
it specifies the HTTP client to use a UDP
resolver. It also provides a synchronous/
blocking HTTP client interface.</td>
</tr>
<tr class="row-even"><td>http_async_8bit_tcp_resolve</td>
<td>This tag provides an active HTTP client
object implementation that uses a TCP
resolver. Response objects returned will
encapsulate a number of <a class="reference external" href="http://www.boost.org/libs/thread">Boost.Thread</a>
shared futures to hold values. Users don’t
have to see this as they are implementation
details.</td>
</tr>
<tr class="row-odd"><td>http_async_8bit_udp_resolve</td>
<td>This is similar to the above tag except that
specifies the HTTP client to use a UDP
resolver.</td>
</tr>
</tbody>
</table>
<p>The default typedef for the HTTP client that is provided uses the
<tt class="docutils literal"><span class="pre">http_async_8bit_udp_resolve</span></tt> tag, and implements HTTP 1.1. The exact
typedef is in the <tt class="docutils literal"><span class="pre">boost::network::http</span></tt> namespace as the following:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span> <span class="k">namespace</span> <span class="n">network</span> <span class="p">{</span> <span class="k">namespace</span> <span class="n">http</span> <span class="p">{</span>
<span class="k">typedef</span> <span class="n">basic_client</span><span class="o"><</span><span class="n">tags</span><span class="o">::</span><span class="n">http_async_8bit_udp_resolve</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="o">></span>
<span class="n">client</span><span class="p">;</span>
<span class="p">}}}</span>
</pre></div>
</div>
<p>This type has nested typedefs for the correct types for the <tt class="docutils literal"><span class="pre">basic_request</span></tt>
and <tt class="docutils literal"><span class="pre">basic_response</span></tt> templates. To use the correct types for <tt class="docutils literal"><span class="pre">basic_request</span></tt>
or <tt class="docutils literal"><span class="pre">basic_response</span></tt> you can use these nested typedefs like so:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">boost</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">http</span><span class="o">::</span><span class="n">client</span><span class="o">::</span><span class="n">request</span> <span class="n">request</span><span class="p">;</span>
<span class="n">boost</span><span class="o">::</span><span class="n">network</span><span class="o">::</span><span class="n">http</span><span class="o">::</span><span class="n">client</span><span class="o">::</span><span class="n">response</span> <span class="n">response</span><span class="p">;</span>
<span class="c1">// or...</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="o">::</span><span class="n">network</span><span class="p">;</span>
<span class="n">http</span><span class="o">::</span><span class="n">client</span><span class="o">::</span><span class="n">request</span> <span class="n">request</span><span class="p">;</span>
<span class="n">http</span><span class="o">::</span><span class="n">client</span><span class="o">::</span><span class="n">response</span> <span class="n">response</span><span class="p">;</span>
</pre></div>
</div>
<p>Typical use cases for the HTTP client would look something like the following:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="o">::</span><span class="n">network</span><span class="p">;</span>
<span class="n">http</span><span class="o">::</span><span class="n">request</span> <span class="n">request</span><span class="p">(</span><span class="s">"http://www.boost.org/"</span><span class="p">);</span>
<span class="n">request</span> <span class="o"><<</span> <span class="n">header</span><span class="p">(</span><span class="s">"Connection"</span><span class="p">,</span> <span class="s">"close"</span><span class="p">);</span>
</pre></div>
</div>
<p>The <tt class="docutils literal"><span class="pre">basic_client</span></tt> implements all HTTP methods as member functions
(HEAD, GET, POST, PUT, DELETE). Therefore, the code to make an HTTP
request looks trivially simple:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="o">::</span><span class="n">network</span><span class="p">;</span>
<span class="n">http</span><span class="o">::</span><span class="n">client</span> <span class="n">client</span><span class="p">;</span>
<span class="n">http</span><span class="o">::</span><span class="n">client</span><span class="o">::</span><span class="n">request</span> <span class="n">request</span><span class="p">(</span><span class="s">"http://www.boost.org/"</span><span class="p">);</span>
<span class="n">http</span><span class="o">::</span><span class="n">client</span><span class="o">::</span><span class="n">response</span> <span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">request</span><span class="p">);</span>
</pre></div>
</div>
<p>Accessing data from <tt class="docutils literal"><span class="pre">http::response</span></tt> is done using wrappers.
To get the response headers, we use the <tt class="docutils literal"><span class="pre">headers</span></tt> wrapper which
returns, in the default case, a multimap of strings to strings:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="o">::</span><span class="n">network</span><span class="p">;</span>
<span class="k">typedef</span> <span class="n">headers_range</span><span class="o"><</span><span class="n">http_client</span><span class="o">::</span><span class="n">response</span><span class="o">>::</span><span class="n">type</span> <span class="n">response_headers</span><span class="p">;</span>
<span class="n">boost</span><span class="o">::</span><span class="n">range_iterator</span><span class="o"><</span><span class="n">response_headers</span><span class="o">>::</span><span class="n">type</span> <span class="n">iterator</span><span class="p">;</span>
<span class="n">response_headers</span> <span class="n">headers_</span> <span class="o">=</span> <span class="n">headers</span><span class="p">(</span><span class="n">response</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="n">iterator</span> <span class="n">it</span> <span class="o">=</span> <span class="n">headers_</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span> <span class="n">it</span> <span class="o">!=</span> <span class="n">headers_</span><span class="p">.</span><span class="n">end</span><span class="p">();</span> <span class="o">++</span><span class="n">it</span><span class="p">)</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">it</span><span class="o">-></span><span class="n">first</span> <span class="o"><<</span> <span class="s">": "</span> <span class="o"><<</span> <span class="n">it</span><span class="o">-></span><span class="n">second</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
</pre></div>
</div>
</div>
<div class="section" id="http-server">
<h2>HTTP server<a class="headerlink" href="#http-server" title="Permalink to this headline">¶</a></h2>
<p>As with the HTTP client, the HTTP server that is provided with
cpp-netlib is extensible through the tag mechanism and is embeddable.
The template class declaration of <tt class="docutils literal"><span class="pre">basic_server</span></tt> is given below:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span> <span class="k">namespace</span> <span class="n">network</span> <span class="p">{</span> <span class="k">namespace</span> <span class="n">http</span> <span class="p">{</span>
<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Tag</span><span class="p">,</span> <span class="k">class</span> <span class="nc">RequestHandler</span><span class="o">></span> <span class="n">basic_server</span><span class="p">;</span>
<span class="p">}}}</span>
</pre></div>
</div>
<p>The second template argument is used to specify the request handler
type. The request handler type is a functor type which should overload
the function call operator (<tt class="docutils literal"><span class="pre">RequestHandler::operator()</span></tt> should be
overloaded) that takes two parameters: the first one being a reference
to a <tt class="docutils literal"><span class="pre">const</span> <span class="pre">basic_request<Tag></span></tt> and the second being a reference to
a <tt class="docutils literal"><span class="pre">basic_response<Tag></span></tt> instance.</p>
<p>All the logic for parsing the HTTP request and building the <tt class="docutils literal"><span class="pre">const</span>
<span class="pre">basic_request<Tag></span></tt> object resides internally in the <tt class="docutils literal"><span class="pre">basic_server</span></tt>
template. Processing the request is delegated to the
<tt class="docutils literal"><span class="pre">RequestHandler</span></tt> type, and the assumption of which would be that the
response is formed inside the <tt class="docutils literal"><span class="pre">RequestHandler</span></tt> function call
operator overload.</p>
<p>The <tt class="docutils literal"><span class="pre">basic_server</span></tt> template however is only an underlying
implementation while the user-visible implementation is the
<tt class="docutils literal"><span class="pre">http::server</span></tt> template. This simply specializes the
<tt class="docutils literal"><span class="pre">basic_server</span></tt> template to use the <tt class="docutils literal"><span class="pre">default_</span></tt> tag and forwards the
<tt class="docutils literal"><span class="pre">RequestHandler</span></tt> parameter:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span> <span class="k">namespace</span> <span class="n">network</span> <span class="p">{</span> <span class="k">namespace</span> <span class="n">http</span> <span class="p">{</span>
<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">RequestHandler</span><span class="o">></span>
<span class="k">class</span> <span class="nc">server</span> <span class="o">:</span>
<span class="k">public</span> <span class="n">basic_server</span><span class="o"><</span><span class="n">default_</span><span class="p">,</span> <span class="n">RequestHandler</span><span class="o">></span> <span class="p">{};</span>
<span class="p">}}}</span>
</pre></div>
</div>
<p>To use the forwarding server type you just supply the request handler
implementation as the parameter. For example, an “echo” server example
might look something like this:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="o">::</span><span class="n">network</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">echo</span><span class="p">;</span>
<span class="k">typedef</span> <span class="n">http</span><span class="o">::</span><span class="n">server</span><span class="o"><</span><span class="n">echo</span><span class="o">></span> <span class="n">echo_server</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">echo</span> <span class="p">{</span>
<span class="kt">void</span> <span class="k">operator</span> <span class="p">()</span> <span class="p">(</span><span class="k">const</span> <span class="n">echo_server</span><span class="o">::</span><span class="n">request</span> <span class="o">&</span><span class="n">request</span><span class="p">,</span>
<span class="n">echo_server</span><span class="o">::</span><span class="n">response</span> <span class="o">&</span><span class="n">response</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">ip</span> <span class="o">=</span> <span class="n">source</span><span class="p">(</span><span class="n">request</span><span class="p">);</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">echo_server</span><span class="o">::</span><span class="n">response</span><span class="o">::</span><span class="n">stock_reply</span><span class="p">(</span>
<span class="n">echo_server</span><span class="o">::</span><span class="n">response</span><span class="o">::</span><span class="n">ok</span><span class="p">,</span>
<span class="n">body</span><span class="p">(</span><span class="n">request</span><span class="p">));</span>
<span class="n">std</span><span class="o">::</span><span class="n">cerr</span> <span class="o"><<</span> <span class="s">"["</span> <span class="o"><<</span> <span class="n">ip</span> <span class="o"><<</span> <span class="s">"]: "</span> <span class="o"><<</span> <span class="n">request</span><span class="p">.</span><span class="n">uri</span> <span class="o"><<</span>
<span class="s">" status = "</span> <span class="o"><<</span> <span class="n">echo_server</span><span class="o">::</span><span class="n">response</span><span class="o">::</span><span class="n">ok</span> <span class="o"><<</span> <span class="sc">'\n'</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">};</span>
</pre></div>
</div>
<p>Here, all we’re doing is returning the original request body with an
HTTP OK response (200). We are also printing the IP address from where the
request came from. Notice that we are using a wrapper to access the source of
the request.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">HTTP implementation</a><ul>
<li><a class="reference internal" href="#http-client">HTTP client</a></li>
<li><a class="reference internal" href="#http-server">HTTP server</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="uri.html"
title="previous chapter">The URI class</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="../techniques.html"
title="next chapter">Techniques</a></p>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../techniques.html" title="Techniques"
>next</a></li>
<li class="right" >
<a href="uri.html" title="The URI class"
>previous</a> |</li>
<li><a href="../contents.html">cpp-netlib v0.10.0</a> »</li>
<li><a href="../in_depth.html" >An in-depth look at the <tt class="docutils literal docutils literal docutils literal docutils literal"><span class="pre">cpp-netlib</span></tt></a> »</li>
</ul>
</div>
<div class="footer">
© Copyright 2008-2013, Glyn Matthews, Dean Michael Berris; 2013 Google, Inc..
Last updated on Jul 05, 2013.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1.
</div>
</body>
</html>