|
24 | 24 | #include<boost/network/protocol/http/header.hpp> |
25 | 25 |
|
26 | 26 | namespaceboost {namespacenetwork {namespacehttp { |
27 | | - |
| 27 | +
|
28 | 28 | /// A reply to be sent to a client. |
29 | 29 | template<> |
30 | 30 | structbasic_response<tags::http_server> { |
| 31 | +/// The status of the reply. |
| 32 | +enum status_type { |
| 33 | + ok =200, |
| 34 | + created =201, |
| 35 | + accepted =202, |
| 36 | + no_content =204, |
| 37 | + multiple_choices =300, |
| 38 | + moved_permanently =301, |
| 39 | + moved_temporarily =302, |
| 40 | + not_modified =304, |
| 41 | + bad_request =400, |
| 42 | + unauthorized =401, |
| 43 | + forbidden =403, |
| 44 | + not_found =404, |
| 45 | + not_supported =405, |
| 46 | + not_acceptable =406, |
| 47 | + internal_server_error =500, |
| 48 | + not_implemented =501, |
| 49 | + bad_gateway =502, |
| 50 | + service_unavailable =503 |
| 51 | + } status; |
| 52 | + |
| 53 | +/// The headers to be included in the reply. |
| 54 | +typedef vector<tags::http_server>::apply<request_header>::type headers_vector; |
| 55 | + headers_vector headers; |
31 | 56 |
|
32 | | -/// The status of the reply. |
33 | | -enum status_type |
34 | | - { |
35 | | - ok =200, |
36 | | - created =201, |
37 | | - accepted =202, |
38 | | - no_content =204, |
39 | | - multiple_choices =300, |
40 | | - moved_permanently =301, |
41 | | - moved_temporarily =302, |
42 | | - not_modified =304, |
43 | | - bad_request =400, |
44 | | - unauthorized =401, |
45 | | - forbidden =403, |
46 | | - not_found =404, |
47 | | - not_supported =405, |
48 | | - not_acceptable =406, |
49 | | - internal_server_error =500, |
50 | | - not_implemented =501, |
51 | | - bad_gateway =502, |
52 | | - service_unavailable =503 |
53 | | - } status; |
54 | | - |
55 | | -/// The headers to be included in the reply. |
56 | | -typedef vector<tags::http_server>::apply<request_header>::type headers_vector; |
57 | | - headers_vector headers; |
| 57 | +/// The content to be sent in the reply. |
| 58 | +typedef string<tags::http_server>::type string_type; |
| 59 | + string_type content; |
58 | 60 |
|
59 | | -/// The content to be sent in the reply. |
60 | | -typedef string<tags::http_server>::type string_type; |
61 | | - string_type content; |
62 | | - |
63 | | -/// Convert the reply into a vector of buffers. The buffers do not own the |
64 | | -/// underlying memory blocks, therefore the reply object must remain valid and |
65 | | -/// not be changed until the write operation has completed. |
66 | | - std::vector<boost::asio::const_buffer>to_buffers() { |
67 | | -using boost::asio::const_buffer; |
68 | | -using boost::asio::buffer; |
69 | | -staticconstchar name_value_separator[] = {':','' }; |
70 | | -staticconstchar crlf[] = {'\r','\n' }; |
71 | | - std::vector<const_buffer> buffers; |
72 | | - buffers.push_back(to_buffer(status)); |
73 | | -for (std::size_t i =0; i < headers.size(); ++i) |
74 | | - { |
75 | | - request_header& h = headers[i]; |
76 | | - buffers.push_back(buffer(h.name)); |
77 | | - buffers.push_back(buffer(name_value_separator)); |
78 | | - buffers.push_back(buffer(h.value)); |
| 61 | +/// Convert the reply into a vector of buffers. The buffers do not own the |
| 62 | +/// underlying memory blocks, therefore the reply object must remain valid and |
| 63 | +/// not be changed until the write operation has completed. |
| 64 | + std::vector<boost::asio::const_buffer>to_buffers() { |
| 65 | +using boost::asio::const_buffer; |
| 66 | +using boost::asio::buffer; |
| 67 | +staticconstchar name_value_separator[] = {':','' }; |
| 68 | +staticconstchar crlf[] = {'\r','\n' }; |
| 69 | + std::vector<const_buffer> buffers; |
| 70 | + buffers.push_back(to_buffer(status)); |
| 71 | +for (std::size_t i =0; i < headers.size(); ++i) { |
| 72 | + request_header& h = headers[i]; |
| 73 | + buffers.push_back(buffer(h.name)); |
| 74 | + buffers.push_back(buffer(name_value_separator)); |
| 75 | + buffers.push_back(buffer(h.value)); |
| 76 | + buffers.push_back(buffer(crlf)); |
| 77 | + } |
79 | 78 | buffers.push_back(buffer(crlf)); |
80 | | - } |
81 | | - buffers.push_back(buffer(crlf)); |
82 | | - buffers.push_back(buffer(content)); |
83 | | -return buffers; |
84 | | - } |
| 79 | + buffers.push_back(buffer(content)); |
| 80 | +return buffers; |
| 81 | + } |
85 | 82 |
|
86 | | -/// Get a stock reply. |
87 | | -static basic_response<tags::http_server>stock_reply(status_type status) { |
88 | | -returnstock_reply(status,to_string(status)); |
89 | | - } |
| 83 | +/// Get a stock reply. |
| 84 | +static basic_response<tags::http_server>stock_reply(status_type status) { |
| 85 | +returnstock_reply(status,to_string(status)); |
| 86 | +} |
90 | 87 |
|
91 | | -/// Get a stock reply with custom plain text data. |
92 | | -static basic_response<tags::http_server>stock_reply(status_type status, string_type content) { |
93 | | -using boost::lexical_cast; |
94 | | - basic_response<tags::http_server> rep; |
95 | | - rep.status = status; |
96 | | - rep.content = content; |
97 | | - rep.headers.resize(2); |
98 | | - rep.headers[0].name ="Content-Length"; |
99 | | - rep.headers[0].value = lexical_cast<string_type>(rep.content.size()); |
100 | | - rep.headers[1].name ="Content-Type"; |
101 | | - rep.headers[1].value ="text/html"; |
102 | | -return rep; |
103 | | - } |
| 88 | +/// Get a stock reply with custom plain text data. |
| 89 | +static basic_response<tags::http_server>stock_reply(status_type status, string_type content) { |
| 90 | +using boost::lexical_cast; |
| 91 | +basic_response<tags::http_server> rep; |
| 92 | +rep.status = status; |
| 93 | +rep.content = content; |
| 94 | +rep.headers.resize(2); |
| 95 | +rep.headers[0].name ="Content-Length"; |
| 96 | +rep.headers[0].value = lexical_cast<string_type>(rep.content.size()); |
| 97 | +rep.headers[1].name ="Content-Type"; |
| 98 | +rep.headers[1].value ="text/html"; |
| 99 | +return rep; |
| 100 | +} |
104 | 101 |
|
105 | | -private: |
| 102 | +/// Swap response objects |
| 103 | +voidswap(basic_response<tags::http_server> &r) { |
| 104 | +using std::swap; |
| 105 | +swap(headers, r.headers); |
| 106 | +swap(content, r.content); |
| 107 | + } |
106 | 108 |
|
| 109 | +private: |
| 110 | + |
107 | 111 | static string_typeto_string(status_type status) { |
108 | 112 | staticconstchar ok[] =""; |
109 | 113 | staticconstchar created[] = |
@@ -191,7 +195,7 @@ namespace boost { namespace network { namespace http { |
191 | 195 | "<head><title>Service Unavailable</title></head>" |
192 | 196 | "<body><h1>503 Service Unavailable</h1></body>" |
193 | 197 | "</html>"; |
194 | | - |
| 198 | +
|
195 | 199 | switch (status) |
196 | 200 | { |
197 | 201 | case basic_response<tags::http_server>::ok: |
@@ -234,7 +238,7 @@ namespace boost { namespace network { namespace http { |
234 | 238 | return internal_server_error; |
235 | 239 | } |
236 | 240 | } |
237 | | - |
| 241 | +
|
238 | 242 | boost::asio::const_bufferto_buffer(status_type status) { |
239 | 243 | using boost::asio::buffer; |
240 | 244 | staticconst string_type ok = |
@@ -273,7 +277,7 @@ namespace boost { namespace network { namespace http { |
273 | 277 | "HTTP/1.0 502 Bad Gateway\r\n"; |
274 | 278 | staticconst string_type service_unavailable = |
275 | 279 | "HTTP/1.0 503 Service Unavailable\r\n"; |
276 | | - |
| 280 | +
|
277 | 281 | switch (status) { |
278 | 282 | case basic_response<tags::http_server>::ok: |
279 | 283 | returnbuffer(ok); |
@@ -315,15 +319,9 @@ namespace boost { namespace network { namespace http { |
315 | 319 | returnbuffer(internal_server_error); |
316 | 320 | } |
317 | 321 | } |
318 | | - |
| 322 | +
|
319 | 323 | }; |
320 | 324 |
|
321 | | -template<> |
322 | | -voidswap(basic_response<tags::http_server> &l, basic_response<tags::http_server> &r) { |
323 | | -using std::swap; |
324 | | -swap(l.headers, r.headers); |
325 | | -swap(l.content, r.content); |
326 | | - } |
327 | 325 |
|
328 | 326 | }// namespace http |
329 | 327 |
|
|