From fc58a0bec8bf779af3afecbc6ca59a7b9c9c0b67 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 7 Nov 2016 10:42:23 +0100 Subject: Added basic HTTP server, not active yet, based on ASIO example with small refactoring included (nw) --- src/lib/http/reply.cpp | 248 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 src/lib/http/reply.cpp (limited to 'src/lib/http/reply.cpp') diff --git a/src/lib/http/reply.cpp b/src/lib/http/reply.cpp new file mode 100644 index 00000000000..0997865f336 --- /dev/null +++ b/src/lib/http/reply.cpp @@ -0,0 +1,248 @@ +// license:Boost +// copyright-holders:Christopher M. Kohlhoff + +#include "reply.hpp" +#include + +namespace http { +namespace server { + +namespace status_strings { + +const std::string ok = + "HTTP/1.0 200 OK\r\n"; +const std::string created = + "HTTP/1.0 201 Created\r\n"; +const std::string accepted = + "HTTP/1.0 202 Accepted\r\n"; +const std::string no_content = + "HTTP/1.0 204 No Content\r\n"; +const std::string multiple_choices = + "HTTP/1.0 300 Multiple Choices\r\n"; +const std::string moved_permanently = + "HTTP/1.0 301 Moved Permanently\r\n"; +const std::string moved_temporarily = + "HTTP/1.0 302 Moved Temporarily\r\n"; +const std::string not_modified = + "HTTP/1.0 304 Not Modified\r\n"; +const std::string bad_request = + "HTTP/1.0 400 Bad Request\r\n"; +const std::string unauthorized = + "HTTP/1.0 401 Unauthorized\r\n"; +const std::string forbidden = + "HTTP/1.0 403 Forbidden\r\n"; +const std::string not_found = + "HTTP/1.0 404 Not Found\r\n"; +const std::string internal_server_error = + "HTTP/1.0 500 Internal Server Error\r\n"; +const std::string not_implemented = + "HTTP/1.0 501 Not Implemented\r\n"; +const std::string bad_gateway = + "HTTP/1.0 502 Bad Gateway\r\n"; +const std::string service_unavailable = + "HTTP/1.0 503 Service Unavailable\r\n"; + +asio::const_buffer to_buffer(reply::status_type status) +{ + switch (status) + { + case reply::ok: + return asio::buffer(ok); + case reply::created: + return asio::buffer(created); + case reply::accepted: + return asio::buffer(accepted); + case reply::no_content: + return asio::buffer(no_content); + case reply::multiple_choices: + return asio::buffer(multiple_choices); + case reply::moved_permanently: + return asio::buffer(moved_permanently); + case reply::moved_temporarily: + return asio::buffer(moved_temporarily); + case reply::not_modified: + return asio::buffer(not_modified); + case reply::bad_request: + return asio::buffer(bad_request); + case reply::unauthorized: + return asio::buffer(unauthorized); + case reply::forbidden: + return asio::buffer(forbidden); + case reply::not_found: + return asio::buffer(not_found); + case reply::internal_server_error: + return asio::buffer(internal_server_error); + case reply::not_implemented: + return asio::buffer(not_implemented); + case reply::bad_gateway: + return asio::buffer(bad_gateway); + case reply::service_unavailable: + return asio::buffer(service_unavailable); + default: + return asio::buffer(internal_server_error); + } +} + +} // namespace status_strings + +namespace misc_strings { + +const char name_value_separator[] = { ':', ' ' }; +const char crlf[] = { '\r', '\n' }; + +} // namespace misc_strings + +std::vector reply::to_buffers() +{ + std::vector buffers; + buffers.push_back(status_strings::to_buffer(status)); + for (std::size_t i = 0; i < headers.size(); ++i) + { + header& h = headers[i]; + buffers.push_back(asio::buffer(h.name)); + buffers.push_back(asio::buffer(misc_strings::name_value_separator)); + buffers.push_back(asio::buffer(h.value)); + buffers.push_back(asio::buffer(misc_strings::crlf)); + } + buffers.push_back(asio::buffer(misc_strings::crlf)); + buffers.push_back(asio::buffer(content)); + return buffers; +} + +namespace stock_replies { + +const char ok[] = ""; +const char created[] = + "" + "Created" + "

201 Created

" + ""; +const char accepted[] = + "" + "Accepted" + "

202 Accepted

" + ""; +const char no_content[] = + "" + "No Content" + "

204 Content

" + ""; +const char multiple_choices[] = + "" + "Multiple Choices" + "

300 Multiple Choices

" + ""; +const char moved_permanently[] = + "" + "Moved Permanently" + "

301 Moved Permanently

" + ""; +const char moved_temporarily[] = + "" + "Moved Temporarily" + "

302 Moved Temporarily

" + ""; +const char not_modified[] = + "" + "Not Modified" + "

304 Not Modified

" + ""; +const char bad_request[] = + "" + "Bad Request" + "

400 Bad Request

" + ""; +const char unauthorized[] = + "" + "Unauthorized" + "

401 Unauthorized

" + ""; +const char forbidden[] = + "" + "Forbidden" + "

403 Forbidden

" + ""; +const char not_found[] = + "" + "Not Found" + "

404 Not Found

" + ""; +const char internal_server_error[] = + "" + "Internal Server Error" + "

500 Internal Server Error

" + ""; +const char not_implemented[] = + "" + "Not Implemented" + "

501 Not Implemented

" + ""; +const char bad_gateway[] = + "" + "Bad Gateway" + "

502 Bad Gateway

" + ""; +const char service_unavailable[] = + "" + "Service Unavailable" + "

503 Service Unavailable

" + ""; + +std::string to_string(reply::status_type status) +{ + switch (status) + { + case reply::ok: + return ok; + case reply::created: + return created; + case reply::accepted: + return accepted; + case reply::no_content: + return no_content; + case reply::multiple_choices: + return multiple_choices; + case reply::moved_permanently: + return moved_permanently; + case reply::moved_temporarily: + return moved_temporarily; + case reply::not_modified: + return not_modified; + case reply::bad_request: + return bad_request; + case reply::unauthorized: + return unauthorized; + case reply::forbidden: + return forbidden; + case reply::not_found: + return not_found; + case reply::internal_server_error: + return internal_server_error; + case reply::not_implemented: + return not_implemented; + case reply::bad_gateway: + return bad_gateway; + case reply::service_unavailable: + return service_unavailable; + default: + return internal_server_error; + } +} + +} // namespace stock_replies + +reply reply::stock_reply(reply::status_type status) +{ + reply rep; + rep.status = status; + rep.content = stock_replies::to_string(status); + rep.headers.resize(2); + rep.headers[0].name = "Content-Length"; + rep.headers[0].value = std::to_string(rep.content.size()); + rep.headers[1].name = "Content-Type"; + rep.headers[1].value = "text/html"; + return rep; +} + +} // namespace server +} // namespace http -- cgit v1.2.3-70-g09d2