13 #include <boost/algorithm/string.hpp>
14 #include <boost/lexical_cast.hpp>
21 namespace status_strings
25 const std::string
ok =
"HTTP/1.0 200 OK\r\n";
26 const std::string
created =
"HTTP/1.0 201 Created\r\n";
27 const std::string
accepted =
"HTTP/1.0 202 Accepted\r\n";
28 const std::string
no_content =
"HTTP/1.0 204 No Content\r\n";
33 const std::string
bad_request =
"HTTP/1.0 400 Bad Request\r\n";
35 const std::string
forbidden =
"HTTP/1.0 403 Forbidden\r\n";
36 const std::string
not_found =
"HTTP/1.0 404 Not Found\r\n";
38 "HTTP/1.0 500 Internal Server Error\r\n";
40 const std::string
bad_gateway =
"HTTP/1.0 502 Bad Gateway\r\n";
50 return boost::asio::buffer(
ok);
52 return boost::asio::buffer(
created);
54 return boost::asio::buffer(
accepted);
88 namespace misc_strings
92 const char crlf[] = {
'\r',
'\n'};
96 namespace stock_replies
102 "<head><title>Created</title></head>"
103 "<body><h1>201 Created</h1></body>"
107 "<head><title>Accepted</title></head>"
108 "<body><h1>202 Accepted</h1></body>"
112 "<head><title>No Content</title></head>"
113 "<body><h1>204 Content</h1></body>"
117 "<head><title>Multiple Choices</title></head>"
118 "<body><h1>300 Multiple Choices</h1></body>"
122 "<head><title>Moved Permanently</title></head>"
123 "<body><h1>301 Moved Permanently</h1></body>"
127 "<head><title>Moved Temporarily</title></head>"
128 "<body><h1>302 Moved Temporarily</h1></body>"
132 "<head><title>Not Modified</title></head>"
133 "<body><h1>304 Not Modified</h1></body>"
137 "<head><title>Bad Request</title></head>"
138 "<body><h1>400 Bad Request</h1></body>"
142 "<head><title>Unauthorized</title></head>"
143 "<body><h1>401 Unauthorized</h1></body>"
147 "<head><title>Forbidden</title></head>"
148 "<body><h1>403 Forbidden</h1></body>"
152 "<head><title>Not Found</title></head>"
153 "<body><h1>404 Not Found</h1></body>"
157 "<head><title>Internal Server Error</title></head>"
158 "<body><h1>500 Internal Server Error</h1></body>"
162 "<head><title>Not Implemented</title></head>"
163 "<body><h1>501 Not Implemented</h1></body>"
167 "<head><title>Bad Gateway</title></head>"
168 "<body><h1>502 Bad Gateway</h1></body>"
172 "<head><title>Service Unavailable</title></head>"
173 "<body><h1>503 Service Unavailable</h1></body>"
219 std::vector<boost::asio::const_buffer>
222 std::vector<boost::asio::const_buffer> buffers;
223 for (std::size_t i = 0; i < headers.size(); ++i)
226 buffers.push_back(boost::asio::buffer(h.
name));
229 buffers.push_back(boost::asio::buffer(h.
value));
238 const std::string& content_type,
239 const std::string& filename,
240 const std::vector<HttpHeader>& additional_headers)
242 std::vector<HttpHeader> headers;
243 headers.push_back(
HttpHeader(
"Content-Type", content_type));
244 std::copy(additional_headers.begin(), additional_headers.end(),
251 const std::vector<HttpHeader>& headers)
252 : status_(status), headers_(headers), filename_(filename)
258 for (
const auto& h : headers)
260 if (boost::iequals(h.name,
"content-type"))
268 if (boost::algorithm::ends_with(filename,
".js"))
269 return "application/javascript";
270 if (boost::algorithm::ends_with(filename,
".htm"))
272 if (boost::algorithm::ends_with(filename,
".html"))
274 if (boost::algorithm::ends_with(filename,
".css"))
276 if (boost::algorithm::ends_with(filename,
".png"))
278 if (boost::algorithm::ends_with(filename,
".jpg"))
280 if (boost::algorithm::ends_with(filename,
".jpeg"))
282 if (boost::algorithm::ends_with(filename,
".gif"))
284 return "application/octet-stream";
288 const std::string& filename,
289 const std::vector<HttpHeader>& headers,
290 boost::shared_ptr<HttpConnection> connection)
292 std::ifstream file_stream(filename.c_str());
293 std::stringstream file_buffer;
294 file_buffer << file_stream.rdbuf();
295 std::string content = file_buffer.str();
298 reply_builder_.
headers(headers);
301 reply_builder_.
header(
"Content-Length",
302 boost::lexical_cast<std::string>(content.size()));
303 reply_builder_.
write(connection);
304 connection->write(content);
308 const HttpRequest& request, boost::shared_ptr<HttpConnection> connection,
309 const char* begin,
const char* end)
316 const std::string& filesystem_root,
bool list_directories,
317 const std::vector<HttpHeader>& additional_headers)
320 list_directories, additional_headers);
324 const std::string& filesystem_root,
bool list_directories,
325 const std::vector<HttpHeader>& headers)
326 : status_(status), headers_(headers), path_root_(path_root),
327 filesystem_root_(filesystem_root), list_directories_(list_directories)
332 const HttpRequest& request, boost::shared_ptr<HttpConnection> connection,
333 const char* begin,
const char* end)
338 if (rel_path.find_first_of(
'/') == 0)
340 rel_path = rel_path.substr(1);
345 if (boost::filesystem::exists(requested_path))
347 if (boost::filesystem::is_directory(requested_path))
351 std::stringstream content;
352 content <<
"<html><body>";
353 content <<
"<h1> Directory Listing: " << request.
path
355 boost::filesystem::directory_iterator end_itr;
356 for (boost::filesystem::directory_iterator itr(
358 itr != end_itr; ++itr)
360 if (boost::filesystem::is_directory(itr->status()))
362 content <<
"<a href=\""
363 << itr->path().leaf().generic_string()
365 content << itr->path().leaf().generic_string()
369 else if (boost::filesystem::is_regular_file(
372 content <<
"<a href=\""
373 << itr->path().leaf().generic_string()
375 content << itr->path().leaf().generic_string();
380 content <<
"</body></html>";
383 request, connection, begin, end);
388 request, connection, begin, end);
392 else if (boost::filesystem::is_regular_file(requested_path))
417 const std::string& content_type,
418 const std::string& content,
419 const std::vector<HttpHeader>& additional_headers)
421 std::vector<HttpHeader> headers;
423 "Content-Length", boost::lexical_cast<std::string>(content.size())));
424 headers.push_back(
HttpHeader(
"Content-Type", content_type));
425 std::copy(additional_headers.begin(), additional_headers.end(),
432 const std::string& content)
433 : reply_builder_(status), content_string_(content)
439 const HttpRequest& request, boost::shared_ptr<HttpConnection> connection,
440 const char* begin,
const char* end)
453 : status_(status), headers_(new std::vector<
HttpHeader>())
458 const std::string& value)