|
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 |
|
|