Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accepting HTTP Post Request #1502

Merged
merged 8 commits into from
Jun 17, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions features/step_definitions/data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,7 @@
Given /^data is loaded with datastore$/ do
@load_method = 'datastore'
end

Given /^the HTTP method "([^"]*)"$/ do |method|
@http_method = method
end
2 changes: 1 addition & 1 deletion features/step_definitions/locate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
out_node = find_node_by_name row['out']
raise "*** unknown out-node '#{row['out']}" unless out_node

response = request_locate("#{in_node.lat},#{in_node.lon}")
response = request_locate(in_node)
if response.code == "200" && response.body.empty? == false
json = JSON.parse response.body
if json['status'] == 0
Expand Down
2 changes: 1 addition & 1 deletion features/step_definitions/nearest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
out_node = find_node_by_name row['out']
raise "*** unknown out-node '#{row['out']}" unless out_node

response = request_nearest("#{in_node.lat},#{in_node.lon}")
response = request_nearest(in_node)
if response.code == "200" && response.body.empty? == false
json = JSON.parse response.body
if json['status'] == 0
Expand Down
34 changes: 34 additions & 0 deletions features/support/http.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'net/http'

def generate_request_url path
if @http_method.eql? "POST"
pos = path.index('?') - 1
service = path[0..pos]
uri = URI.parse "#{HOST}/#{service}"
else
uri = URI.parse "#{HOST}/#{path}"
end
end

def send_request uri, waypoints=[], options={}, timestamps=[]
@query = uri.to_s
Timeout.timeout(OSRM_TIMEOUT) do
if @http_method.eql? "POST"
datas = {}
if waypoints.length > 0
datas[:loc] = waypoints.compact.map { |w| "#{w.lat},#{w.lon}" }
end
if timestamps.length > 0
datas[:t] = timestamps.compact.map { |t| "#{t}" }
end
datas.merge! options
response = Net::HTTP.post_form uri, datas
else
response = Net::HTTP.get_response uri
end
end
rescue Errno::ECONNREFUSED => e
raise "*** osrm-routed is not running."
rescue Timeout::Error
raise "*** osrm-routed did not respond."
end
17 changes: 6 additions & 11 deletions features/support/locate.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
require 'net/http'

def request_locate_url path
def request_locate_url path, node
@query = path
uri = URI.parse "#{HOST}/#{path}"
Timeout.timeout(OSRM_TIMEOUT) do
Net::HTTP.get_response uri
end
rescue Errno::ECONNREFUSED => e
raise "*** osrm-routed is not running."
rescue Timeout::Error
raise "*** osrm-routed did not respond."

uri = generate_request_url path
response = send_request uri, [node]
end

def request_locate a
request_locate_url "locate?loc=#{a}"
def request_locate node
request_locate_url "locate?loc=#{node.lat},#{node.lon}", node
end
12 changes: 3 additions & 9 deletions features/support/match.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,8 @@ def request_matching trace=[], timestamps=[], options={}
end
params = (trace_params + defaults.merge(options).to_param).join('&')
params = nil if params==""
uri = URI.parse ["#{HOST}/match", params].compact.join('?')
@query = uri.to_s
Timeout.timeout(OSRM_TIMEOUT) do
Net::HTTP.get_response uri
end
rescue Errno::ECONNREFUSED => e
raise "*** osrm-routed is not running."
rescue Timeout::Error
raise "*** osrm-routed did not respond."

uri = generate_request_url ("match" + '?' + params)
response = send_request uri, trace, options, timestamps
end

17 changes: 6 additions & 11 deletions features/support/nearest.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
require 'net/http'

def request_nearest_url path
def request_nearest_url path, node
@query = path
uri = URI.parse "#{HOST}/#{path}"
Timeout.timeout(OSRM_TIMEOUT) do
Net::HTTP.get_response uri
end
rescue Errno::ECONNREFUSED => e
raise "*** osrm-routed is not running."
rescue Timeout::Error
raise "*** osrm-routed did not respond."

uri = generate_request_url path
response = send_request uri, [node]
end

def request_nearest a
request_nearest_url "nearest?loc=#{a}"
def request_nearest node
request_nearest_url "nearest?loc=#{node.lat},#{node.lon}", node
end
14 changes: 6 additions & 8 deletions features/support/route.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ def request_path path, waypoints=[], options={}
locs = waypoints.compact.map { |w| "loc=#{w.lat},#{w.lon}" }
params = (locs + options.to_param).join('&')
params = nil if params==""
uri = URI.parse ["#{HOST}/#{path}", params].compact.join('?')
@query = uri.to_s
Timeout.timeout(OSRM_TIMEOUT) do
Net::HTTP.get_response uri

if params == nil
uri = generate_request_url (path)
else
uri = generate_request_url (path + '?' + params)
end
rescue Errno::ECONNREFUSED => e
raise "*** osrm-routed is not running."
rescue Timeout::Error
raise "*** osrm-routed did not respond."
response = send_request uri, waypoints, options
end

def request_url path
Expand Down
100 changes: 100 additions & 0 deletions features/testbot/post.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
@post @testbot
Feature: POST request

Background:
Given the profile "testbot"
And the HTTP method "POST"

Scenario: Testbot - viaroute POST request
Given the node locations
| node | lat | lon |
| a | 55.68740 | 12.52430 |
| b | 55.68745 | 12.52409 |
| c | 55.68711 | 12.52383 |
| x | -55.68740 | 12.52430 |
| y | -55.68745 | 12.52409 |
| z | -55.68711 | 12.52383 |

And the ways
| nodes |
| ab |
| bc |
| xy |
| yz |

When I route I should get
| from | to | route | turns |
| a | c | ab,bc | head,left,destination |
| c | a | bc,ab | head,right,destination |
| x | z | xy,yz | head,right,destination |
| z | x | yz,xy | head,left,destination |

Scenario: Testbot - match POST request
Given the node map
| a | b | c | d |
| e | f | g | h |

And the ways
| nodes | oneway |
| abcd | yes |
| hgfe | yes |

When I match I should get
| trace | matchings |
| dcba | hgfe |

Scenario: Testbot - table POST request
Given the node map
| x | a | b | y |
| | d | e | |

And the ways
| nodes | oneway |
| abeda | yes |
| xa | |
| by | |

When I request a travel time matrix I should get
| | x | y | d | e |
| x | 0 | 300 | 400 | 300 |
| y | 500 | 0 | 300 | 200 |
| d | 200 | 300 | 0 | 300 |
| e | 300 | 400 | 100 | 0 |

Scenario: Testbot - locate POST request
Given the node locations
| node | lat | lon |
| a | -85 | -180 |
| b | 0 | 0 |
| c | 85 | 180 |
| x | -84 | -180 |
| y | 84 | 180 |

And the ways
| nodes |
| abc |

When I request locate I should get
| in | out |
| x | a |
| y | c |

Scenario: Testbot - nearest POST request
Given the node locations
| node | lat | lon |
| a | -85 | -180 |
| b | -85 | -160 |
| c | -85 | -140 |
| x | -84.999 | -180 |
| y | -84.999 | -160 |
| z | -84.999 | -140 |

And the ways
| nodes |
| abc |

When I request nearest I should get
| in | out |
| x | a |
| y | b |
| z | c |
71 changes: 69 additions & 2 deletions server/request_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ namespace http

RequestParser::RequestParser()
: state(internal_state::method_start), current_header({"", ""}),
selected_compression(no_compression)
selected_compression(no_compression), is_post_header(false),
content_length(0)
{
}

Expand All @@ -58,6 +59,11 @@ RequestParser::parse(request &current_request, char *begin, char *end)
}
}
osrm::tribool result = osrm::tribool::indeterminate;

if(state == internal_state::post_request && content_length <= 0)
{
result = osrm::tribool::yes;
}
return std::make_tuple(result, selected_compression);
}

Expand All @@ -70,8 +76,39 @@ osrm::tribool RequestParser::consume(request &current_request, const char input)
{
return osrm::tribool::no;
}
if(input == 'P')
{
state = internal_state::post_O;
return osrm::tribool::indeterminate;
}
state = internal_state::method;
return osrm::tribool::indeterminate;
case internal_state::post_O:
if(input == 'O')
{
state = internal_state::post_S;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::post_S:
if(input == 'S')
{
state = internal_state::post_T;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::post_T:
if(input == 'T')
{
is_post_header = true;
state = internal_state::method;
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
case internal_state::post_request:
current_request.uri.push_back(input);
--content_length;
return osrm::tribool::indeterminate;
case internal_state::method:
if (input == ' ')
{
Expand Down Expand Up @@ -204,6 +241,24 @@ osrm::tribool RequestParser::consume(request &current_request, const char input)
{
current_request.agent = current_header.value;
}
if (boost::iequals(current_header.name, "Content-Length"))
{
try
{
content_length = std::stoi(current_header.value);
}
catch (const std::exception &e)
{
// Ignore the header if the parameter isn't an int
}
}
if (boost::iequals(current_header.name, "Content-Type"))
{
if (!boost::icontains(current_header.value, "application/x-www-form-urlencoded"))
{
return osrm::tribool::no;
}
}

if (input == '\r')
{
Expand Down Expand Up @@ -272,7 +327,19 @@ osrm::tribool RequestParser::consume(request &current_request, const char input)
return osrm::tribool::indeterminate;
}
return osrm::tribool::no;
default: // expecting_newline_3
case internal_state::expecting_newline_3:
if(input == '\n')
{
if(is_post_header)
{
current_request.uri.push_back('?');
state = internal_state::post_request;
return osrm::tribool::indeterminate;
}
return osrm::tribool::yes;
}
return osrm::tribool::no;
default: // should never be reached
return input == '\n' ? osrm::tribool::yes : osrm::tribool::no;
}
}
Expand Down
8 changes: 7 additions & 1 deletion server/request_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,17 @@ class RequestParser
space_before_header_value,
header_value,
expecting_newline_2,
expecting_newline_3
expecting_newline_3,
post_O,
post_S,
post_T,
post_request
} state;

header current_header;
compression_type selected_compression;
bool is_post_header;
int content_length;
};

} // namespace http
Expand Down