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