Fix syntax error position indicators in parameters queries

To fix #2193 prefix_length member variable has been added to ParsedURL
that is set to the length of "/service/version/profile/" prefix
when the prefix is accepted by the parser.
Also BOOST_FUSION_ADAPT_STRUCT for osrm::server::api::ParsedURL
has been moved from header to url_parser.cpp to speed up compilation
of CUs that do not use the fusion adaption.
This commit is contained in:
Michael Krasnyk
2016-04-26 21:20:24 +02:00
parent e9e935303c
commit 5186b9490d
18 changed files with 64 additions and 51 deletions
+23 -7
View File
@@ -1,15 +1,25 @@
#include "server/api/url_parser.hpp"
#include "engine/polyline_compressor.hpp"
//#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_iter_pos.hpp>
#include <string>
#include <type_traits>
BOOST_FUSION_ADAPT_STRUCT(osrm::server::api::ParsedURL,
(std::string, service)
(unsigned, version)
(std::string, profile)
(std::string, query)
)
// Keep impl. TU local
namespace
{
namespace ph = boost::phoenix;
namespace qi = boost::spirit::qi;
template <typename Iterator, typename Into> //
@@ -17,6 +27,8 @@ struct URLParser final : qi::grammar<Iterator, Into>
{
URLParser() : URLParser::base_type(start)
{
using boost::spirit::repository::qi::iter_pos;
alpha_numeral = qi::char_("a-zA-Z0-9");
polyline_chars = qi::char_("a-zA-Z0-9_.--[]{}@?|\\%~`^");
all_chars = polyline_chars | qi::char_("=,;:&().");
@@ -28,10 +40,14 @@ struct URLParser final : qi::grammar<Iterator, Into>
// Example input: /route/v1/driving/7.416351,43.731205;7.420363,43.736189
start = qi::lit('/') > service //
> qi::lit('/') > qi::lit('v') > version //
> qi::lit('/') > profile //
> qi::lit('/') > query; //
start
= qi::lit('/') > service
> qi::lit('/') > qi::lit('v') > version
> qi::lit('/') > profile
> qi::lit('/')
> qi::omit[iter_pos[ph::bind(&osrm::server::api::ParsedURL::prefix_length, qi::_val) = qi::_1 - qi::_r1]]
> query
;
BOOST_SPIRIT_DEBUG_NODES((start)(service)(version)(profile)(query))
}
@@ -61,12 +77,12 @@ boost::optional<ParsedURL> parseURL(std::string::iterator &iter, const std::stri
{
using It = std::decay<decltype(iter)>::type;
static URLParser<It, ParsedURL()> const parser;
static URLParser<It, ParsedURL(It)> const parser;
ParsedURL out;
try
{
const auto ok = boost::spirit::qi::parse(iter, end, parser, out);
const auto ok = boost::spirit::qi::parse(iter, end, parser(boost::phoenix::val(iter)), out);
if (ok && iter == end)
return boost::make_optional(out);
+2 -2
View File
@@ -40,7 +40,7 @@ std::string getWrongOptionHelp(const engine::api::MatchParameters &parameters)
}
} // anon. ns
engine::Status MatchService::RunQuery(std::string &query, ResultT &result)
engine::Status MatchService::RunQuery(std::size_t prefix_length, std::string &query, ResultT &result)
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
@@ -53,7 +53,7 @@ engine::Status MatchService::RunQuery(std::string &query, ResultT &result)
const auto position = std::distance(query.begin(), query_iterator);
json_result.values["code"] = "InvalidQuery";
json_result.values["message"] =
"Query string malformed close to position " + std::to_string(position);
"Query string malformed close to position " + std::to_string(prefix_length + position);
return engine::Status::Error;
}
+2 -2
View File
@@ -39,7 +39,7 @@ std::string getWrongOptionHelp(const engine::api::NearestParameters &parameters)
}
} // anon. ns
engine::Status NearestService::RunQuery(std::string &query, ResultT &result)
engine::Status NearestService::RunQuery(std::size_t prefix_length, std::string &query, ResultT &result)
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
@@ -52,7 +52,7 @@ engine::Status NearestService::RunQuery(std::string &query, ResultT &result)
const auto position = std::distance(query.begin(), query_iterator);
json_result.values["code"] = "InvalidQuery";
json_result.values["message"] =
"Query string malformed close to position " + std::to_string(position);
"Query string malformed close to position " + std::to_string(prefix_length + position);
return engine::Status::Error;
}
BOOST_ASSERT(parameters);
+2 -2
View File
@@ -36,7 +36,7 @@ std::string getWrongOptionHelp(const engine::api::RouteParameters &parameters)
}
} // anon. ns
engine::Status RouteService::RunQuery(std::string &query, ResultT &result)
engine::Status RouteService::RunQuery(std::size_t prefix_length, std::string &query, ResultT &result)
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
@@ -49,7 +49,7 @@ engine::Status RouteService::RunQuery(std::string &query, ResultT &result)
const auto position = std::distance(query.begin(), query_iterator);
json_result.values["code"] = "InvalidQuery";
json_result.values["message"] =
"Query string malformed close to position " + std::to_string(position);
"Query string malformed close to position " + std::to_string(prefix_length + position);
return engine::Status::Error;
}
BOOST_ASSERT(parameters);
+2 -2
View File
@@ -57,7 +57,7 @@ std::string getWrongOptionHelp(const engine::api::TableParameters &parameters)
}
} // anon. ns
engine::Status TableService::RunQuery(std::string &query, ResultT &result)
engine::Status TableService::RunQuery(std::size_t prefix_length, std::string &query, ResultT &result)
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
@@ -70,7 +70,7 @@ engine::Status TableService::RunQuery(std::string &query, ResultT &result)
const auto position = std::distance(query.begin(), query_iterator);
json_result.values["code"] = "InvalidQuery";
json_result.values["message"] =
"Query string malformed close to position " + std::to_string(position);
"Query string malformed close to position " + std::to_string(prefix_length + position);
return engine::Status::Error;
}
BOOST_ASSERT(parameters);
+2 -2
View File
@@ -15,7 +15,7 @@ namespace server
namespace service
{
engine::Status TileService::RunQuery(std::string &query, ResultT &result)
engine::Status TileService::RunQuery(std::size_t prefix_length, std::string &query, ResultT &result)
{
auto query_iterator = query.begin();
auto parameters =
@@ -27,7 +27,7 @@ engine::Status TileService::RunQuery(std::string &query, ResultT &result)
auto &json_result = result.get<util::json::Object>();
json_result.values["code"] = "InvalidQuery";
json_result.values["message"] =
"Query string malformed close to position " + std::to_string(position);
"Query string malformed close to position " + std::to_string(prefix_length + position);
return engine::Status::Error;
}
BOOST_ASSERT(parameters);
+2 -2
View File
@@ -38,7 +38,7 @@ std::string getWrongOptionHelp(const engine::api::TripParameters &parameters)
}
} // anon. ns
engine::Status TripService::RunQuery(std::string &query, ResultT &result)
engine::Status TripService::RunQuery(std::size_t prefix_length, std::string &query, ResultT &result)
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
@@ -53,7 +53,7 @@ engine::Status TripService::RunQuery(std::string &query, ResultT &result)
auto &json_result = result.get<util::json::Object>();
json_result.values["code"] = "InvalidQuery";
json_result.values["message"] =
"Query string malformed close to position " + std::to_string(position);
"Query string malformed close to position " + std::to_string(prefix_length + position);
return engine::Status::Error;
}
BOOST_ASSERT(parameters);
+1 -1
View File
@@ -48,7 +48,7 @@ engine::Status ServiceHandler::RunQuery(api::ParsedURL parsed_url,
return engine::Status::Error;
}
return service->RunQuery(parsed_url.query, result);
return service->RunQuery(parsed_url.prefix_length, parsed_url.query, result);
}
}
}