From: Marcin Siodelski Date: Mon, 19 Dec 2016 18:15:03 +0000 (+0100) Subject: [5088] Improved HttpResponse and derived classes. X-Git-Tag: trac5090_base~2^2~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cbd89c137eea9969235561f3c6c8bd823c3bbf52;p=thirdparty%2Fkea.git [5088] Improved HttpResponse and derived classes. --- diff --git a/src/lib/http/response.cc b/src/lib/http/response.cc index 6278832726..f88f2197db 100644 --- a/src/lib/http/response.cc +++ b/src/lib/http/response.cc @@ -5,6 +5,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include +#include #include using namespace isc::http; @@ -52,13 +53,13 @@ HttpResponse::setBody(const std::string& body) { bool HttpResponse::isClientError(const HttpStatusCode& status_code) { uint16_t c = statusCodeToNumber(status_code); - return ((c >= 400) && (c <= 500)); + return ((c >= 400) && (c < 500)); } bool HttpResponse::isServerError(const HttpStatusCode& status_code) { uint16_t c = statusCodeToNumber(status_code); - return ((c >= 500) && (c <= 600)); + return ((c >= 500) && (c < 600)); } std::string @@ -77,6 +78,16 @@ HttpResponse::statusCodeToNumber(const HttpStatusCode& status_code) { return (static_cast(status_code)); } +std::string +HttpResponse::getDateHeaderValue() const { + time_t rawtime; + struct tm * timeinfo; + + time ( &rawtime ); + timeinfo = localtime ( &rawtime ); + return (std::string(asctime(timeinfo))); +} + std::string HttpResponse::toString() const { std::ostringstream s; @@ -89,8 +100,10 @@ HttpResponse::toString() const { s << header->first << ": " << header->second << crlf; } + s << "Date: " << getDateHeaderValue() << crlf; + if (!body_.empty()) { - s << "Content-Length" << ": " << body_.length() << crlf; + s << "Content-Length: " << body_.length() << crlf; } s << crlf; diff --git a/src/lib/http/response.h b/src/lib/http/response.h index 73c6363510..a8302d0672 100644 --- a/src/lib/http/response.h +++ b/src/lib/http/response.h @@ -57,22 +57,12 @@ public: HttpResponse(const HttpVersion& version, const HttpStatusCode& status_code); - virtual ~HttpResponse() { - } - - template - void addHeader(const std::string& name, const ValueType& value) { - try { - headers_[name] = boost::lexical_cast(value); + virtual ~HttpResponse() { } - } catch (const boost::bad_lexical_cast& ex) { - isc_throw(HttpResponseError, "unable to convert header value" - " to a string: " << ex.what()); - } + void addHeader(const std::string& name, const std::string& value) { + headers_[name] = value; } - void setGenericBody(const HttpStatusCode& status_code) { }; - virtual void setBody(const std::string& body); static bool isClientError(const HttpStatusCode& status_code); @@ -85,10 +75,14 @@ public: protected: + virtual std::string getDateHeaderValue() const; + static uint16_t statusCodeToNumber(const HttpStatusCode& status_code); private: + void setGenericBody(const HttpStatusCode& status_code) { }; + HttpVersion http_version_; HttpStatusCode status_code_; diff --git a/src/lib/http/tests/response_unittests.cc b/src/lib/http/tests/response_unittests.cc index d76ed37b9e..a10b004b67 100644 --- a/src/lib/http/tests/response_unittests.cc +++ b/src/lib/http/tests/response_unittests.cc @@ -9,12 +9,42 @@ #include #include #include +#include using namespace isc::http; namespace { -TEST(HttpResponseTest, construction) { +class TestHttpResponse : public HttpResponse { +public: + + TestHttpResponse(const HttpVersion& version, const HttpStatusCode& status_code) + : HttpResponse(version, status_code) { + } + + virtual std::string getDateHeaderValue() const { + return ("Mon Dec 19 18:53:35 2016"); + } +}; + +class HttpResponseTest : public ::testing::Test { +public: + + void testResponse(const HttpStatusCode& status_code, + const std::string& status_message) { + HttpResponse response(HttpVersion(1, 0), status_code); + response.addHeader("Content-Type", "text/html"); + std::ostringstream response_string; + response_string << "HTTP/1.0 " << static_cast(status_code) + << " " << status_message << "\r\n" + << "Content-Type: text/html\r\n\r\n"; + + EXPECT_EQ(response_string.str(), response.toString()); + } + +}; + +TEST_F(HttpResponseTest, responseOK) { const std::string sample_body = "" "Kea page title" @@ -36,4 +66,61 @@ TEST(HttpResponseTest, construction) { EXPECT_EQ(response_string.str(), response.toString()); } +TEST_F(HttpResponseTest, genericResponse) { + testResponse(HttpStatusCode::OK, "OK"); + testResponse(HttpStatusCode::CREATED, "Created"); + testResponse(HttpStatusCode::ACCEPTED, "Accepted"); + testResponse(HttpStatusCode::NO_CONTENT, "No Content"); + testResponse(HttpStatusCode::MULTIPLE_CHOICES, "Multiple Choices"); + testResponse(HttpStatusCode::MOVED_PERMANENTLY, "Moved Permanently"); + testResponse(HttpStatusCode::MOVED_TEMPORARILY, "Moved Temporarily"); + testResponse(HttpStatusCode::NOT_MODIFIED, "Not Modified"); + testResponse(HttpStatusCode::BAD_REQUEST, "Bad Request"); + testResponse(HttpStatusCode::UNAUTHORIZED, "Unauthorized"); + testResponse(HttpStatusCode::FORBIDDEN, "Forbidden"); + testResponse(HttpStatusCode::NOT_FOUND, "Not Found"); + testResponse(HttpStatusCode::INTERNAL_SERVER_ERROR, "Internal Server Error"); + testResponse(HttpStatusCode::NOT_IMPLEMENTED, "Not Implemented"); + testResponse(HttpStatusCode::BAD_GATEWAY, "Bad Gateway"); + testResponse(HttpStatusCode::SERVICE_UNAVAILABLE, "Service Unavailable"); +} + +TEST_F(HttpResponseTest, isClientError) { + EXPECT_FALSE(HttpResponse::isClientError(HttpStatusCode::OK)); + EXPECT_FALSE(HttpResponse::isClientError(HttpStatusCode::CREATED)); + EXPECT_FALSE(HttpResponse::isClientError(HttpStatusCode::ACCEPTED)); + EXPECT_FALSE(HttpResponse::isClientError(HttpStatusCode::NO_CONTENT)); + EXPECT_FALSE(HttpResponse::isClientError(HttpStatusCode::MULTIPLE_CHOICES)); + EXPECT_FALSE(HttpResponse::isClientError(HttpStatusCode::MOVED_PERMANENTLY)); + EXPECT_FALSE(HttpResponse::isClientError(HttpStatusCode::MOVED_TEMPORARILY)); + EXPECT_FALSE(HttpResponse::isClientError(HttpStatusCode::NOT_MODIFIED)); + EXPECT_TRUE(HttpResponse::isClientError(HttpStatusCode::BAD_REQUEST)); + EXPECT_TRUE(HttpResponse::isClientError(HttpStatusCode::UNAUTHORIZED)); + EXPECT_TRUE(HttpResponse::isClientError(HttpStatusCode::FORBIDDEN)); + EXPECT_TRUE(HttpResponse::isClientError(HttpStatusCode::NOT_FOUND)); + EXPECT_FALSE(HttpResponse::isClientError(HttpStatusCode::INTERNAL_SERVER_ERROR)); + EXPECT_FALSE(HttpResponse::isClientError(HttpStatusCode::NOT_IMPLEMENTED)); + EXPECT_FALSE(HttpResponse::isClientError(HttpStatusCode::BAD_GATEWAY)); + EXPECT_FALSE(HttpResponse::isClientError(HttpStatusCode::SERVICE_UNAVAILABLE)); +} + +TEST_F(HttpResponseTest, isServerError) { + EXPECT_FALSE(HttpResponse::isServerError(HttpStatusCode::OK)); + EXPECT_FALSE(HttpResponse::isServerError(HttpStatusCode::CREATED)); + EXPECT_FALSE(HttpResponse::isServerError(HttpStatusCode::ACCEPTED)); + EXPECT_FALSE(HttpResponse::isServerError(HttpStatusCode::NO_CONTENT)); + EXPECT_FALSE(HttpResponse::isServerError(HttpStatusCode::MULTIPLE_CHOICES)); + EXPECT_FALSE(HttpResponse::isServerError(HttpStatusCode::MOVED_PERMANENTLY)); + EXPECT_FALSE(HttpResponse::isServerError(HttpStatusCode::MOVED_TEMPORARILY)); + EXPECT_FALSE(HttpResponse::isServerError(HttpStatusCode::NOT_MODIFIED)); + EXPECT_FALSE(HttpResponse::isServerError(HttpStatusCode::BAD_REQUEST)); + EXPECT_FALSE(HttpResponse::isServerError(HttpStatusCode::UNAUTHORIZED)); + EXPECT_FALSE(HttpResponse::isServerError(HttpStatusCode::FORBIDDEN)); + EXPECT_FALSE(HttpResponse::isServerError(HttpStatusCode::NOT_FOUND)); + EXPECT_TRUE(HttpResponse::isServerError(HttpStatusCode::INTERNAL_SERVER_ERROR)); + EXPECT_TRUE(HttpResponse::isServerError(HttpStatusCode::NOT_IMPLEMENTED)); + EXPECT_TRUE(HttpResponse::isServerError(HttpStatusCode::BAD_GATEWAY)); + EXPECT_TRUE(HttpResponse::isServerError(HttpStatusCode::SERVICE_UNAVAILABLE)); +} + }