refactor Server/Http to remove camel case

This commit is contained in:
Dennis Luxen 2015-01-27 11:45:33 +01:00
parent f0d3d23b5f
commit 3e47fe54fa
13 changed files with 293 additions and 152 deletions

View File

@ -65,7 +65,7 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
} }
// no error detected, let's parse the request // no error detected, let's parse the request
CompressionType compression_type(noCompression); compression_type compression_type(no_compression);
osrm::tribool result; osrm::tribool result;
std::tie(result, compression_type) = RequestParser().parse( std::tie(result, compression_type) = RequestParser().parse(
request, incoming_data_buffer.data(), incoming_data_buffer.data() + bytes_transferred); request, incoming_data_buffer.data(), incoming_data_buffer.data() + bytes_transferred);
@ -83,26 +83,26 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
// compress the result w/ gzip/deflate if requested // compress the result w/ gzip/deflate if requested
switch (compression_type) switch (compression_type)
{ {
case deflateRFC1951: case deflate_rfc1951:
// use deflate for compression // use deflate for compression
reply.headers.insert(reply.headers.begin(), {"Content-Encoding", "deflate"}); reply.headers.insert(reply.headers.begin(), {"Content-Encoding", "deflate"});
compressed_output = compress_buffers(reply.content, compression_type); compressed_output = compress_buffers(reply.content, compression_type);
reply.SetSize(static_cast<unsigned>(compressed_output.size())); reply.set_size(static_cast<unsigned>(compressed_output.size()));
output_buffer = reply.HeaderstoBuffers(); output_buffer = reply.headers_to_buffers();
output_buffer.push_back(boost::asio::buffer(compressed_output)); output_buffer.push_back(boost::asio::buffer(compressed_output));
break; break;
case gzipRFC1952: case gzip_rfc1952:
// use gzip for compression // use gzip for compression
reply.headers.insert(reply.headers.begin(), {"Content-Encoding", "gzip"}); reply.headers.insert(reply.headers.begin(), {"Content-Encoding", "gzip"});
compressed_output = compress_buffers(reply.content, compression_type); compressed_output = compress_buffers(reply.content, compression_type);
reply.SetSize(static_cast<unsigned>(compressed_output.size())); reply.set_size(static_cast<unsigned>(compressed_output.size()));
output_buffer = reply.HeaderstoBuffers(); output_buffer = reply.headers_to_buffers();
output_buffer.push_back(boost::asio::buffer(compressed_output)); output_buffer.push_back(boost::asio::buffer(compressed_output));
break; break;
case noCompression: case no_compression:
// don't use any compression // don't use any compression
reply.SetUncompressedSize(); reply.set_uncompressed_size();
output_buffer = reply.ToBuffers(); output_buffer = reply.to_buffers();
break; break;
} }
// write result to stream // write result to stream
@ -113,10 +113,10 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
} }
else if (result == osrm::tribool::no) else if (result == osrm::tribool::no)
{ // request is not parseable { // request is not parseable
reply = Reply::StockReply(Reply::badRequest); reply = reply::stock_reply(reply::bad_request);
boost::asio::async_write( boost::asio::async_write(
TCP_socket, reply.ToBuffers(), TCP_socket, reply.to_buffers(),
strand.wrap(boost::bind(&Connection::handle_write, this->shared_from_this(), strand.wrap(boost::bind(&Connection::handle_write, this->shared_from_this(),
boost::asio::placeholders::error))); boost::asio::placeholders::error)));
} }
@ -143,14 +143,14 @@ void Connection::handle_write(const boost::system::error_code &error)
} }
std::vector<char> Connection::compress_buffers(const std::vector<char> &uncompressed_data, std::vector<char> Connection::compress_buffers(const std::vector<char> &uncompressed_data,
const CompressionType compression_type) const compression_type compression_type)
{ {
boost::iostreams::gzip_params compression_parameters; boost::iostreams::gzip_params compression_parameters;
// there's a trade-off between speed and size. speed wins // there's a trade-off between speed and size. speed wins
compression_parameters.level = boost::iostreams::zlib::best_speed; compression_parameters.level = boost::iostreams::zlib::best_speed;
// check which compression flavor is used // check which compression flavor is used
if (deflateRFC1951 == compression_type) if (deflate_rfc1951 == compression_type)
{ {
compression_parameters.noheader = true; compression_parameters.noheader = true;
} }

View File

@ -28,9 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CONNECTION_H #ifndef CONNECTION_H
#define CONNECTION_H #define CONNECTION_H
#include "Http/CompressionType.h" #include "http/compression_type.hpp"
#include "Http/Reply.h" #include "http/reply.hpp"
#include "Http/Request.h" #include "http/request.hpp"
#include <boost/array.hpp> #include <boost/array.hpp>
#include <boost/asio.hpp> #include <boost/asio.hpp>
@ -77,14 +77,14 @@ class Connection : public std::enable_shared_from_this<Connection>
void handle_write(const boost::system::error_code &e); void handle_write(const boost::system::error_code &e);
std::vector<char> compress_buffers(const std::vector<char> &uncompressed_data, std::vector<char> compress_buffers(const std::vector<char> &uncompressed_data,
const CompressionType compression_type); const compression_type compression_type);
boost::asio::io_service::strand strand; boost::asio::io_service::strand strand;
boost::asio::ip::tcp::socket TCP_socket; boost::asio::ip::tcp::socket TCP_socket;
RequestHandler &request_handler; RequestHandler &request_handler;
boost::array<char, 8192> incoming_data_buffer; boost::array<char, 8192> incoming_data_buffer;
Request request; request request;
Reply reply; reply reply;
}; };
} // namespace http } // namespace http

View File

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
@ -25,16 +25,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "Reply.h" #include "reply.hpp"
#include "../../Util/cast.hpp" #include "../../Util/cast.hpp"
namespace http namespace http
{ {
void Reply::SetSize(const unsigned size) const char okHTML[] = "";
const char badRequestHTML[] = "{\"status\": 400,\"status_message\":\"Bad Request\"}";
const char internalServerErrorHTML[] =
"{\"status\": 500,\"status_message\":\"Internal Server Error\"}";
const char seperators[] = {':', ' '};
const char crlf[] = {'\r', '\n'};
const std::string okString = "HTTP/1.0 200 OK\r\n";
const std::string badRequestString = "HTTP/1.0 400 Bad Request\r\n";
const std::string internalServerErrorString = "HTTP/1.0 500 Internal Server Error\r\n";
void reply::set_size(const std::size_t size)
{ {
for (Header &h : headers) for (header &h : headers)
{ {
if ("Content-Length" == h.name) if ("Content-Length" == h.name)
{ {
@ -43,14 +53,13 @@ void Reply::SetSize(const unsigned size)
} }
} }
// Sets the size of the uncompressed output. void reply::set_uncompressed_size() { set_size(content.size()); }
void Reply::SetUncompressedSize() { SetSize(static_cast<unsigned>(content.size())); }
std::vector<boost::asio::const_buffer> Reply::ToBuffers() std::vector<boost::asio::const_buffer> reply::to_buffers()
{ {
std::vector<boost::asio::const_buffer> buffers; std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(ToBuffer(status)); buffers.push_back(status_to_buffer(status));
for (const Header &h : headers) for (const header &h : headers)
{ {
buffers.push_back(boost::asio::buffer(h.name)); buffers.push_back(boost::asio::buffer(h.name));
buffers.push_back(boost::asio::buffer(seperators)); buffers.push_back(boost::asio::buffer(seperators));
@ -62,13 +71,12 @@ std::vector<boost::asio::const_buffer> Reply::ToBuffers()
return buffers; return buffers;
} }
std::vector<boost::asio::const_buffer> Reply::HeaderstoBuffers() std::vector<boost::asio::const_buffer> reply::headers_to_buffers()
{ {
std::vector<boost::asio::const_buffer> buffers; std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(ToBuffer(status)); buffers.push_back(status_to_buffer(status));
for (std::size_t i = 0; i < headers.size(); ++i) for (const header &current_header : headers)
{ {
Header &current_header = headers[i];
buffers.push_back(boost::asio::buffer(current_header.name)); buffers.push_back(boost::asio::buffer(current_header.name));
buffers.push_back(boost::asio::buffer(seperators)); buffers.push_back(boost::asio::buffer(seperators));
buffers.push_back(boost::asio::buffer(current_header.value)); buffers.push_back(boost::asio::buffer(current_header.value));
@ -78,13 +86,13 @@ std::vector<boost::asio::const_buffer> Reply::HeaderstoBuffers()
return buffers; return buffers;
} }
Reply Reply::StockReply(Reply::status_type status) reply reply::stock_reply(const reply::status_type status)
{ {
Reply reply; reply reply;
reply.status = status; reply.status = status;
reply.content.clear(); reply.content.clear();
const std::string status_string = reply.ToString(status); const std::string status_string = reply.status_to_string(status);
reply.content.insert(reply.content.end(), status_string.begin(), status_string.end()); reply.content.insert(reply.content.end(), status_string.begin(), status_string.end());
reply.headers.emplace_back("Access-Control-Allow-Origin", "*"); reply.headers.emplace_back("Access-Control-Allow-Origin", "*");
reply.headers.emplace_back("Content-Length", cast::integral_to_string(reply.content.size())); reply.headers.emplace_back("Content-Length", cast::integral_to_string(reply.content.size()));
@ -92,31 +100,31 @@ Reply Reply::StockReply(Reply::status_type status)
return reply; return reply;
} }
std::string Reply::ToString(Reply::status_type status) std::string reply::status_to_string(const reply::status_type status)
{ {
if (Reply::ok == status) if (reply::ok == status)
{ {
return okHTML; return okHTML;
} }
if (Reply::badRequest == status) if (reply::bad_request == status)
{ {
return badRequestHTML; return badRequestHTML;
} }
return internalServerErrorHTML; return internalServerErrorHTML;
} }
boost::asio::const_buffer Reply::ToBuffer(Reply::status_type status) boost::asio::const_buffer reply::status_to_buffer(const reply::status_type status)
{ {
if (Reply::ok == status) if (reply::ok == status)
{ {
return boost::asio::buffer(okString); return boost::asio::buffer(okString);
} }
if (Reply::internalServerError == status) if (reply::internal_server_error == status)
{ {
return boost::asio::buffer(internalServerErrorString); return boost::asio::buffer(internalServerErrorString);
} }
return boost::asio::buffer(badRequestString); return boost::asio::buffer(badRequestString);
} }
Reply::Reply() : status(ok) {} reply::reply() : status(ok) {}
} }

View File

@ -28,8 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "RequestHandler.h" #include "RequestHandler.h"
#include "APIGrammar.h" #include "APIGrammar.h"
#include "Http/Reply.h" #include "http/reply.hpp"
#include "Http/Request.h" #include "http/request.hpp"
#include "../Library/OSRM.h" #include "../Library/OSRM.h"
#include "../Util/json_renderer.hpp" #include "../Util/json_renderer.hpp"
@ -48,20 +48,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
RequestHandler::RequestHandler() : routing_machine(nullptr) {} RequestHandler::RequestHandler() : routing_machine(nullptr) {}
void RequestHandler::handle_request(const http::Request &req, http::Reply &reply) void RequestHandler::handle_request(const http::request &current_request,
http::reply &current_reply)
{ {
// parse command // parse command
try try
{ {
std::string request; std::string request_string;
URIDecode(req.uri, request); URIDecode(current_request.uri, request_string);
// deactivated as GCC apparently does not implement that, not even in 4.9 // deactivated as GCC apparently does not implement that, not even in 4.9
// std::time_t t = std::time(nullptr); // std::time_t t = std::time(nullptr);
// SimpleLogger().Write() << std::put_time(std::localtime(&t), "%m-%d-%Y %H:%M:%S") << // SimpleLogger().Write() << std::put_time(std::localtime(&t), "%m-%d-%Y %H:%M:%S") <<
// " " << req.endpoint.to_string() << " " << // " " << current_request.endpoint.to_string() << " " <<
// req.referrer << ( 0 == req.referrer.length() ? "- " :" ") << // current_request.referrer << ( 0 == current_request.referrer.length() ? "- " :" ") <<
// req.agent << ( 0 == req.agent.length() ? "- " :" ") << request; // current_request.agent << ( 0 == current_request.agent.length() ? "- " :" ") <<
// request;
time_t ltime; time_t ltime;
struct tm *time_stamp; struct tm *time_stamp;
@ -76,29 +78,33 @@ void RequestHandler::handle_request(const http::Request &req, http::Reply &reply
<< " " << (time_stamp->tm_hour < 10 ? "0" : "") << " " << (time_stamp->tm_hour < 10 ? "0" : "")
<< time_stamp->tm_hour << ":" << (time_stamp->tm_min < 10 ? "0" : "") << time_stamp->tm_hour << ":" << (time_stamp->tm_min < 10 ? "0" : "")
<< time_stamp->tm_min << ":" << (time_stamp->tm_sec < 10 ? "0" : "") << time_stamp->tm_min << ":" << (time_stamp->tm_sec < 10 ? "0" : "")
<< time_stamp->tm_sec << " " << req.endpoint.to_string() << " " << time_stamp->tm_sec << " " << current_request.endpoint.to_string()
<< req.referrer << (0 == req.referrer.length() ? "- " : " ") << " " << current_request.referrer
<< req.agent << (0 == req.agent.length() ? "- " : " ") << request; << (0 == current_request.referrer.length() ? "- " : " ")
<< current_request.agent
<< (0 == current_request.agent.length() ? "- " : " ")
<< request_string;
RouteParameters route_parameters; RouteParameters route_parameters;
APIGrammarParser api_parser(&route_parameters); APIGrammarParser api_parser(&route_parameters);
auto api_iterator = request.begin(); auto api_iterator = request_string.begin();
const bool result = boost::spirit::qi::parse(api_iterator, request.end(), api_parser); const bool result =
boost::spirit::qi::parse(api_iterator, request_string.end(), api_parser);
JSON::Object json_result; JSON::Object json_result;
// check if the was an error with the request // check if the was an error with the request
if (!result || (api_iterator != request.end())) if (!result || (api_iterator != request_string.end()))
{ {
reply = http::Reply::StockReply(http::Reply::badRequest); current_reply = http::reply::stock_reply(http::reply::bad_request);
reply.content.clear(); current_reply.content.clear();
const auto position = std::distance(request.begin(), api_iterator); const auto position = std::distance(request_string.begin(), api_iterator);
json_result.values["status"] = 400; json_result.values["status"] = 400;
std::string message = "Query string malformed close to position "; std::string message = "Query string malformed close to position ";
message += cast::integral_to_string(position); message += cast::integral_to_string(position);
json_result.values["status_message"] = message; json_result.values["status_message"] = message;
JSON::render(reply.content, json_result); JSON::render(current_reply.content, json_result);
return; return;
} }
@ -108,50 +114,54 @@ void RequestHandler::handle_request(const http::Request &req, http::Reply &reply
if (!route_parameters.jsonp_parameter.empty()) if (!route_parameters.jsonp_parameter.empty())
{ // prepend response with jsonp parameter { // prepend response with jsonp parameter
const std::string json_p = (route_parameters.jsonp_parameter + "("); const std::string json_p = (route_parameters.jsonp_parameter + "(");
reply.content.insert(reply.content.end(), json_p.begin(), json_p.end()); current_reply.content.insert(current_reply.content.end(), json_p.begin(), json_p.end());
} }
const auto return_code = routing_machine->RunQuery(route_parameters, json_result); const auto return_code = routing_machine->RunQuery(route_parameters, json_result);
if (200 != return_code) if (200 != return_code)
{ {
reply = http::Reply::StockReply(http::Reply::badRequest); current_reply = http::reply::stock_reply(http::reply::bad_request);
reply.content.clear(); current_reply.content.clear();
json_result.values["status"] = 400; json_result.values["status"] = 400;
std::string message = "Bad Request"; std::string message = "Bad Request";
json_result.values["status_message"] = message; json_result.values["status_message"] = message;
JSON::render(reply.content, json_result); JSON::render(current_reply.content, json_result);
return; return;
} }
// set headers // set headers
reply.headers.emplace_back("Content-Length", current_reply.headers.emplace_back("Content-Length",
cast::integral_to_string(reply.content.size())); cast::integral_to_string(current_reply.content.size()));
if ("gpx" == route_parameters.output_format) if ("gpx" == route_parameters.output_format)
{ // gpx file { // gpx file
JSON::gpx_render(reply.content, json_result.values["route"]); JSON::gpx_render(current_reply.content, json_result.values["route"]);
reply.headers.emplace_back("Content-Type", "application/gpx+xml; charset=UTF-8"); current_reply.headers.emplace_back("Content-Type",
reply.headers.emplace_back("Content-Disposition", "attachment; filename=\"route.gpx\""); "application/gpx+xml; charset=UTF-8");
current_reply.headers.emplace_back("Content-Disposition",
"attachment; filename=\"route.gpx\"");
} }
else if (route_parameters.jsonp_parameter.empty()) else if (route_parameters.jsonp_parameter.empty())
{ // json file { // json file
JSON::render(reply.content, json_result); JSON::render(current_reply.content, json_result);
reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8"); current_reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8");
reply.headers.emplace_back("Content-Disposition", "inline; filename=\"response.json\""); current_reply.headers.emplace_back("Content-Disposition",
"inline; filename=\"response.json\"");
} }
else else
{ // jsonp { // jsonp
JSON::render(reply.content, json_result); JSON::render(current_reply.content, json_result);
reply.headers.emplace_back("Content-Type", "text/javascript; charset=UTF-8"); current_reply.headers.emplace_back("Content-Type", "text/javascript; charset=UTF-8");
reply.headers.emplace_back("Content-Disposition", "inline; filename=\"response.js\""); current_reply.headers.emplace_back("Content-Disposition",
"inline; filename=\"response.js\"");
} }
if (!route_parameters.jsonp_parameter.empty()) if (!route_parameters.jsonp_parameter.empty())
{ // append brace to jsonp response { // append brace to jsonp response
reply.content.push_back(')'); current_reply.content.push_back(')');
} }
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {
reply = http::Reply::StockReply(http::Reply::internalServerError); current_reply = http::reply::stock_reply(http::reply::internal_server_error);
SimpleLogger().Write(logWARNING) << "[server error] code: " << e.what() SimpleLogger().Write(logWARNING) << "[server error] code: " << e.what()
<< ", uri: " << req.uri; << ", uri: " << current_request.uri;
return; return;
} }
} }

View File

@ -36,8 +36,8 @@ class OSRM;
namespace http namespace http
{ {
class Reply; class reply;
struct Request; struct request;
} }
class RequestHandler class RequestHandler
@ -49,7 +49,7 @@ class RequestHandler
RequestHandler(); RequestHandler();
RequestHandler(const RequestHandler &) = delete; RequestHandler(const RequestHandler &) = delete;
void handle_request(const http::Request &req, http::Reply &rep); void handle_request(const http::request &current_request, http::reply &current_reply);
void RegisterRoutingMachine(OSRM *osrm); void RegisterRoutingMachine(OSRM *osrm);
private: private:

View File

@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "RequestParser.h" #include "RequestParser.h"
#include "Http/Request.h" #include "http/request.hpp"
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
@ -35,16 +35,16 @@ namespace http
{ {
RequestParser::RequestParser() RequestParser::RequestParser()
: state(internal_state::method_start), header({"", ""}), compression_type(noCompression) : state(internal_state::method_start), header({"", ""}), compression_type(no_compression)
{ {
} }
std::tuple<osrm::tribool, CompressionType> std::tuple<osrm::tribool, compression_type>
RequestParser::parse(Request &request, char *begin, char *end) RequestParser::parse(request &current_request, char *begin, char *end)
{ {
while (begin != end) while (begin != end)
{ {
osrm::tribool result = consume(request, *begin++); osrm::tribool result = consume(current_request, *begin++);
if (result != osrm::tribool::indeterminate) if (result != osrm::tribool::indeterminate)
{ {
return std::make_tuple(result, compression_type); return std::make_tuple(result, compression_type);
@ -54,7 +54,7 @@ RequestParser::parse(Request &request, char *begin, char *end)
return std::make_tuple(result, compression_type); return std::make_tuple(result, compression_type);
} }
osrm::tribool RequestParser::consume(Request &request, const char input) osrm::tribool RequestParser::consume(request &current_request, const char input)
{ {
switch (state) switch (state)
{ {
@ -82,7 +82,7 @@ osrm::tribool RequestParser::consume(Request &request, const char input)
return osrm::tribool::no; return osrm::tribool::no;
} }
state = internal_state::uri; state = internal_state::uri;
request.uri.push_back(input); current_request.uri.push_back(input);
return osrm::tribool::indeterminate; return osrm::tribool::indeterminate;
case internal_state::uri: case internal_state::uri:
if (input == ' ') if (input == ' ')
@ -94,7 +94,7 @@ osrm::tribool RequestParser::consume(Request &request, const char input)
{ {
return osrm::tribool::no; return osrm::tribool::no;
} }
request.uri.push_back(input); current_request.uri.push_back(input);
return osrm::tribool::indeterminate; return osrm::tribool::indeterminate;
case internal_state::http_version_h: case internal_state::http_version_h:
if (input == 'H') if (input == 'H')
@ -180,22 +180,22 @@ osrm::tribool RequestParser::consume(Request &request, const char input)
/* giving gzip precedence over deflate */ /* giving gzip precedence over deflate */
if (boost::icontains(header.value, "deflate")) if (boost::icontains(header.value, "deflate"))
{ {
compression_type = deflateRFC1951; compression_type = deflate_rfc1951;
} }
if (boost::icontains(header.value, "gzip")) if (boost::icontains(header.value, "gzip"))
{ {
compression_type = gzipRFC1952; compression_type = gzip_rfc1952;
} }
} }
if (boost::iequals(header.name, "Referer")) if (boost::iequals(header.name, "Referer"))
{ {
request.referrer = header.value; current_request.referrer = header.value;
} }
if (boost::iequals(header.name, "User-Agent")) if (boost::iequals(header.name, "User-Agent"))
{ {
request.agent = header.value; current_request.agent = header.value;
} }
if (input == '\r') if (input == '\r')

View File

@ -28,8 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef REQUEST_PARSER_H #ifndef REQUEST_PARSER_H
#define REQUEST_PARSER_H #define REQUEST_PARSER_H
#include "Http/CompressionType.h" #include "http/compression_type.hpp"
#include "Http/Header.h" #include "http/header.hpp"
#include "../data_structures/tribool.hpp" #include "../data_structures/tribool.hpp"
#include <tuple> #include <tuple>
@ -37,17 +37,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace http namespace http
{ {
struct Request; struct request;
class RequestParser class RequestParser
{ {
public: public:
RequestParser(); RequestParser();
std::tuple<osrm::tribool, CompressionType> parse(Request &request, char *begin, char *end); std::tuple<osrm::tribool, compression_type>
parse(request &current_request, char *begin, char *end);
private: private:
osrm::tribool consume(Request &req, const char input); osrm::tribool consume(request &current_request, const char input);
bool is_char(const int character) const; bool is_char(const int character) const;
@ -82,8 +83,8 @@ class RequestParser
expecting_newline_3 expecting_newline_3
} state; } state;
Header header; header header;
CompressionType compression_type; compression_type compression_type;
}; };
} // namespace http } // namespace http

View File

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,

View File

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
@ -25,17 +25,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef COMPRESSION_TYPE_H #ifndef COMPRESSION_TYPE_HPP
#define COMPRESSION_TYPE_H #define COMPRESSION_TYPE_HPP
namespace http namespace http
{ {
enum CompressionType enum compression_type
{ noCompression, {
gzipRFC1952, no_compression,
deflateRFC1951 }; gzip_rfc1952,
deflate_rfc1951
};
} }
#endif // COMPRESSION_TYPE_H #endif // COMPRESSION_TYPE_HPP

View File

@ -25,19 +25,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef HTTP_HEADER_H #ifndef HEADER_HPP
#define HTTP_HEADER_H #define HEADER_HPP
#include <string> #include <string>
#include <algorithm> #include <algorithm>
namespace http namespace http
{ {
struct Header struct header
{ {
Header &operator=(const Header &other) = default; header &operator=(const header &other) = default;
Header(const std::string &name, const std::string &value) : name(name), value(value) {} header(const std::string &name, const std::string &value) : name(name), value(value) {}
Header(Header &&other) : name(std::move(other.name)), value(std::move(other.value)) {} header(header &&other) : name(std::move(other.name)), value(std::move(other.value)) {}
void clear() void clear()
{ {
@ -50,4 +50,4 @@ struct Header
}; };
} }
#endif // HTTP_HEADER_H #endif // HEADER_HPP

130
Server/http/reply.cpp Normal file
View File

@ -0,0 +1,130 @@
/*
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "reply.hpp"
#include "../../Util/cast.hpp"
namespace http
{
const char okHTML[] = "";
const char badRequestHTML[] = "{\"status\": 400,\"status_message\":\"Bad Request\"}";
const char internalServerErrorHTML[] =
"{\"status\": 500,\"status_message\":\"Internal Server Error\"}";
const char seperators[] = {':', ' '};
const char crlf[] = {'\r', '\n'};
const std::string okString = "HTTP/1.0 200 OK\r\n";
const std::string badRequestString = "HTTP/1.0 400 Bad Request\r\n";
const std::string internalServerErrorString = "HTTP/1.0 500 Internal Server Error\r\n";
void reply::set_size(const std::size_t size)
{
for (header &h : headers)
{
if ("Content-Length" == h.name)
{
h.value = cast::integral_to_string(size);
}
}
}
void reply::set_uncompressed_size() { set_size(content.size()); }
std::vector<boost::asio::const_buffer> reply::to_buffers()
{
std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(status_to_buffer(status));
for (const header &h : headers)
{
buffers.push_back(boost::asio::buffer(h.name));
buffers.push_back(boost::asio::buffer(seperators));
buffers.push_back(boost::asio::buffer(h.value));
buffers.push_back(boost::asio::buffer(crlf));
}
buffers.push_back(boost::asio::buffer(crlf));
buffers.push_back(boost::asio::buffer(content));
return buffers;
}
std::vector<boost::asio::const_buffer> reply::headers_to_buffers()
{
std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(status_to_buffer(status));
for (const header &current_header : headers)
{
buffers.push_back(boost::asio::buffer(current_header.name));
buffers.push_back(boost::asio::buffer(seperators));
buffers.push_back(boost::asio::buffer(current_header.value));
buffers.push_back(boost::asio::buffer(crlf));
}
buffers.push_back(boost::asio::buffer(crlf));
return buffers;
}
reply reply::stock_reply(const reply::status_type status)
{
reply reply;
reply.status = status;
reply.content.clear();
const std::string status_string = reply.status_to_string(status);
reply.content.insert(reply.content.end(), status_string.begin(), status_string.end());
reply.headers.emplace_back("Access-Control-Allow-Origin", "*");
reply.headers.emplace_back("Content-Length", cast::integral_to_string(reply.content.size()));
reply.headers.emplace_back("Content-Type", "text/html");
return reply;
}
std::string reply::status_to_string(const reply::status_type status)
{
if (reply::ok == status)
{
return okHTML;
}
if (reply::bad_request == status)
{
return badRequestHTML;
}
return internalServerErrorHTML;
}
boost::asio::const_buffer reply::status_to_buffer(const reply::status_type status)
{
if (reply::ok == status)
{
return boost::asio::buffer(okString);
}
if (reply::internal_server_error == status)
{
return boost::asio::buffer(internalServerErrorString);
}
return boost::asio::buffer(badRequestString);
}
reply::reply() : status(ok) {}
}

View File

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
@ -25,10 +25,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef REPLY_H #ifndef REPLY_HPP
#define REPLY_H #define REPLY_HPP
#include "Header.h" #include "header.hpp"
#include <boost/asio.hpp> #include <boost/asio.hpp>
@ -36,39 +36,30 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace http namespace http
{ {
class reply
const char okHTML[] = "";
const char badRequestHTML[] = "{\"status\": 400,\"status_message\":\"Bad Request\"}";
const char internalServerErrorHTML[] =
"{\"status\": 500,\"status_message\":\"Internal Server Error\"}";
const char seperators[] = {':', ' '};
const char crlf[] = {'\r', '\n'};
const std::string okString = "HTTP/1.0 200 OK\r\n";
const std::string badRequestString = "HTTP/1.0 400 Bad Request\r\n";
const std::string internalServerErrorString = "HTTP/1.0 500 Internal Server Error\r\n";
class Reply
{ {
public: public:
enum status_type enum status_type
{ ok = 200, {
badRequest = 400, ok = 200,
internalServerError = 500 } status; bad_request = 400,
internal_server_error = 500
} status;
std::vector<Header> headers; std::vector<header> headers;
std::vector<boost::asio::const_buffer> ToBuffers(); std::vector<boost::asio::const_buffer> to_buffers();
std::vector<boost::asio::const_buffer> HeaderstoBuffers(); std::vector<boost::asio::const_buffer> headers_to_buffers();
std::vector<char> content; std::vector<char> content;
static Reply StockReply(status_type status); static reply stock_reply(const status_type status);
void SetSize(const unsigned size); void set_size(const std::size_t size);
void SetUncompressedSize(); void set_uncompressed_size();
Reply(); reply();
private: private:
std::string ToString(Reply::status_type status); std::string status_to_string(reply::status_type status);
boost::asio::const_buffer ToBuffer(Reply::status_type status); boost::asio::const_buffer status_to_buffer(reply::status_type status);
}; };
} }
#endif // REPLY_H #endif // REPLY_HPP

View File

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef REQUEST_H #ifndef REQUEST_HPP
#define REQUEST_H #define REQUEST_HPP
#include <boost/asio.hpp> #include <boost/asio.hpp>
@ -35,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace http namespace http
{ {
struct Request struct request
{ {
std::string uri; std::string uri;
std::string referrer; std::string referrer;
@ -45,4 +45,4 @@ struct Request
} // namespace http } // namespace http
#endif // REQUEST_H #endif // REQUEST_HPP