diff --git a/core/util/HTTP.cpp b/core/util/HTTP.cpp index 2addeda3..db740f55 100644 --- a/core/util/HTTP.cpp +++ b/core/util/HTTP.cpp @@ -55,6 +55,50 @@ std::string Request::getHeader(const std::string& name) const return headers.at(name); } +Response::Response(int status) + : status(status), headers() +{ + +} + +void Response::setHeader(const std::string& name, const std::string& value) +{ + headers[name] = value; +} + +std::string Response::toString() const +{ + std::stringstream ss; + ss << "HTTP/1.1 " << status << ' ' << getStatusMessage() << "\r\n"; + for(auto& pair : headers) + ss << pair.first << ": " << pair.second << "\r\n"; + ss << "\r\n"; + return ss.str(); +} + +std::string Response::getStatusMessage() const +{ + switch(status) { + case 105: + return "Name Not Resolved"; + case 200: + return "OK"; + case 400: + return "Bad Request"; + case 404: + return "Not Found"; + case 408: + return "Request Timeout"; + case 500: + return "Internal Server Error"; + case 502: + return "Not Implemented"; + case 504: + return "Gateway Timeout"; + default: + return std::string(); + } +} } } } diff --git a/core/util/HTTP.h b/core/util/HTTP.h index ceb3d931..252b1533 100644 --- a/core/util/HTTP.h +++ b/core/util/HTTP.h @@ -9,11 +9,15 @@ namespace util { namespace http { class Request { + void parseRequestLine(const std::string& line); + void parseHeaderLine(const std::string& line); public: Request(const std::string& data); + Request(); + std::string getMethod() const; std::string getUri() const; @@ -35,6 +39,29 @@ private: std::map headers; }; +class Response { +public: + + Response(int status); + + /** + * @note overrides existing header values with the same name + */ + void setHeader(const std::string& name, const std::string& value); + + std::string toString() const; + + /** + * @return the message associated with the satus of this response, or the + * empty string if the status number is invalid + */ + std::string getStatusMessage() const; + +private: + int status; + std::map headers; +}; + } } } diff --git a/tests/Utility.cpp b/tests/Utility.cpp index 8317669f..ec285b4e 100644 --- a/tests/Utility.cpp +++ b/tests/Utility.cpp @@ -113,5 +113,28 @@ BOOST_AUTO_TEST_CASE(ParseHTTPRequestWithHeaders) BOOST_CHECK_EQUAL(req2.getHeader("Host"), "localhost:123"); } +BOOST_AUTO_TEST_CASE(HTTPResponseStatusMessage) +{ + BOOST_CHECK_EQUAL(Response(0).getStatusMessage(), ""); + BOOST_CHECK_EQUAL(Response(105).getStatusMessage(), "Name Not Resolved"); + BOOST_CHECK_EQUAL(Response(200).getStatusMessage(), "OK"); + BOOST_CHECK_EQUAL(Response(400).getStatusMessage(), "Bad Request"); + BOOST_CHECK_EQUAL(Response(404).getStatusMessage(), "Not Found"); + BOOST_CHECK_EQUAL(Response(408).getStatusMessage(), "Request Timeout"); + BOOST_CHECK_EQUAL(Response(500).getStatusMessage(), "Internal Server Error"); + BOOST_CHECK_EQUAL(Response(502).getStatusMessage(), "Not Implemented"); + BOOST_CHECK_EQUAL(Response(504).getStatusMessage(), "Gateway Timeout"); +} +BOOST_AUTO_TEST_CASE(WriteHTTPResponse) +{ + Response rsp(200); + rsp.setHeader("Connection", "close"); + BOOST_CHECK_EQUAL( + rsp.toString(), + "HTTP/1.1 200 OK\r\n" + "Connection: close\r\n\r\n" + ); +} + BOOST_AUTO_TEST_SUITE_END()