|
24 | 24 | #include <boost/network/protocol/http/header.hpp>
|
25 | 25 |
|
26 | 26 | namespace boost { namespace network { namespace http {
|
27 |
| - |
| 27 | + |
28 | 28 | /// A reply to be sent to a client.
|
29 | 29 | template <>
|
30 | 30 | struct basic_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 |
| - static const char name_value_separator[] = { ':', ' ' }; |
70 |
| - static const char 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 | + static const char name_value_separator[] = { ':', ' ' }; |
| 68 | + static const char 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 |
| - return stock_reply(status, to_string(status)); |
89 |
| - } |
| 83 | + /// Get a stock reply. |
| 84 | + static basic_response<tags::http_server> stock_reply(status_type status) { |
| 85 | + return stock_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 | + void swap(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_type to_string(status_type status) {
|
108 | 112 | static const char ok[] = "";
|
109 | 113 | static const char 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_buffer to_buffer(status_type status) {
|
239 | 243 | using boost::asio::buffer;
|
240 | 244 | static const 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 | static const 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 | return buffer(ok);
|
@@ -315,15 +319,9 @@ namespace boost { namespace network { namespace http {
|
315 | 319 | return buffer(internal_server_error);
|
316 | 320 | }
|
317 | 321 | }
|
318 |
| - |
| 322 | + |
319 | 323 | };
|
320 | 324 |
|
321 |
| - template <> |
322 |
| - void swap(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 |
|
|
0 commit comments