-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathhello_world_server.html
240 lines (220 loc) · 16.5 KB
/
hello_world_server.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
<!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>“Hello world” HTTP server — 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="Examples" href="../../examples.html" />
<link rel="next" title="“Hello world” HTTP client" href="hello_world_client.html" />
<link rel="prev" title="Simple wget" href="simple_wget.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="hello_world_client.html" title="“Hello world” HTTP client"
accesskey="N">next</a></li>
<li class="right" >
<a href="simple_wget.html" title="Simple wget"
accesskey="P">previous</a> |</li>
<li><a href="../../contents.html">cpp-netlib v0.10.0</a> »</li>
<li><a href="../../examples.html" accesskey="U">Examples</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="hello-world-http-server">
<span id="id1"></span><h1>“Hello world” HTTP server<a class="headerlink" href="#hello-world-http-server" title="Permalink to this headline">¶</a></h1>
<p>Now that we’ve seen how we can deal with request and response objects from the
client side, we’ll see how we can then use the same abstractions on the server
side. In this example we’re going to create a simple HTTP Server in C++ using
<tt class="xref py py-mod docutils literal"><span class="pre">cpp-netlib</span></tt>.</p>
<div class="section" id="the-code">
<h2>The code<a class="headerlink" href="#the-code" title="Permalink to this headline">¶</a></h2>
<p>The <tt class="xref py py-mod docutils literal"><span class="pre">cpp-netlib</span></tt> provides the framework to develop embedded HTTP
servers. For this example, the server is configured to return a
simple response to any HTTP request.</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="cp">#include <boost/network/protocol/http/server.hpp></span>
<span class="cp">#include <string></span>
<span class="cp">#include <iostream></span>
<span class="k">namespace</span> <span class="n">http</span> <span class="o">=</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="p">;</span>
<span class="k">struct</span> <span class="n">hello_world</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">hello_world</span><span class="o">></span> <span class="n">server</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">hello_world</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="n">server</span><span class="o">::</span><span class="n">request</span> <span class="k">const</span> <span class="o">&</span><span class="n">request</span><span class="p">,</span>
<span class="n">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="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">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">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">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="s">"Hello, "</span><span class="p">)</span> <span class="o">+</span> <span class="n">ip</span> <span class="o">+</span> <span class="s">"!"</span><span class="p">);</span>
<span class="p">}</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="k">if</span> <span class="p">(</span><span class="n">argc</span> <span class="o">!=</span> <span class="mi">3</span><span class="p">)</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">"Usage: "</span> <span class="o"><<</span> <span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o"><<</span> <span class="s">" address port"</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="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">try</span> <span class="p">{</span>
<span class="n">hello_world</span> <span class="n">handler</span><span class="p">;</span>
<span class="n">server</span> <span class="n">server_</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">handler</span><span class="p">);</span>
<span class="n">server_</span><span class="p">.</span><span class="n">run</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">catch</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">exception</span> <span class="o">&</span><span class="n">e</span><span class="p">)</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="n">e</span><span class="p">.</span><span class="n">what</span><span class="p">()</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="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>This is about a straightforward as server programming will get in C++.</p>
</div>
<div class="section" id="building-and-running-the-server">
<h2>Building and running the server<a class="headerlink" href="#building-and-running-the-server" title="Permalink to this headline">¶</a></h2>
<p>Just like with the HTTP client, we can build this example by doing the following
on the shell:</p>
<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span><span class="nb">cd</span> ~/cpp-netlib-build
<span class="nv">$ </span>make hello_world_server
</pre></div>
</div>
<p>The first two arguments to the <tt class="docutils literal"><span class="pre">server</span></tt> constructor are the host and
the port on which the server will listen. The third argument is the
the handler object defined previously. This example can be run from
a command line as follows:</p>
<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>./example/hello_world_server 0.0.0.0 8000
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you’re going to run the server on port 80, you may have to run it
as an administrator.</p>
</div>
</div>
<div class="section" id="diving-into-the-code">
<h2>Diving into the code<a class="headerlink" href="#diving-into-the-code" title="Permalink to this headline">¶</a></h2>
<p>Let’s take a look at the code listing above in greater detail.</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="cp">#include <boost/network/protocol/http/server.hpp></span>
</pre></div>
</div>
<p>This header contains all the code needed to develop an HTTP server with
<tt class="xref py py-mod docutils literal"><span class="pre">cpp-netlib</span></tt>.</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">struct</span> <span class="n">hello_world</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">hello_world</span><span class="o">></span> <span class="n">server</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">hello_world</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="n">server</span><span class="o">::</span><span class="n">request</span> <span class="k">const</span> <span class="o">&</span><span class="n">request</span><span class="p">,</span>
<span class="n">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="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">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">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">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="s">"Hello, "</span><span class="p">)</span> <span class="o">+</span> <span class="n">ip</span> <span class="o">+</span> <span class="s">"!"</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">};</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">hello_world</span></tt> is a functor class which handles HTTP requests. All
the operator does here is return an HTTP response with HTTP code 200
and the body <tt class="docutils literal"><span class="pre">"Hello,</span> <span class="pre"><ip>!"</span></tt>. The <tt class="docutils literal"><span class="pre"><ip></span></tt> in this case would be
the IP address of the client that made the request.</p>
<p>There are a number of pre-defined stock replies differentiated by
status code with configurable bodies.</p>
<p>All the supported enumeration values for the response status codes can be found
in <tt class="docutils literal"><span class="pre">boost/network/protocol/http/impl/response.ipp</span></tt>.</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">hello_world</span> <span class="n">handler</span><span class="p">;</span>
<span class="n">server</span> <span class="nf">server_</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">handler</span><span class="p">);</span>
<span class="n">server_</span><span class="p">.</span><span class="n">run</span><span class="p">();</span>
</pre></div>
</div>
<p>The first two arguments to the <tt class="docutils literal"><span class="pre">server</span></tt> constructor are the host and
the port on which the server will listen. The third argument is the
the handler object defined previously.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">In this example, the server is specifically made to be single-threaded.
In a multi-threaded server, you would invoke the <tt class="docutils literal"><span class="pre">hello_world::run</span></tt> member
method in a set of threads. In a multi-threaded environment you would also
make sure that the handler does all the necessary synchronization for shared
resources across threads. The handler is passed by reference to the server
constructor and you should ensure that any calls to the <tt class="docutils literal"><span class="pre">operator()</span></tt> overload
are thread-safe.</p>
</div>
</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="#">“Hello world” HTTP server</a><ul>
<li><a class="reference internal" href="#the-code">The code</a></li>
<li><a class="reference internal" href="#building-and-running-the-server">Building and running the server</a></li>
<li><a class="reference internal" href="#diving-into-the-code">Diving into the code</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="simple_wget.html"
title="previous chapter">Simple <cite>wget</cite></a></p>
<h4>Next topic</h4>
<p class="topless"><a href="hello_world_client.html"
title="next chapter">“Hello world” HTTP client</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="hello_world_client.html" title="“Hello world” HTTP client"
>next</a></li>
<li class="right" >
<a href="simple_wget.html" title="Simple wget"
>previous</a> |</li>
<li><a href="../../contents.html">cpp-netlib v0.10.0</a> »</li>
<li><a href="../../examples.html" >Examples</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>