1 // 2 // reply.cpp 3 // ~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 // 10 11 #include "reply.hpp" 12 #include <string> 13 #include <boost/lexical_cast.hpp> 14 15 namespace http { 16 namespace server3 { 17 18 namespace status_strings { 19 20 const std::string ok = 21 "HTTP/1.0 200 OK\r\n"; 22 const std::string created = 23 "HTTP/1.0 201 Created\r\n"; 24 const std::string accepted = 25 "HTTP/1.0 202 Accepted\r\n"; 26 const std::string no_content = 27 "HTTP/1.0 204 No Content\r\n"; 28 const std::string multiple_choices = 29 "HTTP/1.0 300 Multiple Choices\r\n"; 30 const std::string moved_permanently = 31 "HTTP/1.0 301 Moved Permanently\r\n"; 32 const std::string moved_temporarily = 33 "HTTP/1.0 302 Moved Temporarily\r\n"; 34 const std::string not_modified = 35 "HTTP/1.0 304 Not Modified\r\n"; 36 const std::string bad_request = 37 "HTTP/1.0 400 Bad Request\r\n"; 38 const std::string unauthorized = 39 "HTTP/1.0 401 Unauthorized\r\n"; 40 const std::string forbidden = 41 "HTTP/1.0 403 Forbidden\r\n"; 42 const std::string not_found = 43 "HTTP/1.0 404 Not Found\r\n"; 44 const std::string internal_server_error = 45 "HTTP/1.0 500 Internal Server Error\r\n"; 46 const std::string not_implemented = 47 "HTTP/1.0 501 Not Implemented\r\n"; 48 const std::string bad_gateway = 49 "HTTP/1.0 502 Bad Gateway\r\n"; 50 const std::string service_unavailable = 51 "HTTP/1.0 503 Service Unavailable\r\n"; 52 to_buffer(reply::status_type status)53boost::asio::const_buffer to_buffer(reply::status_type status) 54 { 55 switch (status) 56 { 57 case reply::ok: 58 return boost::asio::buffer(ok); 59 case reply::created: 60 return boost::asio::buffer(created); 61 case reply::accepted: 62 return boost::asio::buffer(accepted); 63 case reply::no_content: 64 return boost::asio::buffer(no_content); 65 case reply::multiple_choices: 66 return boost::asio::buffer(multiple_choices); 67 case reply::moved_permanently: 68 return boost::asio::buffer(moved_permanently); 69 case reply::moved_temporarily: 70 return boost::asio::buffer(moved_temporarily); 71 case reply::not_modified: 72 return boost::asio::buffer(not_modified); 73 case reply::bad_request: 74 return boost::asio::buffer(bad_request); 75 case reply::unauthorized: 76 return boost::asio::buffer(unauthorized); 77 case reply::forbidden: 78 return boost::asio::buffer(forbidden); 79 case reply::not_found: 80 return boost::asio::buffer(not_found); 81 case reply::internal_server_error: 82 return boost::asio::buffer(internal_server_error); 83 case reply::not_implemented: 84 return boost::asio::buffer(not_implemented); 85 case reply::bad_gateway: 86 return boost::asio::buffer(bad_gateway); 87 case reply::service_unavailable: 88 return boost::asio::buffer(service_unavailable); 89 default: 90 return boost::asio::buffer(internal_server_error); 91 } 92 } 93 94 } // namespace status_strings 95 96 namespace misc_strings { 97 98 const char name_value_separator[] = { ':', ' ' }; 99 const char crlf[] = { '\r', '\n' }; 100 101 } // namespace misc_strings 102 to_buffers()103std::vector<boost::asio::const_buffer> reply::to_buffers() 104 { 105 std::vector<boost::asio::const_buffer> buffers; 106 buffers.push_back(status_strings::to_buffer(status)); 107 for (std::size_t i = 0; i < headers.size(); ++i) 108 { 109 header& h = headers[i]; 110 buffers.push_back(boost::asio::buffer(h.name)); 111 buffers.push_back(boost::asio::buffer(misc_strings::name_value_separator)); 112 buffers.push_back(boost::asio::buffer(h.value)); 113 buffers.push_back(boost::asio::buffer(misc_strings::crlf)); 114 } 115 buffers.push_back(boost::asio::buffer(misc_strings::crlf)); 116 buffers.push_back(boost::asio::buffer(content)); 117 return buffers; 118 } 119 120 namespace stock_replies { 121 122 const char ok[] = ""; 123 const char created[] = 124 "<html>" 125 "<head><title>Created</title></head>" 126 "<body><h1>201 Created</h1></body>" 127 "</html>"; 128 const char accepted[] = 129 "<html>" 130 "<head><title>Accepted</title></head>" 131 "<body><h1>202 Accepted</h1></body>" 132 "</html>"; 133 const char no_content[] = 134 "<html>" 135 "<head><title>No Content</title></head>" 136 "<body><h1>204 Content</h1></body>" 137 "</html>"; 138 const char multiple_choices[] = 139 "<html>" 140 "<head><title>Multiple Choices</title></head>" 141 "<body><h1>300 Multiple Choices</h1></body>" 142 "</html>"; 143 const char moved_permanently[] = 144 "<html>" 145 "<head><title>Moved Permanently</title></head>" 146 "<body><h1>301 Moved Permanently</h1></body>" 147 "</html>"; 148 const char moved_temporarily[] = 149 "<html>" 150 "<head><title>Moved Temporarily</title></head>" 151 "<body><h1>302 Moved Temporarily</h1></body>" 152 "</html>"; 153 const char not_modified[] = 154 "<html>" 155 "<head><title>Not Modified</title></head>" 156 "<body><h1>304 Not Modified</h1></body>" 157 "</html>"; 158 const char bad_request[] = 159 "<html>" 160 "<head><title>Bad Request</title></head>" 161 "<body><h1>400 Bad Request</h1></body>" 162 "</html>"; 163 const char unauthorized[] = 164 "<html>" 165 "<head><title>Unauthorized</title></head>" 166 "<body><h1>401 Unauthorized</h1></body>" 167 "</html>"; 168 const char forbidden[] = 169 "<html>" 170 "<head><title>Forbidden</title></head>" 171 "<body><h1>403 Forbidden</h1></body>" 172 "</html>"; 173 const char not_found[] = 174 "<html>" 175 "<head><title>Not Found</title></head>" 176 "<body><h1>404 Not Found</h1></body>" 177 "</html>"; 178 const char internal_server_error[] = 179 "<html>" 180 "<head><title>Internal Server Error</title></head>" 181 "<body><h1>500 Internal Server Error</h1></body>" 182 "</html>"; 183 const char not_implemented[] = 184 "<html>" 185 "<head><title>Not Implemented</title></head>" 186 "<body><h1>501 Not Implemented</h1></body>" 187 "</html>"; 188 const char bad_gateway[] = 189 "<html>" 190 "<head><title>Bad Gateway</title></head>" 191 "<body><h1>502 Bad Gateway</h1></body>" 192 "</html>"; 193 const char service_unavailable[] = 194 "<html>" 195 "<head><title>Service Unavailable</title></head>" 196 "<body><h1>503 Service Unavailable</h1></body>" 197 "</html>"; 198 to_string(reply::status_type status)199std::string to_string(reply::status_type status) 200 { 201 switch (status) 202 { 203 case reply::ok: 204 return ok; 205 case reply::created: 206 return created; 207 case reply::accepted: 208 return accepted; 209 case reply::no_content: 210 return no_content; 211 case reply::multiple_choices: 212 return multiple_choices; 213 case reply::moved_permanently: 214 return moved_permanently; 215 case reply::moved_temporarily: 216 return moved_temporarily; 217 case reply::not_modified: 218 return not_modified; 219 case reply::bad_request: 220 return bad_request; 221 case reply::unauthorized: 222 return unauthorized; 223 case reply::forbidden: 224 return forbidden; 225 case reply::not_found: 226 return not_found; 227 case reply::internal_server_error: 228 return internal_server_error; 229 case reply::not_implemented: 230 return not_implemented; 231 case reply::bad_gateway: 232 return bad_gateway; 233 case reply::service_unavailable: 234 return service_unavailable; 235 default: 236 return internal_server_error; 237 } 238 } 239 240 } // namespace stock_replies 241 stock_reply(reply::status_type status)242reply reply::stock_reply(reply::status_type status) 243 { 244 reply rep; 245 rep.status = status; 246 rep.content = stock_replies::to_string(status); 247 rep.headers.resize(2); 248 rep.headers[0].name = "Content-Length"; 249 rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size()); 250 rep.headers[1].name = "Content-Type"; 251 rep.headers[1].value = "text/html"; 252 return rep; 253 } 254 255 } // namespace server3 256 } // namespace http 257