HTTP parsing bug fixes, added tests

Fixed HTTP request parse failing if the URI was too short. 

Fixed HTTP parser not converting POST/GET data to lowercase before storing it, making post and get data which contained capitals impossible to access.
This commit is contained in:
Fred Nicolson 2018-01-26 13:18:45 +00:00
parent 7bab41ed9b
commit ad847f0052
3 changed files with 34 additions and 6 deletions

View File

@ -171,7 +171,10 @@ namespace fr
//Split up the body and store each argument name and value //Split up the body and store each argument name and value
auto post = parse_argument_list(body.substr(post_begin, body.size() - post_begin - (body.size() - post_end))); auto post = parse_argument_list(body.substr(post_begin, body.size() - post_begin - (body.size() - post_end)));
for(auto &c : post) for(auto &c : post)
{
std::transform(c.first.begin(), c.first.end(), c.first.begin(), ::tolower);
post_data.emplace(std::move(c.first), std::move(c.second)); post_data.emplace(std::move(c.first), std::move(c.second));
}
} }
void HttpRequest::parse_header_type(const std::string &str) void HttpRequest::parse_header_type(const std::string &str)
@ -205,22 +208,21 @@ namespace fr
auto uri_end = str.find("HTTP") - 1; auto uri_end = str.find("HTTP") - 1;
if(uri_begin != std::string::npos) if(uri_begin != std::string::npos)
{ {
//Extract URI
std::string uri = str.substr(uri_begin, uri_end - uri_begin);
//Parse GET variables //Parse GET variables
auto get_begin = str.find('?'); auto get_begin = str.find('?');
if(get_begin != std::string::npos) if(get_begin != std::string::npos)
{ {
auto get_vars = parse_argument_list(str.substr(get_begin, uri_end - get_begin)); auto get_vars = parse_argument_list(str.substr(get_begin, uri_end - get_begin));
for(auto &c : get_vars) for(auto &c : get_vars)
{
std::transform(c.first.begin(), c.first.end(), c.first.begin(), ::tolower);
get_data.emplace(std::move(c.first), std::move(c.second)); get_data.emplace(std::move(c.first), std::move(c.second));
}
set_uri(str.substr(uri_begin, get_begin - uri_begin)); set_uri(str.substr(uri_begin, get_begin - uri_begin));
uri.erase(get_begin, uri.size() - get_begin);
} }
else else
{ {
set_uri(uri); set_uri(str.substr(uri_begin, uri_end - uri_begin));
} }
return; return;
} }

View File

@ -139,7 +139,7 @@ namespace fr
//Verify that we're connected //Verify that we're connected
socklen_t len = sizeof(ret); socklen_t len = sizeof(ret);
if(getsockopt(socket_descriptor, SOL_SOCKET, SO_ERROR, &ret, &len) == -1) if(getsockopt(socket_descriptor, SOL_SOCKET, SO_ERROR, (char*)&ret, &len) == -1)
continue; continue;
if(ret != 0) if(ret != 0)
continue; continue;

View File

@ -186,3 +186,29 @@ TEST(HttpRequestTest, partial_parse)
ASSERT_EQ(request.header("content-type"), "application/x-www-form-urlencoded"); ASSERT_EQ(request.header("content-type"), "application/x-www-form-urlencoded");
ASSERT_EQ(request.header("Cache-Control"), "no-cache"); ASSERT_EQ(request.header("Cache-Control"), "no-cache");
} }
TEST(HttpRequestTest, awkward_parse)
{
std::string request_data = ""
"POST /my/url? HTTP/1.1\n"
"\n"
"Test=bob\n"
"\n";
fr::HttpRequest request;
ASSERT_EQ(request.parse(request_data.c_str(), request_data.size()), fr::Socket::Success);
ASSERT_EQ(request.get_uri(), "/my/url");
ASSERT_EQ(request.post("Test"), "bob");
}
TEST(HttpRequestTest, awkward_parse2)
{
std::string request_data = "POST /my/url?Bob=10 HTTP/1.1\n"
"\n"
"Test=bob";
fr::HttpRequest request;
ASSERT_EQ(request.parse(request_data.c_str(), request_data.size()), fr::Socket::Success);
ASSERT_EQ(request.get_uri(), "/my/url");
ASSERT_EQ(request.get("Bob"), "10");
ASSERT_EQ(request.post("Test"), "bob");
}