diff --git a/src/Http.cpp b/src/Http.cpp index 58f69a7..650fc97 100644 --- a/src/Http.cpp +++ b/src/Http.cpp @@ -117,11 +117,11 @@ namespace fr if(str.empty()) return; - //Ensure that URI begins with a / + //Store it, ensuring that it begins with a forwards slash if(str.front() == '/') uri = str; else - uri = "/" + str; + uri = '/' + str; } std::string Http::request_type_to_string(RequestType type) const diff --git a/src/HttpRequest.cpp b/src/HttpRequest.cpp index ac4fa69..928a8fd 100644 --- a/src/HttpRequest.cpp +++ b/src/HttpRequest.cpp @@ -93,7 +93,18 @@ namespace fr std::string HttpRequest::construct(const std::string &host) const { //Add HTTP header - std::string request = request_type_to_string(request_type == Http::Unknown ? Http::Get : request_type) + " " + uri + " HTTP/1.1\r\n"; + std::string request = request_type_to_string(request_type == Http::Unknown ? Http::Get : request_type) + " " + uri; + if(!get_data.empty()) + { + request += "?"; + for(auto iter = get_data.begin(); iter != get_data.end();) + { + request += iter->first + "=" + iter->second; + if(++iter != get_data.end()) + request += "&"; + } + } + request += " HTTP/1.1\r\n"; //Add the headers to the request for(const auto &header : header_data) @@ -104,13 +115,13 @@ namespace fr //Generate post line std::string post_string; - for(auto &post : post_data) - post_string += post.first + "=" + post.second + "&"; - if(!post_string.empty()) + for(auto iter = post_data.begin(); iter != post_data.end();) { - post_string.erase(request.size() - 1, 1); - post_string += "\r\n"; + post_string += iter->first + "=" + iter->second; + if(++iter != get_data.end()) + post_string += "&"; } + post_string += "\r\n"; //Add in required headers if they're missing if(header_data.find("Connection") == header_data.end()) @@ -195,10 +206,13 @@ namespace fr auto get_vars = parse_argument_list(str.substr(get_begin, uri_end - get_begin)); for(auto &c : get_vars) get_data.emplace(std::move(c.first), std::move(c.second)); + set_uri(str.substr(uri_begin, get_begin - uri_begin)); uri.erase(get_begin, uri.size() - get_begin); } - - set_uri(uri); + else + { + set_uri(uri); + } return; } throw std::invalid_argument("No URI found in: " + str); diff --git a/tests/HttpRequestTest.cpp b/tests/HttpRequestTest.cpp index 9087d41..e80343f 100644 --- a/tests/HttpRequestTest.cpp +++ b/tests/HttpRequestTest.cpp @@ -5,7 +5,7 @@ TEST(HttpRequestTest, get_request_parse) { //The test request to parse const std::string raw_request = - "GET /index.html HTTP/1.1\n" + "GET /index.html?var=bob&other=trob HTTP/1.1\n" "Host: frednicolson.co.uk\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "My-Header: header1\n" @@ -35,6 +35,16 @@ TEST(HttpRequestTest, get_request_parse) ASSERT_EQ(request.header("content-type"), "application/x-www-form-urlencoded"); ASSERT_EQ(request.header("My-Other-Header"), "header2"); ASSERT_EQ(request.header("My-Header"), "header1"); + + //Test that GET variables exist + ASSERT_EQ(request.get_exists("var"), true); + ASSERT_EQ(request.get_exists("other"), true); + ASSERT_EQ(request.get_exists("fake"), false); + + //Ensure that GET variables are valid + ASSERT_EQ(request.get("var"), "bob"); + ASSERT_EQ(request.get("other"), "trob"); + ASSERT_EQ(request.get("fake"), ""); } TEST(HttpRequestTest, post_request_parse) @@ -99,7 +109,52 @@ TEST(HttpRequestTest, request_type_parse) request = {}; } -TEST(HttpRequestTest, request_construction) +TEST(HttpRequestTest, get_request_construction) { - //todo: more tests + //Create a request + fr::HttpRequest request; + ASSERT_EQ(request.get_uri(), "/"); + + request.header("MyHeader") = "header1"; + request.header("MyOther-Header") = "header2"; + request.get("my_get") = "var1"; + request.get("my_other_get") = "var2"; + request.set_uri("heyo/bobby"); + request.set_type(fr::Http::Get); + const std::string constructed_request = request.construct("frednicolson.co.uk"); + + //Parse it and check that everything's correct + request = {}; + request.parse(constructed_request.c_str(), constructed_request.size()); + ASSERT_EQ(request.header("MyHeader"), "header1"); + ASSERT_EQ(request.header("MyOther-Header"), "header2"); + ASSERT_EQ(request.get("my_get"), "var1"); + ASSERT_EQ(request.get("my_other_get"), "var2"); + ASSERT_EQ(request.get_uri(), "/heyo/bobby"); + ASSERT_EQ(request.get_type(), fr::Http::Get); +} + +TEST(HttpRequestTest, post_request_construction) +{ + //Create a request + fr::HttpRequest request; + request.header("MyHeader") = "header1"; + request.header("MyOtherHeader") = "header2"; + request.set_uri("/heyo/bobby"); + request.get("var") = "20"; + request.post("my_post") = "post_data"; + request.post("some_post") = "more_post"; + request.set_type(fr::Http::Post); + const std::string constructed_request = request.construct("frednicolson.co.uk"); + + //Parse it + request = {}; + request.parse(constructed_request.c_str(), constructed_request.size()); + ASSERT_EQ(request.header("MyHeader"), "header1"); + ASSERT_EQ(request.header("MyOtherHeader"), "header2"); + ASSERT_EQ(request.get_uri(), "/heyo/bobby"); + ASSERT_EQ(request.get("var"), "20"); + ASSERT_EQ(request.post("my_post"), "post_data"); + ASSERT_EQ(request.post("some_post"), "more_post"); + ASSERT_EQ(request.get_type(), fr::Http::Post); } \ No newline at end of file