Merge pull request #2324 from oxidase/master
Fix syntax error position indicators in parameters queries
This commit is contained in:
commit
21f64c75eb
@ -55,13 +55,13 @@ Feature: Status messages
|
||||
| ? | 400 | URL string malformed close to position 1: "/?" |
|
||||
| route/v1/driving | 400 | URL string malformed close to position 17: "ing" |
|
||||
| route/v1/driving/ | 400 | URL string malformed close to position 18: "ng/" |
|
||||
| route/v1/driving/1 | 400 | Query string malformed close to position 1 |
|
||||
| route/v1/driving/1 | 400 | Query string malformed close to position 19 |
|
||||
| route/v1/driving/1,1 | 400 | Number of coordinates needs to be at least two. |
|
||||
| route/v1/driving/1,1,1 | 400 | Query string malformed close to position 3 |
|
||||
| route/v1/driving/x | 400 | Query string malformed close to position 0 |
|
||||
| route/v1/driving/x,y | 400 | Query string malformed close to position 0 |
|
||||
| route/v1/driving/1,1; | 400 | Query string malformed close to position 3 |
|
||||
| route/v1/driving/1,1;1 | 400 | Query string malformed close to position 5 |
|
||||
| route/v1/driving/1,1;1,1,1 | 400 | Query string malformed close to position 7 |
|
||||
| route/v1/driving/1,1;x | 400 | Query string malformed close to position 3 |
|
||||
| route/v1/driving/1,1;x,y | 400 | Query string malformed close to position 3 |
|
||||
| route/v1/driving/1,1,1 | 400 | Query string malformed close to position 21 |
|
||||
| route/v1/driving/x | 400 | Query string malformed close to position 18 |
|
||||
| route/v1/driving/x,y | 400 | Query string malformed close to position 18 |
|
||||
| route/v1/driving/1,1; | 400 | Query string malformed close to position 21 |
|
||||
| route/v1/driving/1,1;1 | 400 | Query string malformed close to position 23 |
|
||||
| route/v1/driving/1,1;1,1,1 | 400 | Query string malformed close to position 25 |
|
||||
| route/v1/driving/1,1;x | 400 | Query string malformed close to position 21 |
|
||||
| route/v1/driving/1,1;x,y | 400 | Query string malformed close to position 21 |
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
#include "util/coordinate.hpp"
|
||||
|
||||
#include <boost/fusion/include/adapt_struct.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -21,17 +19,11 @@ struct ParsedURL final
|
||||
unsigned version;
|
||||
std::string profile;
|
||||
std::string query;
|
||||
std::size_t prefix_length;
|
||||
};
|
||||
|
||||
} // api
|
||||
} // server
|
||||
} // osrm
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(osrm::server::api::ParsedURL,
|
||||
(std::string, service)
|
||||
(unsigned, version)
|
||||
(std::string, profile)
|
||||
(std::string, query)
|
||||
)
|
||||
|
||||
#endif
|
||||
|
@ -25,7 +25,7 @@ class BaseService
|
||||
BaseService(OSRM &routing_machine) : routing_machine(routing_machine) {}
|
||||
virtual ~BaseService() = default;
|
||||
|
||||
virtual engine::Status RunQuery(std::string &query, ResultT &result) = 0;
|
||||
virtual engine::Status RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) = 0;
|
||||
|
||||
virtual unsigned GetVersion() = 0;
|
||||
|
||||
|
@ -22,7 +22,7 @@ class MatchService final : public BaseService
|
||||
public:
|
||||
MatchService(OSRM &routing_machine) : BaseService(routing_machine) {}
|
||||
|
||||
engine::Status RunQuery(std::string &query, ResultT &result) final override;
|
||||
engine::Status RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) final override;
|
||||
|
||||
unsigned GetVersion() final override { return 1; }
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ class NearestService final : public BaseService
|
||||
public:
|
||||
NearestService(OSRM &routing_machine) : BaseService(routing_machine) {}
|
||||
|
||||
engine::Status RunQuery(std::string &query, ResultT &result) final override;
|
||||
engine::Status RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) final override;
|
||||
|
||||
unsigned GetVersion() final override { return 1; }
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ class RouteService final : public BaseService
|
||||
public:
|
||||
RouteService(OSRM &routing_machine) : BaseService(routing_machine) {}
|
||||
|
||||
engine::Status RunQuery(std::string &query, ResultT &result) final override;
|
||||
engine::Status RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) final override;
|
||||
|
||||
unsigned GetVersion() final override { return 1; }
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ class TableService final : public BaseService
|
||||
public:
|
||||
TableService(OSRM &routing_machine) : BaseService(routing_machine) {}
|
||||
|
||||
engine::Status RunQuery(std::string &query, ResultT &result) final override;
|
||||
engine::Status RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) final override;
|
||||
|
||||
unsigned GetVersion() final override { return 1; }
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ class TileService final : public BaseService
|
||||
public:
|
||||
TileService(OSRM &routing_machine) : BaseService(routing_machine) {}
|
||||
|
||||
engine::Status RunQuery(std::string &query, ResultT &result) final override;
|
||||
engine::Status RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) final override;
|
||||
|
||||
unsigned GetVersion() final override { return 1; }
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ class TripService final : public BaseService
|
||||
public:
|
||||
TripService(OSRM &routing_machine) : BaseService(routing_machine) {}
|
||||
|
||||
engine::Status RunQuery(std::string &query, ResultT &result) final override;
|
||||
engine::Status RunQuery(std::size_t prefix_length, std::string &query, ResultT &result) final override;
|
||||
|
||||
unsigned GetVersion() final override { return 1; }
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -40,7 +40,7 @@ std::string getWrongOptionHelp(const engine::api::MatchParameters ¶meters)
|
||||
}
|
||||
} // 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;
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ std::string getWrongOptionHelp(const engine::api::NearestParameters ¶meters)
|
||||
}
|
||||
} // 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);
|
||||
|
@ -36,7 +36,7 @@ std::string getWrongOptionHelp(const engine::api::RouteParameters ¶meters)
|
||||
}
|
||||
} // 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);
|
||||
|
@ -57,7 +57,7 @@ std::string getWrongOptionHelp(const engine::api::TableParameters ¶meters)
|
||||
}
|
||||
} // 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);
|
||||
|
@ -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);
|
||||
|
@ -38,7 +38,7 @@ std::string getWrongOptionHelp(const engine::api::TripParameters ¶meters)
|
||||
}
|
||||
} // 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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,52 +51,57 @@ BOOST_AUTO_TEST_CASE(invalid_urls)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(valid_urls)
|
||||
{
|
||||
api::ParsedURL reference_1{"route", 1, "profile", "0,1;2,3;4,5?options=value&foo=bar"};
|
||||
api::ParsedURL reference_1{"route", 1, "profile", "0,1;2,3;4,5?options=value&foo=bar", 18UL};
|
||||
auto result_1 = api::parseURL("/route/v1/profile/0,1;2,3;4,5?options=value&foo=bar");
|
||||
BOOST_CHECK(result_1);
|
||||
BOOST_CHECK_EQUAL(reference_1.service, result_1->service);
|
||||
BOOST_CHECK_EQUAL(reference_1.version, result_1->version);
|
||||
BOOST_CHECK_EQUAL(reference_1.profile, result_1->profile);
|
||||
CHECK_EQUAL_RANGE(reference_1.query, result_1->query);
|
||||
BOOST_CHECK_EQUAL(reference_1.prefix_length, result_1->prefix_length);
|
||||
|
||||
// no options
|
||||
api::ParsedURL reference_2{"route", 1, "profile", "0,1;2,3;4,5"};
|
||||
api::ParsedURL reference_2{"route", 1, "profile", "0,1;2,3;4,5", 18UL};
|
||||
auto result_2 = api::parseURL("/route/v1/profile/0,1;2,3;4,5");
|
||||
BOOST_CHECK(result_2);
|
||||
BOOST_CHECK_EQUAL(reference_2.service, result_2->service);
|
||||
BOOST_CHECK_EQUAL(reference_2.version, result_2->version);
|
||||
BOOST_CHECK_EQUAL(reference_2.profile, result_2->profile);
|
||||
CHECK_EQUAL_RANGE(reference_2.query, result_2->query);
|
||||
BOOST_CHECK_EQUAL(reference_2.prefix_length, result_2->prefix_length);
|
||||
|
||||
// one coordinate
|
||||
std::vector<util::Coordinate> coords_3 = {
|
||||
util::Coordinate(util::FloatLongitude(0), util::FloatLatitude(1)),
|
||||
};
|
||||
api::ParsedURL reference_3{"route", 1, "profile", "0,1"};
|
||||
api::ParsedURL reference_3{"route", 1, "profile", "0,1", 18UL};
|
||||
auto result_3 = api::parseURL("/route/v1/profile/0,1");
|
||||
BOOST_CHECK(result_3);
|
||||
BOOST_CHECK_EQUAL(reference_3.service, result_3->service);
|
||||
BOOST_CHECK_EQUAL(reference_3.version, result_3->version);
|
||||
BOOST_CHECK_EQUAL(reference_3.profile, result_3->profile);
|
||||
CHECK_EQUAL_RANGE(reference_3.query, result_3->query);
|
||||
BOOST_CHECK_EQUAL(reference_3.prefix_length, result_3->prefix_length);
|
||||
|
||||
// polyline
|
||||
api::ParsedURL reference_5{"route", 1, "profile", "polyline(_ibE?_seK_seK_seK_seK)?"};
|
||||
api::ParsedURL reference_5{"route", 1, "profile", "polyline(_ibE?_seK_seK_seK_seK)?", 18UL};
|
||||
auto result_5 = api::parseURL("/route/v1/profile/polyline(_ibE?_seK_seK_seK_seK)?");
|
||||
BOOST_CHECK(result_5);
|
||||
BOOST_CHECK_EQUAL(reference_5.service, result_5->service);
|
||||
BOOST_CHECK_EQUAL(reference_5.version, result_5->version);
|
||||
BOOST_CHECK_EQUAL(reference_5.profile, result_5->profile);
|
||||
CHECK_EQUAL_RANGE(reference_5.query, result_5->query);
|
||||
BOOST_CHECK_EQUAL(reference_5.prefix_length, result_5->prefix_length);
|
||||
|
||||
// tile
|
||||
api::ParsedURL reference_6{"route", 1, "profile", "tile(1,2,3).mvt"};
|
||||
api::ParsedURL reference_6{"route", 1, "profile", "tile(1,2,3).mvt", 18UL};
|
||||
auto result_6 = api::parseURL("/route/v1/profile/tile(1,2,3).mvt");
|
||||
BOOST_CHECK(result_5);
|
||||
BOOST_CHECK(result_6);
|
||||
BOOST_CHECK_EQUAL(reference_6.service, result_6->service);
|
||||
BOOST_CHECK_EQUAL(reference_6.version, result_6->version);
|
||||
BOOST_CHECK_EQUAL(reference_6.profile, result_6->profile);
|
||||
CHECK_EQUAL_RANGE(reference_6.query, result_6->query);
|
||||
BOOST_CHECK_EQUAL(reference_6.prefix_length, result_6->prefix_length);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
Loading…
Reference in New Issue
Block a user