renamed: Server/*/*.h -> server/*/*.hpp

This commit is contained in:
Dennis Luxen
2015-01-27 12:35:29 +01:00
parent 0c1101739d
commit 9672f00ec3
28 changed files with 2061 additions and 132 deletions
-74
View File
@@ -1,74 +0,0 @@
/*
Copyright (c) 2013, 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.
*/
#ifndef APIGRAMMAR_H_
#define APIGRAMMAR_H_
#include <boost/bind.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.hpp>
namespace qi = boost::spirit::qi;
template <typename Iterator, class HandlerT>
struct APIGrammar : qi::grammar<Iterator>
{
explicit APIGrammar(HandlerT * h) : APIGrammar::base_type(api_call), handler(h)
{
api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> *(query) >> -(uturns);
query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | u | cmp | language | instruction | geometry | alt_route | old_API | num_results) ) ;
zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >> qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)];
output = (-qi::lit('&')) >> qi::lit("output") >> '=' >> string[boost::bind(&HandlerT::setOutputFormat, handler, ::_1)];
jsonp = (-qi::lit('&')) >> qi::lit("jsonp") >> '=' >> stringwithPercent[boost::bind(&HandlerT::setJSONpParameter, handler, ::_1)];
checksum = (-qi::lit('&')) >> qi::lit("checksum") >> '=' >> qi::uint_[boost::bind(&HandlerT::setChecksum, handler, ::_1)];
instruction = (-qi::lit('&')) >> qi::lit("instructions") >> '=' >> qi::bool_[boost::bind(&HandlerT::setInstructionFlag, handler, ::_1)];
geometry = (-qi::lit('&')) >> qi::lit("geometry") >> '=' >> qi::bool_[boost::bind(&HandlerT::setGeometryFlag, handler, ::_1)];
cmp = (-qi::lit('&')) >> qi::lit("compression") >> '=' >> qi::bool_[boost::bind(&HandlerT::setCompressionFlag, handler, ::_1)];
location = (-qi::lit('&')) >> qi::lit("loc") >> '=' >> (qi::double_ >> qi::lit(',') >> qi::double_)[boost::bind(&HandlerT::addCoordinate, handler, ::_1)];
hint = (-qi::lit('&')) >> qi::lit("hint") >> '=' >> stringwithDot[boost::bind(&HandlerT::addHint, handler, ::_1)];
u = (-qi::lit('&')) >> qi::lit("u") >> '=' >> qi::bool_[boost::bind(&HandlerT::setUTurn, handler, ::_1)];
uturns = (-qi::lit('&')) >> qi::lit("uturns") >> '=' >> qi::bool_[boost::bind(&HandlerT::setAllUTurns, handler, ::_1)];
language = (-qi::lit('&')) >> qi::lit("hl") >> '=' >> string[boost::bind(&HandlerT::setLanguage, handler, ::_1)];
alt_route = (-qi::lit('&')) >> qi::lit("alt") >> '=' >> qi::bool_[boost::bind(&HandlerT::setAlternateRouteFlag, handler, ::_1)];
old_API = (-qi::lit('&')) >> qi::lit("geomformat") >> '=' >> string[boost::bind(&HandlerT::setDeprecatedAPIFlag, handler, ::_1)];
num_results = (-qi::lit('&')) >> qi::lit("num_results") >> '=' >> qi::short_[boost::bind(&HandlerT::setNumberOfResults, handler, ::_1)];
string = +(qi::char_("a-zA-Z"));
stringwithDot = +(qi::char_("a-zA-Z0-9_.-"));
stringwithPercent = +(qi::char_("a-zA-Z0-9_.-") | qi::char_('[') | qi::char_(']') | (qi::char_('%') >> qi::char_("0-9A-Z") >> qi::char_("0-9A-Z") ));
}
qi::rule<Iterator> api_call, query;
qi::rule<Iterator, std::string()> service, zoom, output, string, jsonp, checksum, location, hint,
stringwithDot, stringwithPercent, language, instruction, geometry,
cmp, alt_route, u, uturns, old_API, num_results;
HandlerT * handler;
};
#endif /* APIGRAMMAR_H_ */
+3 -3
View File
@@ -25,9 +25,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Connection.h"
#include "RequestHandler.h"
#include "RequestParser.h"
#include "connection.hpp"
#include "request_handler.hpp"
#include "request_parser.hpp"
#include <boost/assert.hpp>
#include <boost/bind.hpp>
-92
View File
@@ -1,92 +0,0 @@
/*
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.
*/
#ifndef CONNECTION_H
#define CONNECTION_H
#include "http/compression_type.hpp"
#include "http/reply.hpp"
#include "http/request.hpp"
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/config.hpp>
#include <boost/version.hpp>
#include <memory>
#include <vector>
// workaround for incomplete std::shared_ptr compatibility in old boost versions
#if BOOST_VERSION < 105300 || defined BOOST_NO_CXX11_SMART_PTR
namespace boost
{
template <class T> const T *get_pointer(std::shared_ptr<T> const &p) { return p.get(); }
template <class T> T *get_pointer(std::shared_ptr<T> &p) { return p.get(); }
} // namespace boost
#endif
class RequestHandler;
namespace http
{
/// Represents a single connection from a client.
class Connection : public std::enable_shared_from_this<Connection>
{
public:
explicit Connection(boost::asio::io_service &io_service, RequestHandler &handler);
Connection(const Connection &) = delete;
Connection() = delete;
boost::asio::ip::tcp::socket &socket();
/// Start the first asynchronous operation for the connection.
void start();
private:
void handle_read(const boost::system::error_code &e, std::size_t bytes_transferred);
/// Handle completion of a write operation.
void handle_write(const boost::system::error_code &e);
std::vector<char> compress_buffers(const std::vector<char> &uncompressed_data,
const compression_type compression_type);
boost::asio::io_service::strand strand;
boost::asio::ip::tcp::socket TCP_socket;
RequestHandler &request_handler;
boost::array<char, 8192> incoming_data_buffer;
request request;
reply reply;
};
} // namespace http
#endif // CONNECTION_H
-169
View File
@@ -1,169 +0,0 @@
/*
Copyright (c) 2013, 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 "RequestHandler.h"
#include "APIGrammar.h"
#include "http/reply.hpp"
#include "http/request.hpp"
#include "../Library/OSRM.h"
#include "../Util/json_renderer.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/string_util.hpp"
#include "../Util/xml_renderer.hpp"
#include "../typedefs.h"
#include <osrm/route_parameters.hpp>
#include <osrm/json_container.hpp>
#include <ctime>
#include <algorithm>
#include <iostream>
RequestHandler::RequestHandler() : routing_machine(nullptr) {}
void RequestHandler::handle_request(const http::request &current_request,
http::reply &current_reply)
{
// parse command
try
{
std::string request_string;
URIDecode(current_request.uri, request_string);
// deactivated as GCC apparently does not implement that, not even in 4.9
// std::time_t t = std::time(nullptr);
// SimpleLogger().Write() << std::put_time(std::localtime(&t), "%m-%d-%Y %H:%M:%S") <<
// " " << current_request.endpoint.to_string() << " " <<
// current_request.referrer << ( 0 == current_request.referrer.length() ? "- " :" ") <<
// current_request.agent << ( 0 == current_request.agent.length() ? "- " :" ") <<
// request;
time_t ltime;
struct tm *time_stamp;
ltime = time(nullptr);
time_stamp = localtime(&ltime);
// log timestamp
SimpleLogger().Write() << (time_stamp->tm_mday < 10 ? "0" : "") << time_stamp->tm_mday
<< "-" << (time_stamp->tm_mon + 1 < 10 ? "0" : "")
<< (time_stamp->tm_mon + 1) << "-" << 1900 + time_stamp->tm_year
<< " " << (time_stamp->tm_hour < 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_sec << " " << current_request.endpoint.to_string()
<< " " << current_request.referrer
<< (0 == current_request.referrer.length() ? "- " : " ")
<< current_request.agent
<< (0 == current_request.agent.length() ? "- " : " ")
<< request_string;
RouteParameters route_parameters;
APIGrammarParser api_parser(&route_parameters);
auto api_iterator = request_string.begin();
const bool result =
boost::spirit::qi::parse(api_iterator, request_string.end(), api_parser);
JSON::Object json_result;
// check if the was an error with the request
if (!result || (api_iterator != request_string.end()))
{
current_reply = http::reply::stock_reply(http::reply::bad_request);
current_reply.content.clear();
const auto position = std::distance(request_string.begin(), api_iterator);
json_result.values["status"] = 400;
std::string message = "Query string malformed close to position ";
message += cast::integral_to_string(position);
json_result.values["status_message"] = message;
JSON::render(current_reply.content, json_result);
return;
}
// parsing done, lets call the right plugin to handle the request
BOOST_ASSERT_MSG(routing_machine != nullptr, "pointer not init'ed");
if (!route_parameters.jsonp_parameter.empty())
{ // prepend response with jsonp parameter
const std::string json_p = (route_parameters.jsonp_parameter + "(");
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);
if (200 != return_code)
{
current_reply = http::reply::stock_reply(http::reply::bad_request);
current_reply.content.clear();
json_result.values["status"] = 400;
std::string message = "Bad Request";
json_result.values["status_message"] = message;
JSON::render(current_reply.content, json_result);
return;
}
// set headers
current_reply.headers.emplace_back("Content-Length",
cast::integral_to_string(current_reply.content.size()));
if ("gpx" == route_parameters.output_format)
{ // gpx file
JSON::gpx_render(current_reply.content, json_result.values["route"]);
current_reply.headers.emplace_back("Content-Type",
"application/gpx+xml; charset=UTF-8");
current_reply.headers.emplace_back("Content-Disposition",
"attachment; filename=\"route.gpx\"");
}
else if (route_parameters.jsonp_parameter.empty())
{ // json file
JSON::render(current_reply.content, json_result);
current_reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8");
current_reply.headers.emplace_back("Content-Disposition",
"inline; filename=\"response.json\"");
}
else
{ // jsonp
JSON::render(current_reply.content, json_result);
current_reply.headers.emplace_back("Content-Type", "text/javascript; charset=UTF-8");
current_reply.headers.emplace_back("Content-Disposition",
"inline; filename=\"response.js\"");
}
if (!route_parameters.jsonp_parameter.empty())
{ // append brace to jsonp response
current_reply.content.push_back(')');
}
}
catch (const std::exception &e)
{
current_reply = http::reply::stock_reply(http::reply::internal_server_error);
SimpleLogger().Write(logWARNING) << "[server error] code: " << e.what()
<< ", uri: " << current_request.uri;
return;
}
}
void RequestHandler::RegisterRoutingMachine(OSRM *osrm) { routing_machine = osrm; }
-59
View File
@@ -1,59 +0,0 @@
/*
Copyright (c) 2013, 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.
*/
#ifndef REQUEST_HANDLER_H
#define REQUEST_HANDLER_H
#include <string>
template <typename Iterator, class HandlerT> struct APIGrammar;
struct RouteParameters;
class OSRM;
namespace http
{
class reply;
struct request;
}
class RequestHandler
{
public:
using APIGrammarParser = APIGrammar<std::string::iterator, RouteParameters>;
RequestHandler();
RequestHandler(const RequestHandler &) = delete;
void handle_request(const http::request &current_request, http::reply &current_reply);
void RegisterRoutingMachine(OSRM *osrm);
private:
OSRM *routing_machine;
};
#endif // REQUEST_HANDLER_H
-316
View File
@@ -1,316 +0,0 @@
/*
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 "RequestParser.h"
#include "http/request.hpp"
#include <boost/algorithm/string/predicate.hpp>
namespace http
{
RequestParser::RequestParser()
: state(internal_state::method_start), header({"", ""}), compression_type(no_compression)
{
}
std::tuple<osrm::tribool, compression_type>
RequestParser::parse(request &current_request, char *begin, char *end)
{
while (begin != end)
{
osrm::tribool result = consume(current_request, *begin++);
if (result != osrm::tribool::indeterminate)
{
return std::make_tuple(result, compression_type);
}
}
osrm::tribool result = osrm::tribool::indeterminate;
return std::make_tuple(result, compression_type);
}
osrm::tribool RequestParser::consume(request &current_request, const char input)
{
switch (state)
{
case internal_state::method_start:
if (!is_char(input) || is_CTL(input) || is_special(input))
{
return osrm::tribool::no;
}
state = internal_state::method;
return osrm::tribool::indeterminate;
case internal_state::method:
if (input == ' ')
{
state = internal_state::uri;
return osrm::tribool::indeterminate;
}
if (!is_char(input) || is_CTL(input) || is_special(input))
{
return osrm::tribool::no;
}
return osrm::tribool::indeterminate;
case internal_state::uri_start:
if (is_CTL(input))
{
return osrm::tribool::no;
}
state = internal_state::uri;
current_request.uri.push_back(input);
return osrm::tribool::indeterminate;
case internal_state::uri:
if (input == ' ')
{
state = internal_state::http_version_h;
return osrm::tribool::indeterminate;
}
if (is_CTL(input))
{
return osrm::tribool::no;
}
current_request.uri.push_back(input);
return osrm::tribool::indeterminate;
case internal_state::http_version_h:
if (input == 'H')
{
state = internal_state::http_version_t_1;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::http_version_t_1:
if (input == 'T')
{
state = internal_state::http_version_t_2;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::http_version_t_2:
if (input == 'T')
{
state = internal_state::http_version_p;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::http_version_p:
if (input == 'P')
{
state = internal_state::http_version_slash;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::http_version_slash:
if (input == '/')
{
state = internal_state::http_version_major_start;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::http_version_major_start:
if (is_digit(input))
{
state = internal_state::http_version_major;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::http_version_major:
if (input == '.')
{
state = internal_state::http_version_minor_start;
return osrm::tribool::indeterminate;
}
if (is_digit(input))
{
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::http_version_minor_start:
if (is_digit(input))
{
state = internal_state::http_version_minor;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::http_version_minor:
if (input == '\r')
{
state = internal_state::expecting_newline_1;
return osrm::tribool::indeterminate;
}
if (is_digit(input))
{
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::expecting_newline_1:
if (input == '\n')
{
state = internal_state::header_line_start;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::header_line_start:
if (boost::iequals(header.name, "Accept-Encoding"))
{
/* giving gzip precedence over deflate */
if (boost::icontains(header.value, "deflate"))
{
compression_type = deflate_rfc1951;
}
if (boost::icontains(header.value, "gzip"))
{
compression_type = gzip_rfc1952;
}
}
if (boost::iequals(header.name, "Referer"))
{
current_request.referrer = header.value;
}
if (boost::iequals(header.name, "User-Agent"))
{
current_request.agent = header.value;
}
if (input == '\r')
{
state = internal_state::expecting_newline_3;
return osrm::tribool::indeterminate;
}
if (!is_char(input) || is_CTL(input) || is_special(input))
{
return osrm::tribool::no;
}
state = internal_state::header_name;
header.clear();
header.name.push_back(input);
return osrm::tribool::indeterminate;
case internal_state::header_lws:
if (input == '\r')
{
state = internal_state::expecting_newline_2;
return osrm::tribool::indeterminate;
}
if (input == ' ' || input == '\t')
{
return osrm::tribool::indeterminate;
}
if (is_CTL(input))
{
return osrm::tribool::no;
}
state = internal_state::header_value;
return osrm::tribool::indeterminate;
case internal_state::header_name:
if (input == ':')
{
state = internal_state::space_before_header_value;
return osrm::tribool::indeterminate;
}
if (!is_char(input) || is_CTL(input) || is_special(input))
{
return osrm::tribool::no;
}
header.name.push_back(input);
return osrm::tribool::indeterminate;
case internal_state::space_before_header_value:
if (input == ' ')
{
state = internal_state::header_value;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::header_value:
if (input == '\r')
{
state = internal_state::expecting_newline_2;
return osrm::tribool::indeterminate;
}
if (is_CTL(input))
{
return osrm::tribool::no;
}
header.value.push_back(input);
return osrm::tribool::indeterminate;
case internal_state::expecting_newline_2:
if (input == '\n')
{
state = internal_state::header_line_start;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
default: // expecting_newline_3
return (input == '\n' ? osrm::tribool::yes : osrm::tribool::no);
}
}
bool RequestParser::is_char(const int character) const
{
return character >= 0 && character <= 127;
}
bool RequestParser::is_CTL(const int character) const
{
return (character >= 0 && character <= 31) || (character == 127);
}
bool RequestParser::is_special(const int character) const
{
switch (character)
{
case '(':
case ')':
case '<':
case '>':
case '@':
case ',':
case ';':
case ':':
case '\\':
case '"':
case '/':
case '[':
case ']':
case '?':
case '=':
case '{':
case '}':
case ' ':
case '\t':
return true;
default:
return false;
}
}
bool RequestParser::is_digit(const int character) const
{
return character >= '0' && character <= '9';
}
}
-92
View File
@@ -1,92 +0,0 @@
/*
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.
*/
#ifndef REQUEST_PARSER_H
#define REQUEST_PARSER_H
#include "http/compression_type.hpp"
#include "http/header.hpp"
#include "../data_structures/tribool.hpp"
#include <tuple>
namespace http
{
struct request;
class RequestParser
{
public:
RequestParser();
std::tuple<osrm::tribool, compression_type>
parse(request &current_request, char *begin, char *end);
private:
osrm::tribool consume(request &current_request, const char input);
bool is_char(const int character) const;
bool is_CTL(const int character) const;
bool is_special(const int character) const;
bool is_digit(const int character) const;
enum class internal_state : unsigned char
{
method_start,
method,
uri_start,
uri,
http_version_h,
http_version_t_1,
http_version_t_2,
http_version_p,
http_version_slash,
http_version_major_start,
http_version_major,
http_version_minor_start,
http_version_minor,
expecting_newline_1,
header_line_start,
header_lws,
header_name,
space_before_header_value,
header_value,
expecting_newline_2,
expecting_newline_3
} state;
header header;
compression_type compression_type;
};
} // namespace http
#endif // REQUEST_PARSER_H
-119
View File
@@ -1,119 +0,0 @@
/*
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.
*/
#ifndef SERVER_H
#define SERVER_H
#include "Connection.h"
#include "RequestHandler.h"
#include "../Util/cast.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/simple_logger.hpp"
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <zlib.h>
#include <functional>
#include <memory>
#include <thread>
#include <vector>
class Server
{
public:
// Note: returns a shared instead of a unique ptr as it is captured in a lambda somewhere else
static std::shared_ptr<Server>
CreateServer(std::string &ip_address, int ip_port, unsigned requested_num_threads)
{
SimpleLogger().Write() << "http 1.1 compression handled by zlib version " << zlibVersion();
const unsigned hardware_threads = std::max(1u, std::thread::hardware_concurrency());
const unsigned real_num_threads = std::min(hardware_threads, requested_num_threads);
return std::make_shared<Server>(ip_address, ip_port, real_num_threads);
}
explicit Server(const std::string &address, const int port, const unsigned thread_pool_size)
: thread_pool_size(thread_pool_size), acceptor(io_service),
new_connection(std::make_shared<http::Connection>(io_service, request_handler))
{
const std::string port_string = cast::integral_to_string(port);
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(address, port_string);
boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
acceptor.open(endpoint.protocol());
acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
acceptor.bind(endpoint);
acceptor.listen();
acceptor.async_accept(
new_connection->socket(),
boost::bind(&Server::HandleAccept, this, boost::asio::placeholders::error));
}
void Run()
{
std::vector<std::shared_ptr<std::thread>> threads;
for (unsigned i = 0; i < thread_pool_size; ++i)
{
std::shared_ptr<std::thread> thread = std::make_shared<std::thread>(
boost::bind(&boost::asio::io_service::run, &io_service));
threads.push_back(thread);
}
for (auto thread : threads)
{
thread->join();
}
}
void Stop() { io_service.stop(); }
RequestHandler &GetRequestHandlerPtr() { return request_handler; }
private:
void HandleAccept(const boost::system::error_code &e)
{
if (!e)
{
new_connection->start();
new_connection = std::make_shared<http::Connection>(io_service, request_handler);
acceptor.async_accept(
new_connection->socket(),
boost::bind(&Server::HandleAccept, this, boost::asio::placeholders::error));
}
}
unsigned thread_pool_size;
boost::asio::io_service io_service;
boost::asio::ip::tcp::acceptor acceptor;
std::shared_ptr<http::Connection> new_connection;
RequestHandler request_handler;
};
#endif // SERVER_H