~ubuntu-branches/debian/sid/pion/sid

« back to all changes in this revision

Viewing changes to doc/html/http__server_8cpp_source.html

  • Committer: Package Import Robot
  • Author(s): Roberto C. Sanchez
  • Date: 2013-08-03 11:53:18 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20130803115318-3cees1yi7csq8j3m
Tags: 5.0.3+dfsg-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
<a name="l00008"></a>00008 <span class="comment">//</span>
32
32
<a name="l00009"></a>00009 
33
33
<a name="l00010"></a>00010 <span class="preprocessor">#include &lt;boost/exception/diagnostic_information.hpp&gt;</span>
34
 
<a name="l00011"></a>00011 <span class="preprocessor">#include &lt;pion/http/server.hpp&gt;</span>
35
 
<a name="l00012"></a>00012 <span class="preprocessor">#include &lt;pion/http/request.hpp&gt;</span>
36
 
<a name="l00013"></a>00013 <span class="preprocessor">#include &lt;pion/http/request_reader.hpp&gt;</span>
37
 
<a name="l00014"></a>00014 <span class="preprocessor">#include &lt;pion/http/response_writer.hpp&gt;</span>
38
 
<a name="l00015"></a>00015 
 
34
<a name="l00011"></a>00011 <span class="preprocessor">#include &lt;pion/algorithm.hpp&gt;</span>
 
35
<a name="l00012"></a>00012 <span class="preprocessor">#include &lt;pion/http/server.hpp&gt;</span>
 
36
<a name="l00013"></a>00013 <span class="preprocessor">#include &lt;pion/http/request.hpp&gt;</span>
 
37
<a name="l00014"></a>00014 <span class="preprocessor">#include &lt;pion/http/request_reader.hpp&gt;</span>
 
38
<a name="l00015"></a>00015 <span class="preprocessor">#include &lt;pion/http/response_writer.hpp&gt;</span>
39
39
<a name="l00016"></a>00016 
40
 
<a name="l00017"></a>00017 <span class="keyword">namespace </span>pion {    <span class="comment">// begin namespace pion</span>
41
 
<a name="l00018"></a>00018 <span class="keyword">namespace </span>http {    <span class="comment">// begin namespace http</span>
42
 
<a name="l00019"></a>00019 
 
40
<a name="l00017"></a>00017 
 
41
<a name="l00018"></a>00018 <span class="keyword">namespace </span>pion {    <span class="comment">// begin namespace pion</span>
 
42
<a name="l00019"></a>00019 <span class="keyword">namespace </span>http {    <span class="comment">// begin namespace http</span>
43
43
<a name="l00020"></a>00020 
44
 
<a name="l00021"></a>00021 <span class="comment">// static members of server</span>
45
 
<a name="l00022"></a>00022 
46
 
<a name="l00023"></a>00023 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>          server::MAX_REDIRECTS = 10;
47
 
<a name="l00024"></a>00024 
 
44
<a name="l00021"></a>00021 
 
45
<a name="l00022"></a>00022 <span class="comment">// static members of server</span>
 
46
<a name="l00023"></a>00023 
 
47
<a name="l00024"></a>00024 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>          server::MAX_REDIRECTS = 10;
48
48
<a name="l00025"></a>00025 
49
 
<a name="l00026"></a>00026 <span class="comment">// server member functions</span>
50
 
<a name="l00027"></a>00027 
51
 
<a name="l00028"></a><a class="code" href="classpion_1_1http_1_1server.html#a3366fd6be76ebb5ade34413be330aa6a">00028</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#a3366fd6be76ebb5ade34413be330aa6a">server::handle_connection</a>(tcp::connection_ptr&amp; tcp_conn)
52
 
<a name="l00029"></a>00029 {
53
 
<a name="l00030"></a>00030     request_reader_ptr my_reader_ptr;
54
 
<a name="l00031"></a>00031     my_reader_ptr = <a class="code" href="classpion_1_1http_1_1request__reader.html#a889653828718972c32e8671a3b6e29b0">request_reader::create</a>(tcp_conn, boost::bind(&amp;<a class="code" href="classpion_1_1http_1_1server.html#ad3e6180d412e8d2f135423e7e15f43ea">server::handle_request</a>,
55
 
<a name="l00032"></a>00032                                            <span class="keyword">this</span>, _1, _2, _3));
56
 
<a name="l00033"></a>00033     my_reader_ptr-&gt;set_max_content_length(m_max_content_length);
57
 
<a name="l00034"></a>00034     my_reader_ptr-&gt;receive();
58
 
<a name="l00035"></a>00035 }
59
 
<a name="l00036"></a>00036 
60
 
<a name="l00037"></a><a class="code" href="classpion_1_1http_1_1server.html#ad3e6180d412e8d2f135423e7e15f43ea">00037</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#ad3e6180d412e8d2f135423e7e15f43ea">server::handle_request</a>(http::request_ptr&amp; http_request_ptr,
61
 
<a name="l00038"></a>00038     tcp::connection_ptr&amp; tcp_conn, <span class="keyword">const</span> boost::system::error_code&amp; ec)
62
 
<a name="l00039"></a>00039 {
63
 
<a name="l00040"></a>00040     <span class="keywordflow">if</span> (ec || ! http_request_ptr-&gt;is_valid()) {
64
 
<a name="l00041"></a>00041         tcp_conn-&gt;set_lifecycle(tcp::connection::LIFECYCLE_CLOSE); <span class="comment">// make sure it will get closed</span>
65
 
<a name="l00042"></a>00042         <span class="keywordflow">if</span> (tcp_conn-&gt;is_open() &amp;&amp; (ec.category() == <a class="code" href="classpion_1_1http_1_1parser.html#a9313aa230ae4af4c30702c0605a1f701" title="returns an instance of parser::error_category_t">http::parser::get_error_category</a>())) {
66
 
<a name="l00043"></a>00043             <span class="comment">// HTTP parser error</span>
67
 
<a name="l00044"></a>00044             PION_LOG_INFO(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Invalid HTTP request (&quot;</span> &lt;&lt; ec.message() &lt;&lt; <span class="stringliteral">&quot;)&quot;</span>);
68
 
<a name="l00045"></a>00045             m_bad_request_handler(http_request_ptr, tcp_conn);
69
 
<a name="l00046"></a>00046         } <span class="keywordflow">else</span> {
70
 
<a name="l00047"></a>00047             <span class="keyword">static</span> <span class="keyword">const</span> boost::system::error_condition
71
 
<a name="l00048"></a>00048                     ERRCOND_CANCELED(boost::system::errc::operation_canceled, boost::system::system_category()),
72
 
<a name="l00049"></a>00049                     ERRCOND_EOF(boost::asio::error::eof, boost::asio::error::misc_category);
73
 
<a name="l00050"></a>00050 
74
 
<a name="l00051"></a>00051             <span class="keywordflow">if</span> (ec == ERRCOND_CANCELED || ec == ERRCOND_EOF) {
75
 
<a name="l00052"></a>00052                 <span class="comment">// don&apos;t spam the log with common (non-)errors that happen during normal operation</span>
76
 
<a name="l00053"></a>00053                 PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Lost connection on port &quot;</span> &lt;&lt; <a class="code" href="classpion_1_1tcp_1_1server.html#a46c1027475b8748e2a3047c7b738ef0b" title="returns tcp port number that the server listens for connections on">get_port</a>() &lt;&lt; <span class="stringliteral">&quot; (&quot;</span> &lt;&lt; ec.message() &lt;&lt; <span class="stringliteral">&quot;)&quot;</span>);
77
 
<a name="l00054"></a>00054             } <span class="keywordflow">else</span> {
78
 
<a name="l00055"></a>00055                 PION_LOG_INFO(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Lost connection on port &quot;</span> &lt;&lt; <a class="code" href="classpion_1_1tcp_1_1server.html#a46c1027475b8748e2a3047c7b738ef0b" title="returns tcp port number that the server listens for connections on">get_port</a>() &lt;&lt; <span class="stringliteral">&quot; (&quot;</span> &lt;&lt; ec.message() &lt;&lt; <span class="stringliteral">&quot;)&quot;</span>);
79
 
<a name="l00056"></a>00056             }
80
 
<a name="l00057"></a>00057 
81
 
<a name="l00058"></a>00058             tcp_conn-&gt;finish();
82
 
<a name="l00059"></a>00059         }
83
 
<a name="l00060"></a>00060         <span class="keywordflow">return</span>;
84
 
<a name="l00061"></a>00061     }
85
 
<a name="l00062"></a>00062         
86
 
<a name="l00063"></a>00063     PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Received a valid HTTP request&quot;</span>);
87
 
<a name="l00064"></a>00064 
88
 
<a name="l00065"></a>00065     <span class="comment">// strip off trailing slash if the request has one</span>
89
 
<a name="l00066"></a>00066     std::string resource_requested(<a class="code" href="classpion_1_1http_1_1server.html#a375e54d0970e5d3dfc0eb50f902cf4c9">strip_trailing_slash</a>(http_request_ptr-&gt;get_resource()));
90
 
<a name="l00067"></a>00067 
91
 
<a name="l00068"></a>00068     <span class="comment">// apply any redirection</span>
92
 
<a name="l00069"></a>00069     redirect_map_t::const_iterator it = m_redirects.find(resource_requested);
93
 
<a name="l00070"></a>00070     <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num_redirects = 0;
94
 
<a name="l00071"></a>00071     <span class="keywordflow">while</span> (it != m_redirects.end()) {
95
 
<a name="l00072"></a>00072         <span class="keywordflow">if</span> (++num_redirects &gt; MAX_REDIRECTS) {
96
 
<a name="l00073"></a>00073             PION_LOG_ERROR(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Maximum number of redirects (server::MAX_REDIRECTS) exceeded for requested resource: &quot;</span> &lt;&lt; http_request_ptr-&gt;get_original_resource());
97
 
<a name="l00074"></a>00074             m_server_error_handler(http_request_ptr, tcp_conn, <span class="stringliteral">&quot;Maximum number of redirects (server::MAX_REDIRECTS) exceeded for requested resource&quot;</span>);
98
 
<a name="l00075"></a>00075             <span class="keywordflow">return</span>;
99
 
<a name="l00076"></a>00076         }
100
 
<a name="l00077"></a>00077         resource_requested = it-&gt;second;
101
 
<a name="l00078"></a>00078         http_request_ptr-&gt;change_resource(resource_requested);
102
 
<a name="l00079"></a>00079         it = m_redirects.find(resource_requested);
103
 
<a name="l00080"></a>00080     }
104
 
<a name="l00081"></a>00081 
105
 
<a name="l00082"></a>00082     <span class="comment">// if authentication activated, check current request</span>
106
 
<a name="l00083"></a>00083     <span class="keywordflow">if</span> (m_auth_ptr) {
107
 
<a name="l00084"></a>00084         <span class="comment">// try to verify authentication</span>
108
 
<a name="l00085"></a>00085         <span class="keywordflow">if</span> (! m_auth_ptr-&gt;handle_request(http_request_ptr, tcp_conn)) {
109
 
<a name="l00086"></a>00086             <span class="comment">// the HTTP 401 message has already been sent by the authentication object</span>
110
 
<a name="l00087"></a>00087             PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Authentication required for HTTP resource: &quot;</span>
111
 
<a name="l00088"></a>00088                 &lt;&lt; resource_requested);
112
 
<a name="l00089"></a>00089             <span class="keywordflow">if</span> (http_request_ptr-&gt;get_resource() != http_request_ptr-&gt;get_original_resource()) {
113
 
<a name="l00090"></a>00090                 PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Original resource requested was: &quot;</span> &lt;&lt; http_request_ptr-&gt;get_original_resource());
114
 
<a name="l00091"></a>00091             }
115
 
<a name="l00092"></a>00092             <span class="keywordflow">return</span>;
116
 
<a name="l00093"></a>00093         }
117
 
<a name="l00094"></a>00094     }
118
 
<a name="l00095"></a>00095     
119
 
<a name="l00096"></a>00096     <span class="comment">// search for a handler matching the resource requested</span>
120
 
<a name="l00097"></a>00097     <a class="code" href="classpion_1_1http_1_1server.html#a74c41bc6ca8355497abb1401339a1306" title="type of function that is used to handle requests">request_handler_t</a> request_handler;
121
 
<a name="l00098"></a>00098     <span class="keywordflow">if</span> (<a class="code" href="classpion_1_1http_1_1server.html#a2a0e8e0c21438a9928e680cb0d94430c">find_request_handler</a>(resource_requested, request_handler)) {
122
 
<a name="l00099"></a>00099         
123
 
<a name="l00100"></a>00100         <span class="comment">// try to handle the request</span>
124
 
<a name="l00101"></a>00101         <span class="keywordflow">try</span> {
125
 
<a name="l00102"></a>00102             request_handler(http_request_ptr, tcp_conn);
126
 
<a name="l00103"></a>00103             PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Found request handler for HTTP resource: &quot;</span>
127
 
<a name="l00104"></a>00104                            &lt;&lt; resource_requested);
128
 
<a name="l00105"></a>00105             <span class="keywordflow">if</span> (http_request_ptr-&gt;get_resource() != http_request_ptr-&gt;get_original_resource()) {
129
 
<a name="l00106"></a>00106                 PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Original resource requested was: &quot;</span> &lt;&lt; http_request_ptr-&gt;get_original_resource());
130
 
<a name="l00107"></a>00107             }
131
 
<a name="l00108"></a>00108         } <span class="keywordflow">catch</span> (std::bad_alloc&amp;) {
132
 
<a name="l00109"></a>00109             <span class="comment">// propagate memory errors (FATAL)</span>
133
 
<a name="l00110"></a>00110             <span class="keywordflow">throw</span>;
134
 
<a name="l00111"></a>00111         } <span class="keywordflow">catch</span> (std::exception&amp; e) {
135
 
<a name="l00112"></a>00112             <span class="comment">// recover gracefully from other exceptions thrown request handlers</span>
136
 
<a name="l00113"></a>00113             PION_LOG_ERROR(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;HTTP request handler: &quot;</span> &lt;&lt; boost::diagnostic_information(e));
137
 
<a name="l00114"></a>00114             m_server_error_handler(http_request_ptr, tcp_conn, boost::diagnostic_information(e));
138
 
<a name="l00115"></a>00115         }
139
 
<a name="l00116"></a>00116         
140
 
<a name="l00117"></a>00117     } <span class="keywordflow">else</span> {
141
 
<a name="l00118"></a>00118         
142
 
<a name="l00119"></a>00119         <span class="comment">// no web services found that could handle the request</span>
143
 
<a name="l00120"></a>00120         PION_LOG_INFO(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;No HTTP request handlers found for resource: &quot;</span>
144
 
<a name="l00121"></a>00121                       &lt;&lt; resource_requested);
145
 
<a name="l00122"></a>00122         <span class="keywordflow">if</span> (http_request_ptr-&gt;get_resource() != http_request_ptr-&gt;get_original_resource()) {
146
 
<a name="l00123"></a>00123             PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Original resource requested was: &quot;</span> &lt;&lt; http_request_ptr-&gt;get_original_resource());
147
 
<a name="l00124"></a>00124         }
148
 
<a name="l00125"></a>00125         m_not_found_handler(http_request_ptr, tcp_conn);
149
 
<a name="l00126"></a>00126     }
150
 
<a name="l00127"></a>00127 }
151
 
<a name="l00128"></a>00128     
152
 
<a name="l00129"></a><a class="code" href="classpion_1_1http_1_1server.html#a2a0e8e0c21438a9928e680cb0d94430c">00129</a> <span class="keywordtype">bool</span> <a class="code" href="classpion_1_1http_1_1server.html#a2a0e8e0c21438a9928e680cb0d94430c">server::find_request_handler</a>(<span class="keyword">const</span> std::string&amp; resource,
153
 
<a name="l00130"></a>00130                                     request_handler_t&amp; request_handler)<span class="keyword"> const</span>
154
 
<a name="l00131"></a>00131 <span class="keyword"></span>{
155
 
<a name="l00132"></a>00132     <span class="comment">// first make sure that HTTP resources are registered</span>
156
 
<a name="l00133"></a>00133     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
157
 
<a name="l00134"></a>00134     <span class="keywordflow">if</span> (m_resources.empty())
158
 
<a name="l00135"></a>00135         <span class="keywordflow">return</span> <span class="keyword">false</span>;
159
 
<a name="l00136"></a>00136     
160
 
<a name="l00137"></a>00137     <span class="comment">// iterate through each resource entry that may match the resource</span>
161
 
<a name="l00138"></a>00138     resource_map_t::const_iterator i = m_resources.upper_bound(resource);
162
 
<a name="l00139"></a>00139     <span class="keywordflow">while</span> (i != m_resources.begin()) {
163
 
<a name="l00140"></a>00140         --i;
164
 
<a name="l00141"></a>00141         <span class="comment">// check for a match if the first part of the strings match</span>
165
 
<a name="l00142"></a>00142         <span class="keywordflow">if</span> (i-&gt;first.empty() || resource.compare(0, i-&gt;first.size(), i-&gt;first) == 0) {
166
 
<a name="l00143"></a>00143             <span class="comment">// only if the resource matches the plug-in&apos;s identifier</span>
167
 
<a name="l00144"></a>00144             <span class="comment">// or if resource is followed first with a &apos;/&apos; character</span>
168
 
<a name="l00145"></a>00145             <span class="keywordflow">if</span> (resource.size() == i-&gt;first.size() || resource[i-&gt;first.size()]==<span class="charliteral">&apos;/&apos;</span>) {
169
 
<a name="l00146"></a>00146                 request_handler = i-&gt;second;
170
 
<a name="l00147"></a>00147                 <span class="keywordflow">return</span> <span class="keyword">true</span>;
171
 
<a name="l00148"></a>00148             }
172
 
<a name="l00149"></a>00149         }
173
 
<a name="l00150"></a>00150     }
174
 
<a name="l00151"></a>00151     
175
 
<a name="l00152"></a>00152     <span class="keywordflow">return</span> <span class="keyword">false</span>;
176
 
<a name="l00153"></a>00153 }
177
 
<a name="l00154"></a>00154 
178
 
<a name="l00155"></a><a class="code" href="classpion_1_1http_1_1server.html#a312ad564b529bda2b4ddd12f02fd6d62">00155</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#a312ad564b529bda2b4ddd12f02fd6d62">server::add_resource</a>(<span class="keyword">const</span> std::string&amp; resource,
179
 
<a name="l00156"></a>00156                              request_handler_t request_handler)
180
 
<a name="l00157"></a>00157 {
181
 
<a name="l00158"></a>00158     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
182
 
<a name="l00159"></a>00159     <span class="keyword">const</span> std::string clean_resource(<a class="code" href="classpion_1_1http_1_1server.html#a375e54d0970e5d3dfc0eb50f902cf4c9">strip_trailing_slash</a>(resource));
183
 
<a name="l00160"></a>00160     m_resources.insert(std::make_pair(clean_resource, request_handler));
184
 
<a name="l00161"></a>00161     PION_LOG_INFO(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Added request handler for HTTP resource: &quot;</span> &lt;&lt; clean_resource);
185
 
<a name="l00162"></a>00162 }
186
 
<a name="l00163"></a>00163 
187
 
<a name="l00164"></a><a class="code" href="classpion_1_1http_1_1server.html#ac75fe5968f4d5e5c68e6328d483d0794">00164</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#ac75fe5968f4d5e5c68e6328d483d0794">server::remove_resource</a>(<span class="keyword">const</span> std::string&amp; resource)
188
 
<a name="l00165"></a>00165 {
189
 
<a name="l00166"></a>00166     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
190
 
<a name="l00167"></a>00167     <span class="keyword">const</span> std::string clean_resource(<a class="code" href="classpion_1_1http_1_1server.html#a375e54d0970e5d3dfc0eb50f902cf4c9">strip_trailing_slash</a>(resource));
191
 
<a name="l00168"></a>00168     m_resources.erase(clean_resource);
192
 
<a name="l00169"></a>00169     PION_LOG_INFO(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Removed request handler for HTTP resource: &quot;</span> &lt;&lt; clean_resource);
193
 
<a name="l00170"></a>00170 }
194
 
<a name="l00171"></a>00171 
195
 
<a name="l00172"></a><a class="code" href="classpion_1_1http_1_1server.html#a114c86a620ac425e4da9ebacebda3f21">00172</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#a114c86a620ac425e4da9ebacebda3f21">server::add_redirect</a>(<span class="keyword">const</span> std::string&amp; requested_resource,
196
 
<a name="l00173"></a>00173                              <span class="keyword">const</span> std::string&amp; new_resource)
197
 
<a name="l00174"></a>00174 {
198
 
<a name="l00175"></a>00175     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
199
 
<a name="l00176"></a>00176     <span class="keyword">const</span> std::string clean_requested_resource(<a class="code" href="classpion_1_1http_1_1server.html#a375e54d0970e5d3dfc0eb50f902cf4c9">strip_trailing_slash</a>(requested_resource));
200
 
<a name="l00177"></a>00177     <span class="keyword">const</span> std::string clean_new_resource(<a class="code" href="classpion_1_1http_1_1server.html#a375e54d0970e5d3dfc0eb50f902cf4c9">strip_trailing_slash</a>(new_resource));
201
 
<a name="l00178"></a>00178     m_redirects.insert(std::make_pair(clean_requested_resource, clean_new_resource));
202
 
<a name="l00179"></a>00179     PION_LOG_INFO(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Added redirection for HTTP resource &quot;</span> &lt;&lt; clean_requested_resource &lt;&lt; <span class="stringliteral">&quot; to resource &quot;</span> &lt;&lt; clean_new_resource);
203
 
<a name="l00180"></a>00180 }
204
 
<a name="l00181"></a>00181 
205
 
<a name="l00182"></a><a class="code" href="classpion_1_1http_1_1server.html#a080297b6789515f60ef8b856d6e0f372">00182</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#a080297b6789515f60ef8b856d6e0f372">server::handle_bad_request</a>(http::request_ptr&amp; http_request_ptr,
206
 
<a name="l00183"></a>00183                                   tcp::connection_ptr&amp; tcp_conn)
207
 
<a name="l00184"></a>00184 {
208
 
<a name="l00185"></a>00185     <span class="keyword">static</span> <span class="keyword">const</span> std::string BAD_REQUEST_HTML =
209
 
<a name="l00186"></a>00186         <span class="stringliteral">&quot;&lt;html&gt;&lt;head&gt;\n&quot;</span>
210
 
<a name="l00187"></a>00187         <span class="stringliteral">&quot;&lt;title&gt;400 Bad Request&lt;/title&gt;\n&quot;</span>
211
 
<a name="l00188"></a>00188         <span class="stringliteral">&quot;&lt;/head&gt;&lt;body&gt;\n&quot;</span>
212
 
<a name="l00189"></a>00189         <span class="stringliteral">&quot;&lt;h1&gt;Bad Request&lt;/h1&gt;\n&quot;</span>
213
 
<a name="l00190"></a>00190         <span class="stringliteral">&quot;&lt;p&gt;Your browser sent a request that this server could not understand.&lt;/p&gt;\n&quot;</span>
214
 
<a name="l00191"></a>00191         <span class="stringliteral">&quot;&lt;/body&gt;&lt;/html&gt;\n&quot;</span>;
215
 
<a name="l00192"></a>00192     http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
216
 
<a name="l00193"></a>00193                                                             boost::bind(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
217
 
<a name="l00194"></a>00194     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_BAD_REQUEST);
218
 
<a name="l00195"></a>00195     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_BAD_REQUEST);
219
 
<a name="l00196"></a>00196     writer-&gt;write_no_copy(BAD_REQUEST_HTML);
220
 
<a name="l00197"></a>00197     writer-&gt;send();
221
 
<a name="l00198"></a>00198 }
222
 
<a name="l00199"></a>00199 
223
 
<a name="l00200"></a><a class="code" href="classpion_1_1http_1_1server.html#ae2484144be6281ac5c1cbbcea99da81b">00200</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#ae2484144be6281ac5c1cbbcea99da81b">server::handle_not_found_request</a>(http::request_ptr&amp; http_request_ptr,
224
 
<a name="l00201"></a>00201                                        tcp::connection_ptr&amp; tcp_conn)
225
 
<a name="l00202"></a>00202 {
226
 
<a name="l00203"></a>00203     <span class="keyword">static</span> <span class="keyword">const</span> std::string NOT_FOUND_HTML_START =
227
 
<a name="l00204"></a>00204         <span class="stringliteral">&quot;&lt;html&gt;&lt;head&gt;\n&quot;</span>
228
 
<a name="l00205"></a>00205         <span class="stringliteral">&quot;&lt;title&gt;404 Not Found&lt;/title&gt;\n&quot;</span>
229
 
<a name="l00206"></a>00206         <span class="stringliteral">&quot;&lt;/head&gt;&lt;body&gt;\n&quot;</span>
230
 
<a name="l00207"></a>00207         <span class="stringliteral">&quot;&lt;h1&gt;Not Found&lt;/h1&gt;\n&quot;</span>
231
 
<a name="l00208"></a>00208         <span class="stringliteral">&quot;&lt;p&gt;The requested URL &quot;</span>;
232
 
<a name="l00209"></a>00209     <span class="keyword">static</span> <span class="keyword">const</span> std::string NOT_FOUND_HTML_FINISH =
233
 
<a name="l00210"></a>00210         <span class="stringliteral">&quot; was not found on this server.&lt;/p&gt;\n&quot;</span>
234
 
<a name="l00211"></a>00211         <span class="stringliteral">&quot;&lt;/body&gt;&lt;/html&gt;\n&quot;</span>;
235
 
<a name="l00212"></a>00212     http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
236
 
<a name="l00213"></a>00213                                                             boost::bind(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
237
 
<a name="l00214"></a>00214     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_NOT_FOUND);
238
 
<a name="l00215"></a>00215     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_NOT_FOUND);
239
 
<a name="l00216"></a>00216     writer-&gt;write_no_copy(NOT_FOUND_HTML_START);
240
 
<a name="l00217"></a>00217     writer &lt;&lt; http_request_ptr-&gt;get_resource();
241
 
<a name="l00218"></a>00218     writer-&gt;write_no_copy(NOT_FOUND_HTML_FINISH);
242
 
<a name="l00219"></a>00219     writer-&gt;send();
243
 
<a name="l00220"></a>00220 }
244
 
<a name="l00221"></a>00221 
245
 
<a name="l00222"></a><a class="code" href="classpion_1_1http_1_1server.html#aae06fc86091293ff3168822f0018c183">00222</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#aae06fc86091293ff3168822f0018c183">server::handle_server_error</a>(http::request_ptr&amp; http_request_ptr,
246
 
<a name="l00223"></a>00223                                    tcp::connection_ptr&amp; tcp_conn,
247
 
<a name="l00224"></a>00224                                    <span class="keyword">const</span> std::string&amp; error_msg)
248
 
<a name="l00225"></a>00225 {
249
 
<a name="l00226"></a>00226     <span class="keyword">static</span> <span class="keyword">const</span> std::string SERVER_ERROR_HTML_START =
250
 
<a name="l00227"></a>00227         <span class="stringliteral">&quot;&lt;html&gt;&lt;head&gt;\n&quot;</span>
251
 
<a name="l00228"></a>00228         <span class="stringliteral">&quot;&lt;title&gt;500 Server Error&lt;/title&gt;\n&quot;</span>
252
 
<a name="l00229"></a>00229         <span class="stringliteral">&quot;&lt;/head&gt;&lt;body&gt;\n&quot;</span>
253
 
<a name="l00230"></a>00230         <span class="stringliteral">&quot;&lt;h1&gt;Internal Server Error&lt;/h1&gt;\n&quot;</span>
254
 
<a name="l00231"></a>00231         <span class="stringliteral">&quot;&lt;p&gt;The server encountered an internal error: &lt;strong&gt;&quot;</span>;
255
 
<a name="l00232"></a>00232     <span class="keyword">static</span> <span class="keyword">const</span> std::string SERVER_ERROR_HTML_FINISH =
256
 
<a name="l00233"></a>00233         <span class="stringliteral">&quot;&lt;/strong&gt;&lt;/p&gt;\n&quot;</span>
257
 
<a name="l00234"></a>00234         <span class="stringliteral">&quot;&lt;/body&gt;&lt;/html&gt;\n&quot;</span>;
258
 
<a name="l00235"></a>00235     http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
259
 
<a name="l00236"></a>00236                                                             boost::bind(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
260
 
<a name="l00237"></a>00237     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_SERVER_ERROR);
261
 
<a name="l00238"></a>00238     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_SERVER_ERROR);
262
 
<a name="l00239"></a>00239     writer-&gt;write_no_copy(SERVER_ERROR_HTML_START);
263
 
<a name="l00240"></a>00240     writer &lt;&lt; error_msg;
264
 
<a name="l00241"></a>00241     writer-&gt;write_no_copy(SERVER_ERROR_HTML_FINISH);
265
 
<a name="l00242"></a>00242     writer-&gt;send();
266
 
<a name="l00243"></a>00243 }
267
 
<a name="l00244"></a>00244 
268
 
<a name="l00245"></a><a class="code" href="classpion_1_1http_1_1server.html#acc9ff11da47156419e059bebdddb5941">00245</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#acc9ff11da47156419e059bebdddb5941">server::handle_forbidden_request</a>(http::request_ptr&amp; http_request_ptr,
269
 
<a name="l00246"></a>00246                                         tcp::connection_ptr&amp; tcp_conn,
270
 
<a name="l00247"></a>00247                                         <span class="keyword">const</span> std::string&amp; error_msg)
271
 
<a name="l00248"></a>00248 {
272
 
<a name="l00249"></a>00249     <span class="keyword">static</span> <span class="keyword">const</span> std::string FORBIDDEN_HTML_START =
273
 
<a name="l00250"></a>00250         <span class="stringliteral">&quot;&lt;html&gt;&lt;head&gt;\n&quot;</span>
274
 
<a name="l00251"></a>00251         <span class="stringliteral">&quot;&lt;title&gt;403 Forbidden&lt;/title&gt;\n&quot;</span>
275
 
<a name="l00252"></a>00252         <span class="stringliteral">&quot;&lt;/head&gt;&lt;body&gt;\n&quot;</span>
276
 
<a name="l00253"></a>00253         <span class="stringliteral">&quot;&lt;h1&gt;Forbidden&lt;/h1&gt;\n&quot;</span>
277
 
<a name="l00254"></a>00254         <span class="stringliteral">&quot;&lt;p&gt;User not authorized to access the requested URL &quot;</span>;
278
 
<a name="l00255"></a>00255     <span class="keyword">static</span> <span class="keyword">const</span> std::string FORBIDDEN_HTML_MIDDLE =
279
 
<a name="l00256"></a>00256         <span class="stringliteral">&quot;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;\n&quot;</span>;
280
 
<a name="l00257"></a>00257     <span class="keyword">static</span> <span class="keyword">const</span> std::string FORBIDDEN_HTML_FINISH =
281
 
<a name="l00258"></a>00258         <span class="stringliteral">&quot;&lt;/strong&gt;&lt;/p&gt;\n&quot;</span>
282
 
<a name="l00259"></a>00259         <span class="stringliteral">&quot;&lt;/body&gt;&lt;/html&gt;\n&quot;</span>;
283
 
<a name="l00260"></a>00260     http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
284
 
<a name="l00261"></a>00261                                                             boost::bind(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
285
 
<a name="l00262"></a>00262     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_FORBIDDEN);
286
 
<a name="l00263"></a>00263     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_FORBIDDEN);
287
 
<a name="l00264"></a>00264     writer-&gt;write_no_copy(FORBIDDEN_HTML_START);
288
 
<a name="l00265"></a>00265     writer &lt;&lt; http_request_ptr-&gt;get_resource();
289
 
<a name="l00266"></a>00266     writer-&gt;write_no_copy(FORBIDDEN_HTML_MIDDLE);
290
 
<a name="l00267"></a>00267     writer &lt;&lt; error_msg;
291
 
<a name="l00268"></a>00268     writer-&gt;write_no_copy(FORBIDDEN_HTML_FINISH);
292
 
<a name="l00269"></a>00269     writer-&gt;send();
293
 
<a name="l00270"></a>00270 }
294
 
<a name="l00271"></a>00271 
295
 
<a name="l00272"></a><a class="code" href="classpion_1_1http_1_1server.html#a6c9f8330d4c0569da5f719438dccbc22">00272</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#a6c9f8330d4c0569da5f719438dccbc22">server::handle_method_not_allowed</a>(http::request_ptr&amp; http_request_ptr,
296
 
<a name="l00273"></a>00273                                         tcp::connection_ptr&amp; tcp_conn,
297
 
<a name="l00274"></a>00274                                         <span class="keyword">const</span> std::string&amp; allowed_methods)
298
 
<a name="l00275"></a>00275 {
299
 
<a name="l00276"></a>00276     <span class="keyword">static</span> <span class="keyword">const</span> std::string NOT_ALLOWED_HTML_START =
300
 
<a name="l00277"></a>00277         <span class="stringliteral">&quot;&lt;html&gt;&lt;head&gt;\n&quot;</span>
301
 
<a name="l00278"></a>00278         <span class="stringliteral">&quot;&lt;title&gt;405 Method Not Allowed&lt;/title&gt;\n&quot;</span>
302
 
<a name="l00279"></a>00279         <span class="stringliteral">&quot;&lt;/head&gt;&lt;body&gt;\n&quot;</span>
303
 
<a name="l00280"></a>00280         <span class="stringliteral">&quot;&lt;h1&gt;Not Allowed&lt;/h1&gt;\n&quot;</span>
304
 
<a name="l00281"></a>00281         <span class="stringliteral">&quot;&lt;p&gt;The requested method &quot;</span>;
305
 
<a name="l00282"></a>00282     <span class="keyword">static</span> <span class="keyword">const</span> std::string NOT_ALLOWED_HTML_FINISH =
306
 
<a name="l00283"></a>00283         <span class="stringliteral">&quot; is not allowed on this server.&lt;/p&gt;\n&quot;</span>
307
 
<a name="l00284"></a>00284         <span class="stringliteral">&quot;&lt;/body&gt;&lt;/html&gt;\n&quot;</span>;
308
 
<a name="l00285"></a>00285     http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
309
 
<a name="l00286"></a>00286                                                             boost::bind(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
310
 
<a name="l00287"></a>00287     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_METHOD_NOT_ALLOWED);
311
 
<a name="l00288"></a>00288     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_METHOD_NOT_ALLOWED);
312
 
<a name="l00289"></a>00289     <span class="keywordflow">if</span> (! allowed_methods.empty())
313
 
<a name="l00290"></a>00290         writer-&gt;get_response().add_header(<span class="stringliteral">&quot;Allow&quot;</span>, allowed_methods);
314
 
<a name="l00291"></a>00291     writer-&gt;write_no_copy(NOT_ALLOWED_HTML_START);
315
 
<a name="l00292"></a>00292     writer &lt;&lt; http_request_ptr-&gt;get_method();
316
 
<a name="l00293"></a>00293     writer-&gt;write_no_copy(NOT_ALLOWED_HTML_FINISH);
317
 
<a name="l00294"></a>00294     writer-&gt;send();
318
 
<a name="l00295"></a>00295 }
319
 
<a name="l00296"></a>00296 
320
 
<a name="l00297"></a>00297 }   <span class="comment">// end namespace http</span>
321
 
<a name="l00298"></a>00298 }   <span class="comment">// end namespace pion</span>
 
49
<a name="l00026"></a>00026 
 
50
<a name="l00027"></a>00027 <span class="comment">// server member functions</span>
 
51
<a name="l00028"></a>00028 
 
52
<a name="l00029"></a><a class="code" href="classpion_1_1http_1_1server.html#a3366fd6be76ebb5ade34413be330aa6a">00029</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#a3366fd6be76ebb5ade34413be330aa6a">server::handle_connection</a>(tcp::connection_ptr&amp; tcp_conn)
 
53
<a name="l00030"></a>00030 {
 
54
<a name="l00031"></a>00031     request_reader_ptr my_reader_ptr;
 
55
<a name="l00032"></a>00032     my_reader_ptr = <a class="code" href="classpion_1_1http_1_1request__reader.html#a889653828718972c32e8671a3b6e29b0">request_reader::create</a>(tcp_conn, boost::bind(&amp;<a class="code" href="classpion_1_1http_1_1server.html#ad3e6180d412e8d2f135423e7e15f43ea">server::handle_request</a>,
 
56
<a name="l00033"></a>00033                                            <span class="keyword">this</span>, _1, _2, _3));
 
57
<a name="l00034"></a>00034     my_reader_ptr-&gt;set_max_content_length(m_max_content_length);
 
58
<a name="l00035"></a>00035     my_reader_ptr-&gt;receive();
 
59
<a name="l00036"></a>00036 }
 
60
<a name="l00037"></a>00037 
 
61
<a name="l00038"></a><a class="code" href="classpion_1_1http_1_1server.html#ad3e6180d412e8d2f135423e7e15f43ea">00038</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#ad3e6180d412e8d2f135423e7e15f43ea">server::handle_request</a>(http::request_ptr&amp; http_request_ptr,
 
62
<a name="l00039"></a>00039     tcp::connection_ptr&amp; tcp_conn, <span class="keyword">const</span> boost::system::error_code&amp; ec)
 
63
<a name="l00040"></a>00040 {
 
64
<a name="l00041"></a>00041     <span class="keywordflow">if</span> (ec || ! http_request_ptr-&gt;is_valid()) {
 
65
<a name="l00042"></a>00042         tcp_conn-&gt;set_lifecycle(tcp::connection::LIFECYCLE_CLOSE); <span class="comment">// make sure it will get closed</span>
 
66
<a name="l00043"></a>00043         <span class="keywordflow">if</span> (tcp_conn-&gt;is_open() &amp;&amp; (ec.category() == <a class="code" href="classpion_1_1http_1_1parser.html#a9313aa230ae4af4c30702c0605a1f701" title="returns an instance of parser::error_category_t">http::parser::get_error_category</a>())) {
 
67
<a name="l00044"></a>00044             <span class="comment">// HTTP parser error</span>
 
68
<a name="l00045"></a>00045             PION_LOG_INFO(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Invalid HTTP request (&quot;</span> &lt;&lt; ec.message() &lt;&lt; <span class="stringliteral">&quot;)&quot;</span>);
 
69
<a name="l00046"></a>00046             m_bad_request_handler(http_request_ptr, tcp_conn);
 
70
<a name="l00047"></a>00047         } <span class="keywordflow">else</span> {
 
71
<a name="l00048"></a>00048             <span class="keyword">static</span> <span class="keyword">const</span> boost::system::error_condition
 
72
<a name="l00049"></a>00049                     ERRCOND_CANCELED(boost::system::errc::operation_canceled, boost::system::system_category()),
 
73
<a name="l00050"></a>00050                     ERRCOND_EOF(boost::asio::error::eof, boost::asio::error::misc_category);
 
74
<a name="l00051"></a>00051 
 
75
<a name="l00052"></a>00052             <span class="keywordflow">if</span> (ec == ERRCOND_CANCELED || ec == ERRCOND_EOF) {
 
76
<a name="l00053"></a>00053                 <span class="comment">// don&apos;t spam the log with common (non-)errors that happen during normal operation</span>
 
77
<a name="l00054"></a>00054                 PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Lost connection on port &quot;</span> &lt;&lt; <a class="code" href="classpion_1_1tcp_1_1server.html#a46c1027475b8748e2a3047c7b738ef0b" title="returns tcp port number that the server listens for connections on">get_port</a>() &lt;&lt; <span class="stringliteral">&quot; (&quot;</span> &lt;&lt; ec.message() &lt;&lt; <span class="stringliteral">&quot;)&quot;</span>);
 
78
<a name="l00055"></a>00055             } <span class="keywordflow">else</span> {
 
79
<a name="l00056"></a>00056                 PION_LOG_INFO(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Lost connection on port &quot;</span> &lt;&lt; <a class="code" href="classpion_1_1tcp_1_1server.html#a46c1027475b8748e2a3047c7b738ef0b" title="returns tcp port number that the server listens for connections on">get_port</a>() &lt;&lt; <span class="stringliteral">&quot; (&quot;</span> &lt;&lt; ec.message() &lt;&lt; <span class="stringliteral">&quot;)&quot;</span>);
 
80
<a name="l00057"></a>00057             }
 
81
<a name="l00058"></a>00058 
 
82
<a name="l00059"></a>00059             tcp_conn-&gt;finish();
 
83
<a name="l00060"></a>00060         }
 
84
<a name="l00061"></a>00061         <span class="keywordflow">return</span>;
 
85
<a name="l00062"></a>00062     }
 
86
<a name="l00063"></a>00063         
 
87
<a name="l00064"></a>00064     PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Received a valid HTTP request&quot;</span>);
 
88
<a name="l00065"></a>00065 
 
89
<a name="l00066"></a>00066     <span class="comment">// strip off trailing slash if the request has one</span>
 
90
<a name="l00067"></a>00067     std::string resource_requested(<a class="code" href="classpion_1_1http_1_1server.html#a375e54d0970e5d3dfc0eb50f902cf4c9">strip_trailing_slash</a>(http_request_ptr-&gt;get_resource()));
 
91
<a name="l00068"></a>00068 
 
92
<a name="l00069"></a>00069     <span class="comment">// apply any redirection</span>
 
93
<a name="l00070"></a>00070     redirect_map_t::const_iterator it = m_redirects.find(resource_requested);
 
94
<a name="l00071"></a>00071     <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num_redirects = 0;
 
95
<a name="l00072"></a>00072     <span class="keywordflow">while</span> (it != m_redirects.end()) {
 
96
<a name="l00073"></a>00073         <span class="keywordflow">if</span> (++num_redirects &gt; MAX_REDIRECTS) {
 
97
<a name="l00074"></a>00074             PION_LOG_ERROR(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Maximum number of redirects (server::MAX_REDIRECTS) exceeded for requested resource: &quot;</span> &lt;&lt; http_request_ptr-&gt;get_original_resource());
 
98
<a name="l00075"></a>00075             m_server_error_handler(http_request_ptr, tcp_conn, <span class="stringliteral">&quot;Maximum number of redirects (server::MAX_REDIRECTS) exceeded for requested resource&quot;</span>);
 
99
<a name="l00076"></a>00076             <span class="keywordflow">return</span>;
 
100
<a name="l00077"></a>00077         }
 
101
<a name="l00078"></a>00078         resource_requested = it-&gt;second;
 
102
<a name="l00079"></a>00079         http_request_ptr-&gt;change_resource(resource_requested);
 
103
<a name="l00080"></a>00080         it = m_redirects.find(resource_requested);
 
104
<a name="l00081"></a>00081     }
 
105
<a name="l00082"></a>00082 
 
106
<a name="l00083"></a>00083     <span class="comment">// if authentication activated, check current request</span>
 
107
<a name="l00084"></a>00084     <span class="keywordflow">if</span> (m_auth_ptr) {
 
108
<a name="l00085"></a>00085         <span class="comment">// try to verify authentication</span>
 
109
<a name="l00086"></a>00086         <span class="keywordflow">if</span> (! m_auth_ptr-&gt;handle_request(http_request_ptr, tcp_conn)) {
 
110
<a name="l00087"></a>00087             <span class="comment">// the HTTP 401 message has already been sent by the authentication object</span>
 
111
<a name="l00088"></a>00088             PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Authentication required for HTTP resource: &quot;</span>
 
112
<a name="l00089"></a>00089                 &lt;&lt; resource_requested);
 
113
<a name="l00090"></a>00090             <span class="keywordflow">if</span> (http_request_ptr-&gt;get_resource() != http_request_ptr-&gt;get_original_resource()) {
 
114
<a name="l00091"></a>00091                 PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Original resource requested was: &quot;</span> &lt;&lt; http_request_ptr-&gt;get_original_resource());
 
115
<a name="l00092"></a>00092             }
 
116
<a name="l00093"></a>00093             <span class="keywordflow">return</span>;
 
117
<a name="l00094"></a>00094         }
 
118
<a name="l00095"></a>00095     }
 
119
<a name="l00096"></a>00096     
 
120
<a name="l00097"></a>00097     <span class="comment">// search for a handler matching the resource requested</span>
 
121
<a name="l00098"></a>00098     <a class="code" href="classpion_1_1http_1_1server.html#a74c41bc6ca8355497abb1401339a1306" title="type of function that is used to handle requests">request_handler_t</a> request_handler;
 
122
<a name="l00099"></a>00099     <span class="keywordflow">if</span> (<a class="code" href="classpion_1_1http_1_1server.html#a2a0e8e0c21438a9928e680cb0d94430c">find_request_handler</a>(resource_requested, request_handler)) {
 
123
<a name="l00100"></a>00100         
 
124
<a name="l00101"></a>00101         <span class="comment">// try to handle the request</span>
 
125
<a name="l00102"></a>00102         <span class="keywordflow">try</span> {
 
126
<a name="l00103"></a>00103             request_handler(http_request_ptr, tcp_conn);
 
127
<a name="l00104"></a>00104             PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Found request handler for HTTP resource: &quot;</span>
 
128
<a name="l00105"></a>00105                            &lt;&lt; resource_requested);
 
129
<a name="l00106"></a>00106             <span class="keywordflow">if</span> (http_request_ptr-&gt;get_resource() != http_request_ptr-&gt;get_original_resource()) {
 
130
<a name="l00107"></a>00107                 PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Original resource requested was: &quot;</span> &lt;&lt; http_request_ptr-&gt;get_original_resource());
 
131
<a name="l00108"></a>00108             }
 
132
<a name="l00109"></a>00109         } <span class="keywordflow">catch</span> (std::bad_alloc&amp;) {
 
133
<a name="l00110"></a>00110             <span class="comment">// propagate memory errors (FATAL)</span>
 
134
<a name="l00111"></a>00111             <span class="keywordflow">throw</span>;
 
135
<a name="l00112"></a>00112         } <span class="keywordflow">catch</span> (std::exception&amp; e) {
 
136
<a name="l00113"></a>00113             <span class="comment">// recover gracefully from other exceptions thrown by request handlers</span>
 
137
<a name="l00114"></a>00114             PION_LOG_ERROR(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;HTTP request handler: &quot;</span> &lt;&lt; pion::diagnostic_information(e));
 
138
<a name="l00115"></a>00115             m_server_error_handler(http_request_ptr, tcp_conn, e.what());
 
139
<a name="l00116"></a>00116         } <span class="keywordflow">catch</span> (boost::exception&amp; e) {
 
140
<a name="l00117"></a>00117             <span class="comment">// recover gracefully from boost exceptions thrown by request handlers</span>
 
141
<a name="l00118"></a>00118             PION_LOG_ERROR(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;HTTP request handler: &quot;</span> &lt;&lt; pion::diagnostic_information(e));
 
142
<a name="l00119"></a>00119             m_server_error_handler(http_request_ptr, tcp_conn, pion::diagnostic_information(e));
 
143
<a name="l00120"></a>00120         }
 
144
<a name="l00121"></a>00121         
 
145
<a name="l00122"></a>00122     } <span class="keywordflow">else</span> {
 
146
<a name="l00123"></a>00123         
 
147
<a name="l00124"></a>00124         <span class="comment">// no web services found that could handle the request</span>
 
148
<a name="l00125"></a>00125         PION_LOG_INFO(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;No HTTP request handlers found for resource: &quot;</span>
 
149
<a name="l00126"></a>00126                       &lt;&lt; resource_requested);
 
150
<a name="l00127"></a>00127         <span class="keywordflow">if</span> (http_request_ptr-&gt;get_resource() != http_request_ptr-&gt;get_original_resource()) {
 
151
<a name="l00128"></a>00128             PION_LOG_DEBUG(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Original resource requested was: &quot;</span> &lt;&lt; http_request_ptr-&gt;get_original_resource());
 
152
<a name="l00129"></a>00129         }
 
153
<a name="l00130"></a>00130         m_not_found_handler(http_request_ptr, tcp_conn);
 
154
<a name="l00131"></a>00131     }
 
155
<a name="l00132"></a>00132 }
 
156
<a name="l00133"></a>00133     
 
157
<a name="l00134"></a><a class="code" href="classpion_1_1http_1_1server.html#a2a0e8e0c21438a9928e680cb0d94430c">00134</a> <span class="keywordtype">bool</span> <a class="code" href="classpion_1_1http_1_1server.html#a2a0e8e0c21438a9928e680cb0d94430c">server::find_request_handler</a>(<span class="keyword">const</span> std::string&amp; resource,
 
158
<a name="l00135"></a>00135                                     request_handler_t&amp; request_handler)<span class="keyword"> const</span>
 
159
<a name="l00136"></a>00136 <span class="keyword"></span>{
 
160
<a name="l00137"></a>00137     <span class="comment">// first make sure that HTTP resources are registered</span>
 
161
<a name="l00138"></a>00138     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
 
162
<a name="l00139"></a>00139     <span class="keywordflow">if</span> (m_resources.empty())
 
163
<a name="l00140"></a>00140         <span class="keywordflow">return</span> <span class="keyword">false</span>;
 
164
<a name="l00141"></a>00141     
 
165
<a name="l00142"></a>00142     <span class="comment">// iterate through each resource entry that may match the resource</span>
 
166
<a name="l00143"></a>00143     resource_map_t::const_iterator i = m_resources.upper_bound(resource);
 
167
<a name="l00144"></a>00144     <span class="keywordflow">while</span> (i != m_resources.begin()) {
 
168
<a name="l00145"></a>00145         --i;
 
169
<a name="l00146"></a>00146         <span class="comment">// check for a match if the first part of the strings match</span>
 
170
<a name="l00147"></a>00147         <span class="keywordflow">if</span> (i-&gt;first.empty() || resource.compare(0, i-&gt;first.size(), i-&gt;first) == 0) {
 
171
<a name="l00148"></a>00148             <span class="comment">// only if the resource matches the plug-in&apos;s identifier</span>
 
172
<a name="l00149"></a>00149             <span class="comment">// or if resource is followed first with a &apos;/&apos; character</span>
 
173
<a name="l00150"></a>00150             <span class="keywordflow">if</span> (resource.size() == i-&gt;first.size() || resource[i-&gt;first.size()]==<span class="charliteral">&apos;/&apos;</span>) {
 
174
<a name="l00151"></a>00151                 request_handler = i-&gt;second;
 
175
<a name="l00152"></a>00152                 <span class="keywordflow">return</span> <span class="keyword">true</span>;
 
176
<a name="l00153"></a>00153             }
 
177
<a name="l00154"></a>00154         }
 
178
<a name="l00155"></a>00155     }
 
179
<a name="l00156"></a>00156     
 
180
<a name="l00157"></a>00157     <span class="keywordflow">return</span> <span class="keyword">false</span>;
 
181
<a name="l00158"></a>00158 }
 
182
<a name="l00159"></a>00159 
 
183
<a name="l00160"></a><a class="code" href="classpion_1_1http_1_1server.html#a312ad564b529bda2b4ddd12f02fd6d62">00160</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#a312ad564b529bda2b4ddd12f02fd6d62">server::add_resource</a>(<span class="keyword">const</span> std::string&amp; resource,
 
184
<a name="l00161"></a>00161                              request_handler_t request_handler)
 
185
<a name="l00162"></a>00162 {
 
186
<a name="l00163"></a>00163     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
 
187
<a name="l00164"></a>00164     <span class="keyword">const</span> std::string clean_resource(<a class="code" href="classpion_1_1http_1_1server.html#a375e54d0970e5d3dfc0eb50f902cf4c9">strip_trailing_slash</a>(resource));
 
188
<a name="l00165"></a>00165     m_resources.insert(std::make_pair(clean_resource, request_handler));
 
189
<a name="l00166"></a>00166     PION_LOG_INFO(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Added request handler for HTTP resource: &quot;</span> &lt;&lt; clean_resource);
 
190
<a name="l00167"></a>00167 }
 
191
<a name="l00168"></a>00168 
 
192
<a name="l00169"></a><a class="code" href="classpion_1_1http_1_1server.html#ac75fe5968f4d5e5c68e6328d483d0794">00169</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#ac75fe5968f4d5e5c68e6328d483d0794">server::remove_resource</a>(<span class="keyword">const</span> std::string&amp; resource)
 
193
<a name="l00170"></a>00170 {
 
194
<a name="l00171"></a>00171     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
 
195
<a name="l00172"></a>00172     <span class="keyword">const</span> std::string clean_resource(<a class="code" href="classpion_1_1http_1_1server.html#a375e54d0970e5d3dfc0eb50f902cf4c9">strip_trailing_slash</a>(resource));
 
196
<a name="l00173"></a>00173     m_resources.erase(clean_resource);
 
197
<a name="l00174"></a>00174     PION_LOG_INFO(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Removed request handler for HTTP resource: &quot;</span> &lt;&lt; clean_resource);
 
198
<a name="l00175"></a>00175 }
 
199
<a name="l00176"></a>00176 
 
200
<a name="l00177"></a><a class="code" href="classpion_1_1http_1_1server.html#a114c86a620ac425e4da9ebacebda3f21">00177</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#a114c86a620ac425e4da9ebacebda3f21">server::add_redirect</a>(<span class="keyword">const</span> std::string&amp; requested_resource,
 
201
<a name="l00178"></a>00178                              <span class="keyword">const</span> std::string&amp; new_resource)
 
202
<a name="l00179"></a>00179 {
 
203
<a name="l00180"></a>00180     boost::mutex::scoped_lock resource_lock(m_resource_mutex);
 
204
<a name="l00181"></a>00181     <span class="keyword">const</span> std::string clean_requested_resource(<a class="code" href="classpion_1_1http_1_1server.html#a375e54d0970e5d3dfc0eb50f902cf4c9">strip_trailing_slash</a>(requested_resource));
 
205
<a name="l00182"></a>00182     <span class="keyword">const</span> std::string clean_new_resource(<a class="code" href="classpion_1_1http_1_1server.html#a375e54d0970e5d3dfc0eb50f902cf4c9">strip_trailing_slash</a>(new_resource));
 
206
<a name="l00183"></a>00183     m_redirects.insert(std::make_pair(clean_requested_resource, clean_new_resource));
 
207
<a name="l00184"></a>00184     PION_LOG_INFO(<a class="code" href="classpion_1_1tcp_1_1server.html#a0fd391b946961fca8604b902ddb06f7d" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Added redirection for HTTP resource &quot;</span> &lt;&lt; clean_requested_resource &lt;&lt; <span class="stringliteral">&quot; to resource &quot;</span> &lt;&lt; clean_new_resource);
 
208
<a name="l00185"></a>00185 }
 
209
<a name="l00186"></a>00186 
 
210
<a name="l00187"></a><a class="code" href="classpion_1_1http_1_1server.html#a080297b6789515f60ef8b856d6e0f372">00187</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#a080297b6789515f60ef8b856d6e0f372">server::handle_bad_request</a>(http::request_ptr&amp; http_request_ptr,
 
211
<a name="l00188"></a>00188                                   tcp::connection_ptr&amp; tcp_conn)
 
212
<a name="l00189"></a>00189 {
 
213
<a name="l00190"></a>00190     <span class="keyword">static</span> <span class="keyword">const</span> std::string BAD_REQUEST_HTML =
 
214
<a name="l00191"></a>00191         <span class="stringliteral">&quot;&lt;html&gt;&lt;head&gt;\n&quot;</span>
 
215
<a name="l00192"></a>00192         <span class="stringliteral">&quot;&lt;title&gt;400 Bad Request&lt;/title&gt;\n&quot;</span>
 
216
<a name="l00193"></a>00193         <span class="stringliteral">&quot;&lt;/head&gt;&lt;body&gt;\n&quot;</span>
 
217
<a name="l00194"></a>00194         <span class="stringliteral">&quot;&lt;h1&gt;Bad Request&lt;/h1&gt;\n&quot;</span>
 
218
<a name="l00195"></a>00195         <span class="stringliteral">&quot;&lt;p&gt;Your browser sent a request that this server could not understand.&lt;/p&gt;\n&quot;</span>
 
219
<a name="l00196"></a>00196         <span class="stringliteral">&quot;&lt;/body&gt;&lt;/html&gt;\n&quot;</span>;
 
220
<a name="l00197"></a>00197     http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
 
221
<a name="l00198"></a>00198                                                             boost::bind(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
 
222
<a name="l00199"></a>00199     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_BAD_REQUEST);
 
223
<a name="l00200"></a>00200     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_BAD_REQUEST);
 
224
<a name="l00201"></a>00201     writer-&gt;write_no_copy(BAD_REQUEST_HTML);
 
225
<a name="l00202"></a>00202     writer-&gt;send();
 
226
<a name="l00203"></a>00203 }
 
227
<a name="l00204"></a>00204 
 
228
<a name="l00205"></a><a class="code" href="classpion_1_1http_1_1server.html#ae2484144be6281ac5c1cbbcea99da81b">00205</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#ae2484144be6281ac5c1cbbcea99da81b">server::handle_not_found_request</a>(http::request_ptr&amp; http_request_ptr,
 
229
<a name="l00206"></a>00206                                        tcp::connection_ptr&amp; tcp_conn)
 
230
<a name="l00207"></a>00207 {
 
231
<a name="l00208"></a>00208     <span class="keyword">static</span> <span class="keyword">const</span> std::string NOT_FOUND_HTML_START =
 
232
<a name="l00209"></a>00209         <span class="stringliteral">&quot;&lt;html&gt;&lt;head&gt;\n&quot;</span>
 
233
<a name="l00210"></a>00210         <span class="stringliteral">&quot;&lt;title&gt;404 Not Found&lt;/title&gt;\n&quot;</span>
 
234
<a name="l00211"></a>00211         <span class="stringliteral">&quot;&lt;/head&gt;&lt;body&gt;\n&quot;</span>
 
235
<a name="l00212"></a>00212         <span class="stringliteral">&quot;&lt;h1&gt;Not Found&lt;/h1&gt;\n&quot;</span>
 
236
<a name="l00213"></a>00213         <span class="stringliteral">&quot;&lt;p&gt;The requested URL &quot;</span>;
 
237
<a name="l00214"></a>00214     <span class="keyword">static</span> <span class="keyword">const</span> std::string NOT_FOUND_HTML_FINISH =
 
238
<a name="l00215"></a>00215         <span class="stringliteral">&quot; was not found on this server.&lt;/p&gt;\n&quot;</span>
 
239
<a name="l00216"></a>00216         <span class="stringliteral">&quot;&lt;/body&gt;&lt;/html&gt;\n&quot;</span>;
 
240
<a name="l00217"></a>00217     http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
 
241
<a name="l00218"></a>00218                                                             boost::bind(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
 
242
<a name="l00219"></a>00219     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_NOT_FOUND);
 
243
<a name="l00220"></a>00220     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_NOT_FOUND);
 
244
<a name="l00221"></a>00221     writer-&gt;write_no_copy(NOT_FOUND_HTML_START);
 
245
<a name="l00222"></a>00222     writer &lt;&lt; <a class="code" href="structpion_1_1algorithm.html#a2177ca0d0f01e6ef6d4d3bceb73d82bb" title="TODO: escapes XML/HTML-encoded strings (1 &amp;lt; 2).">algorithm::xml_encode</a>(http_request_ptr-&gt;get_resource());
 
246
<a name="l00223"></a>00223     writer-&gt;write_no_copy(NOT_FOUND_HTML_FINISH);
 
247
<a name="l00224"></a>00224     writer-&gt;send();
 
248
<a name="l00225"></a>00225 }
 
249
<a name="l00226"></a>00226 
 
250
<a name="l00227"></a><a class="code" href="classpion_1_1http_1_1server.html#aae06fc86091293ff3168822f0018c183">00227</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#aae06fc86091293ff3168822f0018c183">server::handle_server_error</a>(http::request_ptr&amp; http_request_ptr,
 
251
<a name="l00228"></a>00228                                    tcp::connection_ptr&amp; tcp_conn,
 
252
<a name="l00229"></a>00229                                    <span class="keyword">const</span> std::string&amp; error_msg)
 
253
<a name="l00230"></a>00230 {
 
254
<a name="l00231"></a>00231     <span class="keyword">static</span> <span class="keyword">const</span> std::string SERVER_ERROR_HTML_START =
 
255
<a name="l00232"></a>00232         <span class="stringliteral">&quot;&lt;html&gt;&lt;head&gt;\n&quot;</span>
 
256
<a name="l00233"></a>00233         <span class="stringliteral">&quot;&lt;title&gt;500 Server Error&lt;/title&gt;\n&quot;</span>
 
257
<a name="l00234"></a>00234         <span class="stringliteral">&quot;&lt;/head&gt;&lt;body&gt;\n&quot;</span>
 
258
<a name="l00235"></a>00235         <span class="stringliteral">&quot;&lt;h1&gt;Internal Server Error&lt;/h1&gt;\n&quot;</span>
 
259
<a name="l00236"></a>00236         <span class="stringliteral">&quot;&lt;p&gt;The server encountered an internal error: &lt;strong&gt;&quot;</span>;
 
260
<a name="l00237"></a>00237     <span class="keyword">static</span> <span class="keyword">const</span> std::string SERVER_ERROR_HTML_FINISH =
 
261
<a name="l00238"></a>00238         <span class="stringliteral">&quot;&lt;/strong&gt;&lt;/p&gt;\n&quot;</span>
 
262
<a name="l00239"></a>00239         <span class="stringliteral">&quot;&lt;/body&gt;&lt;/html&gt;\n&quot;</span>;
 
263
<a name="l00240"></a>00240     http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
 
264
<a name="l00241"></a>00241                                                             boost::bind(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
 
265
<a name="l00242"></a>00242     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_SERVER_ERROR);
 
266
<a name="l00243"></a>00243     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_SERVER_ERROR);
 
267
<a name="l00244"></a>00244     writer-&gt;write_no_copy(SERVER_ERROR_HTML_START);
 
268
<a name="l00245"></a>00245     writer &lt;&lt; <a class="code" href="structpion_1_1algorithm.html#a2177ca0d0f01e6ef6d4d3bceb73d82bb" title="TODO: escapes XML/HTML-encoded strings (1 &amp;lt; 2).">algorithm::xml_encode</a>(error_msg);
 
269
<a name="l00246"></a>00246     writer-&gt;write_no_copy(SERVER_ERROR_HTML_FINISH);
 
270
<a name="l00247"></a>00247     writer-&gt;send();
 
271
<a name="l00248"></a>00248 }
 
272
<a name="l00249"></a>00249 
 
273
<a name="l00250"></a><a class="code" href="classpion_1_1http_1_1server.html#acc9ff11da47156419e059bebdddb5941">00250</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#acc9ff11da47156419e059bebdddb5941">server::handle_forbidden_request</a>(http::request_ptr&amp; http_request_ptr,
 
274
<a name="l00251"></a>00251                                         tcp::connection_ptr&amp; tcp_conn,
 
275
<a name="l00252"></a>00252                                         <span class="keyword">const</span> std::string&amp; error_msg)
 
276
<a name="l00253"></a>00253 {
 
277
<a name="l00254"></a>00254     <span class="keyword">static</span> <span class="keyword">const</span> std::string FORBIDDEN_HTML_START =
 
278
<a name="l00255"></a>00255         <span class="stringliteral">&quot;&lt;html&gt;&lt;head&gt;\n&quot;</span>
 
279
<a name="l00256"></a>00256         <span class="stringliteral">&quot;&lt;title&gt;403 Forbidden&lt;/title&gt;\n&quot;</span>
 
280
<a name="l00257"></a>00257         <span class="stringliteral">&quot;&lt;/head&gt;&lt;body&gt;\n&quot;</span>
 
281
<a name="l00258"></a>00258         <span class="stringliteral">&quot;&lt;h1&gt;Forbidden&lt;/h1&gt;\n&quot;</span>
 
282
<a name="l00259"></a>00259         <span class="stringliteral">&quot;&lt;p&gt;User not authorized to access the requested URL &quot;</span>;
 
283
<a name="l00260"></a>00260     <span class="keyword">static</span> <span class="keyword">const</span> std::string FORBIDDEN_HTML_MIDDLE =
 
284
<a name="l00261"></a>00261         <span class="stringliteral">&quot;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;\n&quot;</span>;
 
285
<a name="l00262"></a>00262     <span class="keyword">static</span> <span class="keyword">const</span> std::string FORBIDDEN_HTML_FINISH =
 
286
<a name="l00263"></a>00263         <span class="stringliteral">&quot;&lt;/strong&gt;&lt;/p&gt;\n&quot;</span>
 
287
<a name="l00264"></a>00264         <span class="stringliteral">&quot;&lt;/body&gt;&lt;/html&gt;\n&quot;</span>;
 
288
<a name="l00265"></a>00265     http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
 
289
<a name="l00266"></a>00266                                                             boost::bind(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
 
290
<a name="l00267"></a>00267     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_FORBIDDEN);
 
291
<a name="l00268"></a>00268     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_FORBIDDEN);
 
292
<a name="l00269"></a>00269     writer-&gt;write_no_copy(FORBIDDEN_HTML_START);
 
293
<a name="l00270"></a>00270     writer &lt;&lt; <a class="code" href="structpion_1_1algorithm.html#a2177ca0d0f01e6ef6d4d3bceb73d82bb" title="TODO: escapes XML/HTML-encoded strings (1 &amp;lt; 2).">algorithm::xml_encode</a>(http_request_ptr-&gt;get_resource());
 
294
<a name="l00271"></a>00271     writer-&gt;write_no_copy(FORBIDDEN_HTML_MIDDLE);
 
295
<a name="l00272"></a>00272     writer &lt;&lt; error_msg;
 
296
<a name="l00273"></a>00273     writer-&gt;write_no_copy(FORBIDDEN_HTML_FINISH);
 
297
<a name="l00274"></a>00274     writer-&gt;send();
 
298
<a name="l00275"></a>00275 }
 
299
<a name="l00276"></a>00276 
 
300
<a name="l00277"></a><a class="code" href="classpion_1_1http_1_1server.html#a6c9f8330d4c0569da5f719438dccbc22">00277</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1server.html#a6c9f8330d4c0569da5f719438dccbc22">server::handle_method_not_allowed</a>(http::request_ptr&amp; http_request_ptr,
 
301
<a name="l00278"></a>00278                                         tcp::connection_ptr&amp; tcp_conn,
 
302
<a name="l00279"></a>00279                                         <span class="keyword">const</span> std::string&amp; allowed_methods)
 
303
<a name="l00280"></a>00280 {
 
304
<a name="l00281"></a>00281     <span class="keyword">static</span> <span class="keyword">const</span> std::string NOT_ALLOWED_HTML_START =
 
305
<a name="l00282"></a>00282         <span class="stringliteral">&quot;&lt;html&gt;&lt;head&gt;\n&quot;</span>
 
306
<a name="l00283"></a>00283         <span class="stringliteral">&quot;&lt;title&gt;405 Method Not Allowed&lt;/title&gt;\n&quot;</span>
 
307
<a name="l00284"></a>00284         <span class="stringliteral">&quot;&lt;/head&gt;&lt;body&gt;\n&quot;</span>
 
308
<a name="l00285"></a>00285         <span class="stringliteral">&quot;&lt;h1&gt;Not Allowed&lt;/h1&gt;\n&quot;</span>
 
309
<a name="l00286"></a>00286         <span class="stringliteral">&quot;&lt;p&gt;The requested method &quot;</span>;
 
310
<a name="l00287"></a>00287     <span class="keyword">static</span> <span class="keyword">const</span> std::string NOT_ALLOWED_HTML_FINISH =
 
311
<a name="l00288"></a>00288         <span class="stringliteral">&quot; is not allowed on this server.&lt;/p&gt;\n&quot;</span>
 
312
<a name="l00289"></a>00289         <span class="stringliteral">&quot;&lt;/body&gt;&lt;/html&gt;\n&quot;</span>;
 
313
<a name="l00290"></a>00290     http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
 
314
<a name="l00291"></a>00291                                                             boost::bind(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
 
315
<a name="l00292"></a>00292     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_METHOD_NOT_ALLOWED);
 
316
<a name="l00293"></a>00293     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_METHOD_NOT_ALLOWED);
 
317
<a name="l00294"></a>00294     <span class="keywordflow">if</span> (! allowed_methods.empty())
 
318
<a name="l00295"></a>00295         writer-&gt;get_response().add_header(<span class="stringliteral">&quot;Allow&quot;</span>, allowed_methods);
 
319
<a name="l00296"></a>00296     writer-&gt;write_no_copy(NOT_ALLOWED_HTML_START);
 
320
<a name="l00297"></a>00297     writer &lt;&lt; <a class="code" href="structpion_1_1algorithm.html#a2177ca0d0f01e6ef6d4d3bceb73d82bb" title="TODO: escapes XML/HTML-encoded strings (1 &amp;lt; 2).">algorithm::xml_encode</a>(http_request_ptr-&gt;get_method());
 
321
<a name="l00298"></a>00298     writer-&gt;write_no_copy(NOT_ALLOWED_HTML_FINISH);
 
322
<a name="l00299"></a>00299     writer-&gt;send();
 
323
<a name="l00300"></a>00300 }
 
324
<a name="l00301"></a>00301 
 
325
<a name="l00302"></a>00302 }   <span class="comment">// end namespace http</span>
 
326
<a name="l00303"></a>00303 }   <span class="comment">// end namespace pion</span>
322
327
</pre></div></div>
323
 
<hr size="1"/><address style="text-align: right;"><small>Generated on 15 Apr 2013 for pion by&nbsp;
 
328
<hr size="1"/><address style="text-align: right;"><small>Generated on 26 Jul 2013 for pion by&nbsp;
324
329
<a href="http://www.doxygen.org/index.html">
325
330
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.1 </small></address>
326
331
</body>