First implementation of moving the algorithmic core into a library
This commit is contained in:
@@ -20,12 +20,16 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
#ifndef BASIC_DATASTRUCTURES_H
|
||||
#define BASIC_DATASTRUCTURES_H
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "../Util/StringUtil.h"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
namespace http {
|
||||
|
||||
const std::string okString = "HTTP/1.0 200 OK\r\n";
|
||||
@@ -77,7 +81,7 @@ struct Reply {
|
||||
BOOST_FOREACH ( Header& h, headers) {
|
||||
if("Content-Length" == h.name) {
|
||||
std::string sizeString;
|
||||
intToString(size,h.value );
|
||||
intToString(size,h.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,7 +143,7 @@ Reply Reply::stockReply(Reply::status_type status) {
|
||||
Reply rep;
|
||||
rep.status = status;
|
||||
rep.content = ToString(status);
|
||||
rep.headers.resize(3);
|
||||
rep.headers.resize(3);
|
||||
rep.headers[0].name = "Access-Control-Allow-Origin";
|
||||
rep.headers[0].value = "*";
|
||||
rep.headers[1].name = "Content-Length";
|
||||
|
||||
+5
-5
@@ -21,7 +21,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#ifndef CONNECTION_H
|
||||
#define CONNECTION_H
|
||||
|
||||
#include <vector>
|
||||
#include "BasicDatastructures.h"
|
||||
#include "RequestHandler.h"
|
||||
#include "RequestParser.h"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/array.hpp>
|
||||
@@ -30,11 +32,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
|
||||
#include "BasicDatastructures.h"
|
||||
#include "RequestHandler.h"
|
||||
#include "RequestParser.h"
|
||||
#include <zlib.h>
|
||||
|
||||
#include "zlib.h"
|
||||
#include <vector>
|
||||
|
||||
namespace http {
|
||||
|
||||
|
||||
+23
-40
@@ -21,35 +21,27 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#ifndef REQUEST_HANDLER_H
|
||||
#define REQUEST_HANDLER_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype> // std::tolower
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include "APIGrammar.h"
|
||||
#include "BasicDatastructures.h"
|
||||
#include "../DataStructures/HashTable.h"
|
||||
#include "../Plugins/BasePlugin.h"
|
||||
#include "../Library/OSRM.h"
|
||||
#include "../Plugins/RouteParameters.h"
|
||||
#include "../Util/StringUtil.h"
|
||||
#include "../typedefs.h"
|
||||
|
||||
namespace http {
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
class RequestHandler : private boost::noncopyable {
|
||||
public:
|
||||
explicit RequestHandler() : _pluginCount(0) { }
|
||||
typedef APIGrammar<std::string::iterator, RouteParameters> APIGrammarParser;
|
||||
explicit RequestHandler() { }
|
||||
|
||||
~RequestHandler() {
|
||||
|
||||
for(unsigned i = 0; i < _pluginVector.size(); i++) {
|
||||
BasePlugin * tempPointer = _pluginVector[i];
|
||||
delete tempPointer;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_request(const Request& req, Reply& rep){
|
||||
void handle_request(const http::Request& req, http::Reply& rep){
|
||||
//parse command
|
||||
try {
|
||||
std::string request(req.uri);
|
||||
@@ -66,10 +58,10 @@ public:
|
||||
}
|
||||
|
||||
RouteParameters routeParameters;
|
||||
APIGrammar<std::string::iterator, RouteParameters> apiParser(&routeParameters);
|
||||
APIGrammarParser apiParser(&routeParameters);
|
||||
|
||||
std::string::iterator it = request.begin();
|
||||
bool result = boost::spirit::qi::parse(it, request.end(), apiParser); // returns true if successful
|
||||
bool result = boost::spirit::qi::parse(it, request.end(), apiParser);
|
||||
if (!result || (it != request.end()) ) {
|
||||
rep = http::Reply::stockReply(http::Reply::badRequest);
|
||||
int position = std::distance(request.begin(), it);
|
||||
@@ -80,38 +72,29 @@ public:
|
||||
rep.content += request;
|
||||
rep.content += tmp_position_string;
|
||||
rep.content += "<br>";
|
||||
for(unsigned i = 0, end = std::distance(request.begin(), it); i < end; ++i)
|
||||
unsigned end = std::distance(request.begin(), it);
|
||||
for(unsigned i = 0; i < end; ++i) {
|
||||
rep.content += " ";
|
||||
}
|
||||
rep.content += "^<br></pre>";
|
||||
} else {
|
||||
//Finished parsing, lets call the right plugin to handle the request
|
||||
if(pluginMap.Holds(routeParameters.service)) {
|
||||
rep.status = Reply::ok;
|
||||
_pluginVector[pluginMap.Find(routeParameters.service)]->HandleRequest(routeParameters, rep );
|
||||
} else {
|
||||
rep = Reply::stockReply(Reply::badRequest);
|
||||
}
|
||||
//parsing done, lets call the right plugin to handle the request
|
||||
routing_machine->RunQuery(routeParameters, rep);
|
||||
return;
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
rep = Reply::stockReply(Reply::internalServerError);
|
||||
std::cerr << "[server error] code: " << e.what() << ", uri: " << req.uri << std::endl;
|
||||
rep = http::Reply::stockReply(http::Reply::internalServerError);
|
||||
WARN("[server error] code: " << e.what() << ", uri: " << req.uri);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
void RegisterPlugin(BasePlugin * plugin) {
|
||||
std::cout << "[handler] registering plugin " << plugin->GetDescriptor() << std::endl;
|
||||
pluginMap.Add(plugin->GetDescriptor(), _pluginCount);
|
||||
_pluginVector.push_back(plugin);
|
||||
++_pluginCount;
|
||||
void RegisterRoutingMachine(OSRM * osrm) {
|
||||
routing_machine = osrm;
|
||||
}
|
||||
|
||||
private:
|
||||
HashTable<std::string, unsigned> pluginMap;
|
||||
std::vector<BasePlugin *> _pluginVector;
|
||||
unsigned _pluginCount;
|
||||
OSRM * routing_machine;
|
||||
};
|
||||
} // namespace http
|
||||
|
||||
#endif // REQUEST_HANDLER_H
|
||||
|
||||
+34
-14
@@ -21,21 +21,29 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#ifndef SERVER_H
|
||||
#define SERVER_H
|
||||
|
||||
#include <vector>
|
||||
#include "Connection.h"
|
||||
#include "RequestHandler.h"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include "Connection.h"
|
||||
#include "RequestHandler.h"
|
||||
|
||||
namespace http {
|
||||
#include <vector>
|
||||
|
||||
class Server: private boost::noncopyable {
|
||||
public:
|
||||
explicit Server(const std::string& address, const std::string& port, unsigned thread_pool_size) : threadPoolSize(thread_pool_size), acceptor(ioService), newConnection(new Connection(ioService, requestHandler)), requestHandler(){
|
||||
explicit Server(
|
||||
const std::string& address,
|
||||
const std::string& port,
|
||||
unsigned thread_pool_size
|
||||
) :
|
||||
threadPoolSize(thread_pool_size),
|
||||
acceptor(ioService),
|
||||
newConnection(new http::Connection(ioService, requestHandler)),
|
||||
requestHandler()
|
||||
{
|
||||
boost::asio::ip::tcp::resolver resolver(ioService);
|
||||
boost::asio::ip::tcp::resolver::query query(address, port);
|
||||
boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
|
||||
@@ -44,7 +52,14 @@ public:
|
||||
acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
|
||||
acceptor.bind(endpoint);
|
||||
acceptor.listen();
|
||||
acceptor.async_accept(newConnection->socket(), boost::bind(&Server::handleAccept, this, boost::asio::placeholders::error));
|
||||
acceptor.async_accept(
|
||||
newConnection->socket(),
|
||||
boost::bind(
|
||||
&Server::handleAccept,
|
||||
this,
|
||||
boost::asio::placeholders::error
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void Run() {
|
||||
@@ -66,23 +81,28 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
typedef boost::shared_ptr<Connection > ConnectionPtr;
|
||||
|
||||
void handleAccept(const boost::system::error_code& e) {
|
||||
if (!e) {
|
||||
newConnection->start();
|
||||
newConnection.reset(new Connection(ioService, requestHandler));
|
||||
acceptor.async_accept(newConnection->socket(), boost::bind(&Server::handleAccept, this, boost::asio::placeholders::error));
|
||||
newConnection.reset(
|
||||
new http::Connection(ioService, requestHandler)
|
||||
);
|
||||
acceptor.async_accept(
|
||||
newConnection->socket(),
|
||||
boost::bind(
|
||||
&Server::handleAccept,
|
||||
this,
|
||||
boost::asio::placeholders::error
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned threadPoolSize;
|
||||
boost::asio::io_service ioService;
|
||||
boost::asio::ip::tcp::acceptor acceptor;
|
||||
ConnectionPtr newConnection;
|
||||
boost::shared_ptr<http::Connection> newConnection;
|
||||
RequestHandler requestHandler;
|
||||
};
|
||||
|
||||
} // namespace http
|
||||
|
||||
#endif // SERVER_H
|
||||
|
||||
@@ -25,21 +25,19 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#ifndef SERVERFACTORY_H_
|
||||
#define SERVERFACTORY_H_
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#include "Server.h"
|
||||
#include "ServerConfiguration.h"
|
||||
|
||||
#include "../Util/BaseConfiguration.h"
|
||||
#include "../Util/InputFileUtil.h"
|
||||
#include "../Util/OpenMPWrapper.h"
|
||||
#include "../Util/StringUtil.h"
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
typedef http::Server Server;
|
||||
#include <zlib.h>
|
||||
|
||||
struct ServerFactory {
|
||||
static Server * CreateServer(ServerConfiguration& serverConfig) {
|
||||
static Server * CreateServer(BaseConfiguration& serverConfig) {
|
||||
|
||||
if(!testDataFile(serverConfig.GetParameter("nodesData"))) {
|
||||
ERR("nodes file not found");
|
||||
@@ -76,7 +74,7 @@ struct ServerFactory {
|
||||
}
|
||||
|
||||
static Server * CreateServer(const char * iniFile) {
|
||||
ServerConfiguration serverConfig(iniFile);
|
||||
BaseConfiguration serverConfig(iniFile);
|
||||
return CreateServer(serverConfig);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user