/usr/share/doc/libpion-doc/html/http__message_8cpp_source.html is in libpion-doc 5.0.6+dfsg-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | <!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/xhtml;charset=UTF-8"/>
<title>pion: src/http_message.cpp Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.6.1 -->
<div class="navigation" id="top">
<div class="tabs">
<ul>
<li><a href="index.html"><span>Main Page</span></a></li>
<li><a href="annotated.html"><span>Classes</span></a></li>
<li class="current"><a href="files.html"><span>Files</span></a></li>
</ul>
</div>
<div class="tabs">
<ul>
<li><a href="files.html"><span>File List</span></a></li>
</ul>
</div>
<h1>src/http_message.cpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">// ---------------------------------------------------------------------</span>
<a name="l00002"></a>00002 <span class="comment">// pion: a Boost C++ framework for building lightweight HTTP interfaces</span>
<a name="l00003"></a>00003 <span class="comment">// ---------------------------------------------------------------------</span>
<a name="l00004"></a>00004 <span class="comment">// Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion)</span>
<a name="l00005"></a>00005 <span class="comment">//</span>
<a name="l00006"></a>00006 <span class="comment">// Distributed under the Boost Software License, Version 1.0.</span>
<a name="l00007"></a>00007 <span class="comment">// See http://www.boost.org/LICENSE_1_0.txt</span>
<a name="l00008"></a>00008 <span class="comment">//</span>
<a name="l00009"></a>00009
<a name="l00010"></a>00010 <span class="preprocessor">#include <iostream></span>
<a name="l00011"></a>00011 <span class="preprocessor">#include <algorithm></span>
<a name="l00012"></a>00012 <span class="preprocessor">#include <boost/asio.hpp></span>
<a name="l00013"></a>00013 <span class="preprocessor">#include <boost/assert.hpp></span>
<a name="l00014"></a>00014 <span class="preprocessor">#include <boost/regex.hpp></span>
<a name="l00015"></a>00015 <span class="preprocessor">#include <boost/logic/tribool.hpp></span>
<a name="l00016"></a>00016 <span class="preprocessor">#include <pion/http/message.hpp></span>
<a name="l00017"></a>00017 <span class="preprocessor">#include <pion/http/request.hpp></span>
<a name="l00018"></a>00018 <span class="preprocessor">#include <pion/http/parser.hpp></span>
<a name="l00019"></a>00019 <span class="preprocessor">#include <pion/tcp/connection.hpp></span>
<a name="l00020"></a>00020
<a name="l00021"></a>00021
<a name="l00022"></a>00022 <span class="keyword">namespace </span>pion { <span class="comment">// begin namespace pion</span>
<a name="l00023"></a>00023 <span class="keyword">namespace </span>http { <span class="comment">// begin namespace http</span>
<a name="l00024"></a>00024
<a name="l00025"></a>00025
<a name="l00026"></a>00026 <span class="comment">// static members of message</span>
<a name="l00027"></a>00027
<a name="l00028"></a>00028 <span class="keyword">const</span> boost::regex message::REGEX_ICASE_CHUNKED(<span class="stringliteral">".*chunked.*"</span>, boost::regex::icase);
<a name="l00029"></a>00029
<a name="l00030"></a>00030
<a name="l00031"></a>00031 <span class="comment">// message member functions</span>
<a name="l00032"></a>00032
<a name="l00033"></a><a class="code" href="classpion_1_1http_1_1message.html#ab90f91badb0f98f900a7624418781bea">00033</a> std::size_t <a class="code" href="classpion_1_1http_1_1message.html#ab90f91badb0f98f900a7624418781bea">message::send</a>(<a class="code" href="classpion_1_1tcp_1_1connection.html">tcp::connection</a>& tcp_conn,
<a name="l00034"></a>00034 boost::system::error_code& ec, <span class="keywordtype">bool</span> headers_only)
<a name="l00035"></a>00035 {
<a name="l00036"></a>00036 <span class="comment">// initialize write buffers for send operation using HTTP headers</span>
<a name="l00037"></a>00037 <a class="code" href="classpion_1_1http_1_1message.html#aacf9a6a7677c32e4ab764ac97d0b5e7b" title="data type for I/O write buffers (these wrap existing data to be sent)">write_buffers_t</a> write_buffers;
<a name="l00038"></a>00038 <a class="code" href="classpion_1_1http_1_1message.html#a668182618dfc614ddbe6c1af26552568">prepare_buffers_for_send</a>(write_buffers, tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#a35394d8c3f144ab8a264824410bb7088" title="returns true if the connection should be kept alive">get_keep_alive</a>(), <span class="keyword">false</span>);
<a name="l00039"></a>00039
<a name="l00040"></a>00040 <span class="comment">// append payload content to write buffers (if there is any)</span>
<a name="l00041"></a>00041 <span class="keywordflow">if</span> (!headers_only && <a class="code" href="classpion_1_1http_1_1message.html#a10606f8fd2efbe14d447ef8eb8731a54" title="returns the length of the payload content (in bytes)">get_content_length</a>() > 0 && <a class="code" href="classpion_1_1http_1_1message.html#a60ddb1bd09afecdadc5e9c33c8c1de28" title="returns a pointer to the payload content, or empty string if there is none">get_content</a>() != NULL)
<a name="l00042"></a>00042 write_buffers.push_back(boost::asio::buffer(<a class="code" href="classpion_1_1http_1_1message.html#a60ddb1bd09afecdadc5e9c33c8c1de28" title="returns a pointer to the payload content, or empty string if there is none">get_content</a>(), <a class="code" href="classpion_1_1http_1_1message.html#a10606f8fd2efbe14d447ef8eb8731a54" title="returns the length of the payload content (in bytes)">get_content_length</a>()));
<a name="l00043"></a>00043
<a name="l00044"></a>00044 <span class="comment">// send the message and return the result</span>
<a name="l00045"></a>00045 <span class="keywordflow">return</span> tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#a7ba752cbf79d2824dcf423a2ed77184a">write</a>(write_buffers, ec);
<a name="l00046"></a>00046 }
<a name="l00047"></a>00047
<a name="l00048"></a><a class="code" href="classpion_1_1http_1_1message.html#a7e3c3f1ea265f91b87a9e075234b5d31">00048</a> std::size_t <a class="code" href="classpion_1_1http_1_1message.html#a7e3c3f1ea265f91b87a9e075234b5d31">message::receive</a>(<a class="code" href="classpion_1_1tcp_1_1connection.html">tcp::connection</a>& tcp_conn,
<a name="l00049"></a>00049 boost::system::error_code& ec,
<a name="l00050"></a>00050 <a class="code" href="classpion_1_1http_1_1parser.html">parser</a>& http_parser)
<a name="l00051"></a>00051 {
<a name="l00052"></a>00052 std::size_t last_bytes_read = 0;
<a name="l00053"></a>00053
<a name="l00054"></a>00054 <span class="comment">// make sure that we start out with an empty message</span>
<a name="l00055"></a>00055 <a class="code" href="classpion_1_1http_1_1message.html#af13279269cf1e00ae4fc5091c1c7cae5" title="clears all message data">clear</a>();
<a name="l00056"></a>00056
<a name="l00057"></a>00057 <span class="keywordflow">if</span> (tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#aa54a75a48eae812955f7ce6b2b4c3d51" title="returns true if the HTTP requests are pipelined">get_pipelined</a>()) {
<a name="l00058"></a>00058 <span class="comment">// there are pipelined messages available in the connection's read buffer</span>
<a name="l00059"></a>00059 <span class="keyword">const</span> <span class="keywordtype">char</span> *read_ptr;
<a name="l00060"></a>00060 <span class="keyword">const</span> <span class="keywordtype">char</span> *read_end_ptr;
<a name="l00061"></a>00061 tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#a4cc9d7185adda632de1f3482552ed5f6">load_read_pos</a>(read_ptr, read_end_ptr);
<a name="l00062"></a>00062 last_bytes_read = (read_end_ptr - read_ptr);
<a name="l00063"></a>00063 http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#a71fdd1e6e681a3bd932baf2bd6a9f9c9">set_read_buffer</a>(read_ptr, last_bytes_read);
<a name="l00064"></a>00064 } <span class="keywordflow">else</span> {
<a name="l00065"></a>00065 <span class="comment">// read buffer is empty (not pipelined) -> read some bytes from the connection</span>
<a name="l00066"></a>00066 last_bytes_read = tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#af3c5c14c87e99bd40b605b0fb0b4a84e">read_some</a>(ec);
<a name="l00067"></a>00067 <span class="keywordflow">if</span> (ec) <span class="keywordflow">return</span> 0;
<a name="l00068"></a>00068 BOOST_ASSERT(last_bytes_read > 0);
<a name="l00069"></a>00069 http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#a71fdd1e6e681a3bd932baf2bd6a9f9c9">set_read_buffer</a>(tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#a9ffefe15c4ae6acf85e13b315fbfc72b" title="returns the buffer used for reading data from the TCP connection">get_read_buffer</a>().data(), last_bytes_read);
<a name="l00070"></a>00070 }
<a name="l00071"></a>00071
<a name="l00072"></a>00072 <span class="comment">// incrementally read and parse bytes from the connection</span>
<a name="l00073"></a>00073 <span class="keywordtype">bool</span> force_connection_closed = <span class="keyword">false</span>;
<a name="l00074"></a>00074 boost::tribool parse_result;
<a name="l00075"></a>00075 <span class="keywordflow">while</span> (<span class="keyword">true</span>) {
<a name="l00076"></a>00076 <span class="comment">// parse bytes available in the read buffer</span>
<a name="l00077"></a>00077 parse_result = http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#aead5bbb8da80c78bc2de3c264e4ace9c">parse</a>(*<span class="keyword">this</span>, ec);
<a name="l00078"></a>00078 <span class="keywordflow">if</span> (! boost::indeterminate(parse_result)) <span class="keywordflow">break</span>;
<a name="l00079"></a>00079
<a name="l00080"></a>00080 <span class="comment">// read more bytes from the connection</span>
<a name="l00081"></a>00081 last_bytes_read = tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#af3c5c14c87e99bd40b605b0fb0b4a84e">read_some</a>(ec);
<a name="l00082"></a>00082 <span class="keywordflow">if</span> (ec || last_bytes_read == 0) {
<a name="l00083"></a>00083 <span class="keywordflow">if</span> (http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#ad41eedba2dd5977ffddb1bc65dddc8fc">check_premature_eof</a>(*<span class="keyword">this</span>)) {
<a name="l00084"></a>00084 <span class="comment">// premature EOF encountered</span>
<a name="l00085"></a>00085 <span class="keywordflow">if</span> (! ec)
<a name="l00086"></a>00086 ec = make_error_code(boost::system::errc::io_error);
<a name="l00087"></a>00087 <span class="keywordflow">return</span> http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#ae458700259bab34f090832c3bc23ab80" title="returns the total number of bytes read while parsing the HTTP message">get_total_bytes_read</a>();
<a name="l00088"></a>00088 } <span class="keywordflow">else</span> {
<a name="l00089"></a>00089 <span class="comment">// EOF reached when content length unknown</span>
<a name="l00090"></a>00090 <span class="comment">// assume it is the correct end of content</span>
<a name="l00091"></a>00091 <span class="comment">// and everything is OK</span>
<a name="l00092"></a>00092 force_connection_closed = <span class="keyword">true</span>;
<a name="l00093"></a>00093 parse_result = <span class="keyword">true</span>;
<a name="l00094"></a>00094 ec.clear();
<a name="l00095"></a>00095 <span class="keywordflow">break</span>;
<a name="l00096"></a>00096 }
<a name="l00097"></a>00097 <span class="keywordflow">break</span>;
<a name="l00098"></a>00098 }
<a name="l00099"></a>00099
<a name="l00100"></a>00100 <span class="comment">// update the HTTP parser's read buffer</span>
<a name="l00101"></a>00101 http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#a71fdd1e6e681a3bd932baf2bd6a9f9c9">set_read_buffer</a>(tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#a9ffefe15c4ae6acf85e13b315fbfc72b" title="returns the buffer used for reading data from the TCP connection">get_read_buffer</a>().data(), last_bytes_read);
<a name="l00102"></a>00102 }
<a name="l00103"></a>00103
<a name="l00104"></a>00104 <span class="keywordflow">if</span> (parse_result == <span class="keyword">false</span>) {
<a name="l00105"></a>00105 <span class="comment">// an error occurred while parsing the message headers</span>
<a name="l00106"></a>00106 <span class="keywordflow">return</span> http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#ae458700259bab34f090832c3bc23ab80" title="returns the total number of bytes read while parsing the HTTP message">get_total_bytes_read</a>();
<a name="l00107"></a>00107 }
<a name="l00108"></a>00108
<a name="l00109"></a>00109 <span class="comment">// set the connection's lifecycle type</span>
<a name="l00110"></a>00110 <span class="keywordflow">if</span> (!force_connection_closed && <a class="code" href="classpion_1_1http_1_1message.html#ab0aa463a1327eac0d73ff6ab62ca3891" title="returns true if the HTTP connection may be kept alive">check_keep_alive</a>()) {
<a name="l00111"></a>00111 <span class="keywordflow">if</span> ( http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#adf957476284a4833ea89306e412b1862" title="returns true if there are no more bytes available in the read buffer">eof</a>() ) {
<a name="l00112"></a>00112 <span class="comment">// the connection should be kept alive, but does not have pipelined messages</span>
<a name="l00113"></a>00113 tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#a440cc929ced689cfe4fe4bec0620162c" title="sets the lifecycle type for the connection">set_lifecycle</a>(tcp::connection::LIFECYCLE_KEEPALIVE);
<a name="l00114"></a>00114 } <span class="keywordflow">else</span> {
<a name="l00115"></a>00115 <span class="comment">// the connection has pipelined messages</span>
<a name="l00116"></a>00116 tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#a440cc929ced689cfe4fe4bec0620162c" title="sets the lifecycle type for the connection">set_lifecycle</a>(tcp::connection::LIFECYCLE_PIPELINED);
<a name="l00117"></a>00117
<a name="l00118"></a>00118 <span class="comment">// save the read position as a bookmark so that it can be retrieved</span>
<a name="l00119"></a>00119 <span class="comment">// by a new HTTP parser, which will be created after the current</span>
<a name="l00120"></a>00120 <span class="comment">// message has been handled</span>
<a name="l00121"></a>00121 <span class="keyword">const</span> <span class="keywordtype">char</span> *read_ptr;
<a name="l00122"></a>00122 <span class="keyword">const</span> <span class="keywordtype">char</span> *read_end_ptr;
<a name="l00123"></a>00123 http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#a3feba34ee7fb1c4f59dda5c1e58d3d82">load_read_pos</a>(read_ptr, read_end_ptr);
<a name="l00124"></a>00124 tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#a7951ebfca8e6834faa78417c5e87a748">save_read_pos</a>(read_ptr, read_end_ptr);
<a name="l00125"></a>00125 }
<a name="l00126"></a>00126 } <span class="keywordflow">else</span> {
<a name="l00127"></a>00127 <span class="comment">// default to close the connection</span>
<a name="l00128"></a>00128 tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#a440cc929ced689cfe4fe4bec0620162c" title="sets the lifecycle type for the connection">set_lifecycle</a>(tcp::connection::LIFECYCLE_CLOSE);
<a name="l00129"></a>00129
<a name="l00130"></a>00130 <span class="comment">// save the read position as a bookmark so that it can be retrieved</span>
<a name="l00131"></a>00131 <span class="comment">// by a new HTTP parser</span>
<a name="l00132"></a>00132 <span class="keywordflow">if</span> (http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#a37e691fd12abb6be3bf2f0dda3c412d7" title="returns true if parsing headers only">get_parse_headers_only</a>()) {
<a name="l00133"></a>00133 <span class="keyword">const</span> <span class="keywordtype">char</span> *read_ptr;
<a name="l00134"></a>00134 <span class="keyword">const</span> <span class="keywordtype">char</span> *read_end_ptr;
<a name="l00135"></a>00135 http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#a3feba34ee7fb1c4f59dda5c1e58d3d82">load_read_pos</a>(read_ptr, read_end_ptr);
<a name="l00136"></a>00136 tcp_conn.<a class="code" href="classpion_1_1tcp_1_1connection.html#a7951ebfca8e6834faa78417c5e87a748">save_read_pos</a>(read_ptr, read_end_ptr);
<a name="l00137"></a>00137 }
<a name="l00138"></a>00138 }
<a name="l00139"></a>00139
<a name="l00140"></a>00140 <span class="keywordflow">return</span> (http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#ae458700259bab34f090832c3bc23ab80" title="returns the total number of bytes read while parsing the HTTP message">get_total_bytes_read</a>());
<a name="l00141"></a>00141 }
<a name="l00142"></a>00142
<a name="l00143"></a><a class="code" href="classpion_1_1http_1_1message.html#a029d3c6260deabf91fdcc9f1f0157268">00143</a> std::size_t <a class="code" href="classpion_1_1http_1_1message.html#a7e3c3f1ea265f91b87a9e075234b5d31">message::receive</a>(<a class="code" href="classpion_1_1tcp_1_1connection.html">tcp::connection</a>& tcp_conn,
<a name="l00144"></a>00144 boost::system::error_code& ec,
<a name="l00145"></a>00145 <span class="keywordtype">bool</span> headers_only,
<a name="l00146"></a>00146 std::size_t max_content_length)
<a name="l00147"></a>00147 {
<a name="l00148"></a>00148 <a class="code" href="classpion_1_1http_1_1parser.html">http::parser</a> http_parser(dynamic_cast<http::request*>(<span class="keyword">this</span>) != NULL);
<a name="l00149"></a>00149 http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#a1f7f084f396c9c912d65426883b33a38">parse_headers_only</a>(headers_only);
<a name="l00150"></a>00150 http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#a6533144b6f6d1e93dd000360748ac271" title="sets the maximum length for HTTP payload content">set_max_content_length</a>(max_content_length);
<a name="l00151"></a>00151 <span class="keywordflow">return</span> <a class="code" href="classpion_1_1http_1_1message.html#a7e3c3f1ea265f91b87a9e075234b5d31">receive</a>(tcp_conn, ec, http_parser);
<a name="l00152"></a>00152 }
<a name="l00153"></a>00153
<a name="l00154"></a><a class="code" href="classpion_1_1http_1_1message.html#a4a3911ad03031a1ddacfa4cedeb125a2">00154</a> std::size_t <a class="code" href="classpion_1_1http_1_1message.html#a4a3911ad03031a1ddacfa4cedeb125a2">message::write</a>(std::ostream& out,
<a name="l00155"></a>00155 boost::system::error_code& ec, <span class="keywordtype">bool</span> headers_only)
<a name="l00156"></a>00156 {
<a name="l00157"></a>00157 <span class="comment">// reset error_code</span>
<a name="l00158"></a>00158 ec.clear();
<a name="l00159"></a>00159
<a name="l00160"></a>00160 <span class="comment">// initialize write buffers for send operation using HTTP headers</span>
<a name="l00161"></a>00161 <a class="code" href="classpion_1_1http_1_1message.html#aacf9a6a7677c32e4ab764ac97d0b5e7b" title="data type for I/O write buffers (these wrap existing data to be sent)">write_buffers_t</a> write_buffers;
<a name="l00162"></a>00162 <a class="code" href="classpion_1_1http_1_1message.html#a668182618dfc614ddbe6c1af26552568">prepare_buffers_for_send</a>(write_buffers, <span class="keyword">true</span>, <span class="keyword">false</span>);
<a name="l00163"></a>00163
<a name="l00164"></a>00164 <span class="comment">// append payload content to write buffers (if there is any)</span>
<a name="l00165"></a>00165 <span class="keywordflow">if</span> (!headers_only && <a class="code" href="classpion_1_1http_1_1message.html#a10606f8fd2efbe14d447ef8eb8731a54" title="returns the length of the payload content (in bytes)">get_content_length</a>() > 0 && <a class="code" href="classpion_1_1http_1_1message.html#a60ddb1bd09afecdadc5e9c33c8c1de28" title="returns a pointer to the payload content, or empty string if there is none">get_content</a>() != NULL)
<a name="l00166"></a>00166 write_buffers.push_back(boost::asio::buffer(<a class="code" href="classpion_1_1http_1_1message.html#a60ddb1bd09afecdadc5e9c33c8c1de28" title="returns a pointer to the payload content, or empty string if there is none">get_content</a>(), <a class="code" href="classpion_1_1http_1_1message.html#a10606f8fd2efbe14d447ef8eb8731a54" title="returns the length of the payload content (in bytes)">get_content_length</a>()));
<a name="l00167"></a>00167
<a name="l00168"></a>00168 <span class="comment">// write message to the output stream</span>
<a name="l00169"></a>00169 std::size_t bytes_out = 0;
<a name="l00170"></a>00170 <span class="keywordflow">for</span> (write_buffers_t::const_iterator i=write_buffers.begin(); i!=write_buffers.end(); ++i) {
<a name="l00171"></a>00171 <span class="keyword">const</span> <span class="keywordtype">char</span> *ptr = boost::asio::buffer_cast<<span class="keyword">const</span> <span class="keywordtype">char</span>*>(*i);
<a name="l00172"></a>00172 <span class="keywordtype">size_t</span> len = boost::asio::buffer_size(*i);
<a name="l00173"></a>00173 out.write(ptr, len);
<a name="l00174"></a>00174 bytes_out += len;
<a name="l00175"></a>00175 }
<a name="l00176"></a>00176
<a name="l00177"></a>00177 <span class="keywordflow">return</span> bytes_out;
<a name="l00178"></a>00178 }
<a name="l00179"></a>00179
<a name="l00180"></a><a class="code" href="classpion_1_1http_1_1message.html#a7b67f3e8303d838bb5d379ab72a35e2d">00180</a> std::size_t <a class="code" href="classpion_1_1http_1_1message.html#a7b67f3e8303d838bb5d379ab72a35e2d">message::read</a>(std::istream& in,
<a name="l00181"></a>00181 boost::system::error_code& ec,
<a name="l00182"></a>00182 <a class="code" href="classpion_1_1http_1_1parser.html">parser</a>& http_parser)
<a name="l00183"></a>00183 {
<a name="l00184"></a>00184 <span class="comment">// make sure that we start out with an empty message & clear error_code</span>
<a name="l00185"></a>00185 <a class="code" href="classpion_1_1http_1_1message.html#af13279269cf1e00ae4fc5091c1c7cae5" title="clears all message data">clear</a>();
<a name="l00186"></a>00186 ec.clear();
<a name="l00187"></a>00187
<a name="l00188"></a>00188 <span class="comment">// parse data from file one byte at a time</span>
<a name="l00189"></a>00189 boost::tribool parse_result;
<a name="l00190"></a>00190 <span class="keywordtype">char</span> c;
<a name="l00191"></a>00191 <span class="keywordflow">while</span> (in) {
<a name="l00192"></a>00192 in.read(&c, 1);
<a name="l00193"></a>00193 <span class="keywordflow">if</span> ( ! in ) {
<a name="l00194"></a>00194 ec = make_error_code(boost::system::errc::io_error);
<a name="l00195"></a>00195 <span class="keywordflow">break</span>;
<a name="l00196"></a>00196 }
<a name="l00197"></a>00197 http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#a71fdd1e6e681a3bd932baf2bd6a9f9c9">set_read_buffer</a>(&c, 1);
<a name="l00198"></a>00198 parse_result = http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#aead5bbb8da80c78bc2de3c264e4ace9c">parse</a>(*<span class="keyword">this</span>, ec);
<a name="l00199"></a>00199 <span class="keywordflow">if</span> (! boost::indeterminate(parse_result)) <span class="keywordflow">break</span>;
<a name="l00200"></a>00200 }
<a name="l00201"></a>00201
<a name="l00202"></a>00202 <span class="keywordflow">if</span> (boost::indeterminate(parse_result)) {
<a name="l00203"></a>00203 <span class="keywordflow">if</span> (http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#ad41eedba2dd5977ffddb1bc65dddc8fc">check_premature_eof</a>(*<span class="keyword">this</span>)) {
<a name="l00204"></a>00204 <span class="comment">// premature EOF encountered</span>
<a name="l00205"></a>00205 <span class="keywordflow">if</span> (! ec)
<a name="l00206"></a>00206 ec = make_error_code(boost::system::errc::io_error);
<a name="l00207"></a>00207 } <span class="keywordflow">else</span> {
<a name="l00208"></a>00208 <span class="comment">// EOF reached when content length unknown</span>
<a name="l00209"></a>00209 <span class="comment">// assume it is the correct end of content</span>
<a name="l00210"></a>00210 <span class="comment">// and everything is OK</span>
<a name="l00211"></a>00211 parse_result = <span class="keyword">true</span>;
<a name="l00212"></a>00212 ec.clear();
<a name="l00213"></a>00213 }
<a name="l00214"></a>00214 }
<a name="l00215"></a>00215
<a name="l00216"></a>00216 <span class="keywordflow">return</span> (http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#ae458700259bab34f090832c3bc23ab80" title="returns the total number of bytes read while parsing the HTTP message">get_total_bytes_read</a>());
<a name="l00217"></a>00217 }
<a name="l00218"></a>00218
<a name="l00219"></a><a class="code" href="classpion_1_1http_1_1message.html#ae99b6c39dd1b878520125f7037c035de">00219</a> std::size_t <a class="code" href="classpion_1_1http_1_1message.html#a7b67f3e8303d838bb5d379ab72a35e2d">message::read</a>(std::istream& in,
<a name="l00220"></a>00220 boost::system::error_code& ec,
<a name="l00221"></a>00221 <span class="keywordtype">bool</span> headers_only,
<a name="l00222"></a>00222 std::size_t max_content_length)
<a name="l00223"></a>00223 {
<a name="l00224"></a>00224 <a class="code" href="classpion_1_1http_1_1parser.html">http::parser</a> http_parser(dynamic_cast<http::request*>(<span class="keyword">this</span>) != NULL);
<a name="l00225"></a>00225 http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#a1f7f084f396c9c912d65426883b33a38">parse_headers_only</a>(headers_only);
<a name="l00226"></a>00226 http_parser.<a class="code" href="classpion_1_1http_1_1parser.html#a6533144b6f6d1e93dd000360748ac271" title="sets the maximum length for HTTP payload content">set_max_content_length</a>(max_content_length);
<a name="l00227"></a>00227 <span class="keywordflow">return</span> <a class="code" href="classpion_1_1http_1_1message.html#a7b67f3e8303d838bb5d379ab72a35e2d">read</a>(in, ec, http_parser);
<a name="l00228"></a>00228 }
<a name="l00229"></a>00229
<a name="l00230"></a><a class="code" href="classpion_1_1http_1_1message.html#aeffca5e2173be2b83f38b630d07f4bfd">00230</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1message.html#aeffca5e2173be2b83f38b630d07f4bfd">message::concatenate_chunks</a>(<span class="keywordtype">void</span>)
<a name="l00231"></a>00231 {
<a name="l00232"></a>00232 <a class="code" href="classpion_1_1http_1_1message.html#a81612c01ac85ebe08b947b1f9cfc2a75" title="sets the length of the payload content (in bytes)">set_content_length</a>(m_chunk_cache.size());
<a name="l00233"></a>00233 <span class="keywordtype">char</span> *post_buffer = <a class="code" href="classpion_1_1http_1_1message.html#a468f42e5bc2866d9c93138e3a4cec31b">create_content_buffer</a>();
<a name="l00234"></a>00234 <span class="keywordflow">if</span> (m_chunk_cache.size() > 0)
<a name="l00235"></a>00235 std::copy(m_chunk_cache.begin(), m_chunk_cache.end(), post_buffer);
<a name="l00236"></a>00236 }
<a name="l00237"></a>00237
<a name="l00238"></a>00238
<a name="l00239"></a>00239 } <span class="comment">// end namespace http</span>
<a name="l00240"></a>00240 } <span class="comment">// end namespace pion</span>
</pre></div></div>
<hr size="1"/><address style="text-align: right;"><small>Generated on 24 Mar 2014 for pion by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.1 </small></address>
</body>
</html>
|