implements output generation through a dedicated JSON container:

- JSON syntax is not scattered over several files, but one place
- Reduces code duplication
- breaking changes:
  - new property in json(p) formatted response: "found_alternative": True/False
  - returned filenames now response.js(on) or route.gpx
  - /hello plugin returns JSON now
This commit is contained in:
Dennis Luxen
2014-05-16 16:09:40 +02:00
parent acab77f4f8
commit a80815d57a
28 changed files with 1092 additions and 675 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ struct APIGrammar : qi::grammar<Iterator>
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::int_[boost::bind(&HandlerT::setChecksum, 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)];
+7 -12
View File
@@ -81,6 +81,7 @@ void Connection::handle_read(const boost::system::error_code &e, std::size_t byt
Header compression_header;
std::vector<char> compressed_output;
std::vector<boost::asio::const_buffer> output_buffer;
switch (compression_type)
{
case deflateRFC1951:
@@ -158,7 +159,7 @@ void Connection::handle_write(const boost::system::error_code &e)
}
}
void Connection::compressBufferCollection(std::vector<std::string> uncompressed_data,
void Connection::compressBufferCollection(std::vector<char> uncompressed_data,
CompressionType compression_type,
std::vector<char> &compressed_data)
{
@@ -171,16 +172,10 @@ void Connection::compressBufferCollection(std::vector<std::string> uncompressed_
}
BOOST_ASSERT(compressed_data.empty());
boost::iostreams::filtering_ostream compressing_stream;
compressing_stream.push(boost::iostreams::gzip_compressor(compression_parameters));
compressing_stream.push(boost::iostreams::back_inserter(compressed_data));
for (const std::string &line : uncompressed_data)
{
compressing_stream << line;
}
compressing_stream.reset();
boost::iostreams::filtering_ostream gzip_stream;
gzip_stream.push(boost::iostreams::gzip_compressor(compression_parameters));
gzip_stream.push(boost::iostreams::back_inserter(compressed_data));
gzip_stream.write(&uncompressed_data[0], uncompressed_data.size());
boost::iostreams::close(gzip_stream);
}
}
+1 -1
View File
@@ -89,7 +89,7 @@ class Connection : public std::enable_shared_from_this<Connection>
/// Handle completion of a write operation.
void handle_write(const boost::system::error_code &e);
void compressBufferCollection(std::vector<std::string> uncompressed_data,
void compressBufferCollection(std::vector<char> uncompressed_data,
CompressionType compression_type,
std::vector<char> &compressed_data);
+7 -12
View File
@@ -38,7 +38,7 @@ void Reply::setSize(const unsigned size)
{
if ("Content-Length" == h.name)
{
intToString(size, h.value);
h.value = IntToString(size);
}
}
}
@@ -47,10 +47,7 @@ void Reply::setSize(const unsigned size)
void Reply::SetUncompressedSize()
{
unsigned uncompressed_size = 0;
for (const std::string &current_line : content)
{
uncompressed_size += current_line.size();
}
uncompressed_size = content.size();
setSize(uncompressed_size);
}
@@ -66,10 +63,7 @@ std::vector<boost::asio::const_buffer> Reply::toBuffers()
buffers.push_back(boost::asio::buffer(crlf));
}
buffers.push_back(boost::asio::buffer(crlf));
for (const std::string &line : content)
{
buffers.push_back(boost::asio::buffer(line));
}
buffers.push_back(boost::asio::buffer(content));
return buffers;
}
@@ -94,14 +88,15 @@ Reply Reply::StockReply(Reply::status_type status)
Reply rep;
rep.status = status;
rep.content.clear();
rep.content.push_back(rep.ToString(status));
const std::string status_string = rep.ToString(status);
rep.content.insert(rep.content.end(), status_string.begin(), status_string.end());
rep.headers.resize(3);
rep.headers[0].name = "Access-Control-Allow-Origin";
rep.headers[0].value = "*";
rep.headers[1].name = "Content-Length";
std::string size_string;
intToString(rep.content.size(), size_string);
std::string size_string = IntToString(rep.content.size());
rep.headers[1].value = size_string;
rep.headers[2].name = "Content-Type";
+40 -6
View File
@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "RequestHandler.h"
#include "Http/Request.h"
#include "../DataStructures/JSONContainer.h"
#include "../Library/OSRM.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
@@ -85,18 +86,51 @@ void RequestHandler::handle_request(const http::Request &req, http::Reply &reply
reply = http::Reply::StockReply(http::Reply::badRequest);
reply.content.clear();
const int position = std::distance(request.begin(), it);
reply.content.push_back(
"{\"status\":400,\"status_message\":\"Query string malformed close to position ");
std::string tmp_position_string;
intToString(position, tmp_position_string);
reply.content.push_back(tmp_position_string);
reply.content.push_back("\"}");
JSON::Object json_result;
json_result.values["status"] = 400;
std::string tmp_position_string = IntToString(position);
std::string message = ("Query string malformed close to position " + IntToString(position));
json_result.values["status_message"] = message;
JSON::render(reply.content, json_result);
}
else
{
// 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())
{
const std::string json_p = (route_parameters.jsonp_parameter + "(");
reply.content.insert(reply.content.end(), json_p.begin(), json_p.end());
}
routing_machine->RunQuery(route_parameters, reply);
// set headers, still ugly and should be reworked
reply.headers.resize(3);
if ("gpx" == route_parameters.output_format)
{
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "application/gpx+xml; charset=UTF-8";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"route.gpx\"";
}
else if (!route_parameters.jsonp_parameter.empty())
{
reply.content.push_back(')');
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"response.js\"";
}
else
{
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "application/x-javascript";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"response.json\"";
}
reply.headers[0].name = "Content-Length";
reply.headers[0].value = IntToString(reply.content.size());
return;
}
}
+1 -5
View File
@@ -41,12 +41,8 @@ struct ServerFactory
ServerFactory(const ServerFactory &) = delete;
static Server *CreateServer(std::string &ip_address, int ip_port, int threads)
{
SimpleLogger().Write() << "http 1.1 compression handled by zlib version " << zlibVersion();
std::string port_stream;
intToString(ip_port, port_stream);
std::string port_stream = IntToString(ip_port);
return new Server(ip_address, port_stream, std::min(omp_get_num_procs(), threads));
}
};