diff --git a/webcc/client.cc b/webcc/client.cc index ff8be5d..ce4cbc5 100644 --- a/webcc/client.cc +++ b/webcc/client.cc @@ -1,7 +1,6 @@ #include "webcc/client.h" #include "webcc/logger.h" -#include "webcc/utility.h" using boost::asio::ip::tcp; @@ -16,8 +15,6 @@ Client::Client() timer_canceled_(false), timed_out_(false), error_(kNoError) { - - } bool Client::Request(RequestPtr request, bool connect) { @@ -75,14 +72,14 @@ Error Client::Connect(RequestPtr request) { if (request->url().scheme() == "https") { #if WEBCC_ENABLE_SSL socket_.reset(new SslSocket{ io_context_, ssl_verify_ }); - return DoConnect(request, kPort443); + return DoConnect(request, "443"); #else LOG_ERRO("SSL/HTTPS support is not enabled."); return kSchemaError; #endif // WEBCC_ENABLE_SSL } else { socket_.reset(new Socket{ io_context_ }); - return DoConnect(request, kPort80); + return DoConnect(request, "80"); } } diff --git a/webcc/globals.h b/webcc/globals.h index 6b9cb40..24efe10 100644 --- a/webcc/globals.h +++ b/webcc/globals.h @@ -38,6 +38,8 @@ #endif // _MSC_VER +#define ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A))) + namespace webcc { // ----------------------------------------------------------------------------- @@ -57,15 +59,9 @@ const std::size_t kMaxDumpSize = 2048; // Default buffer size for socket reading. const std::size_t kBufferSize = 1024; -// Default port for HTTP. -const char* const kPort80 = "80"; -// Default port for HTTPS. -const char* const kPort443 = "443"; - // Why 1400? See the following page: // https://www.itworld.com/article/2693941/why-it-doesn-t-make-sense-to- // gzip-all-content-from-your-web-server.html -// TODO: Configurable const std::size_t kGzipThreshold = 1400; // ----------------------------------------------------------------------------- @@ -87,10 +83,10 @@ const char* const kPatch = "PATCH"; } // namespace methods -// HTTP response status. -// This is not a full list. -// Full list: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes -// NTOE: Don't use enum class because we want to convert to/from int easily. +// HTTP status codes. +// Don't use "enum class" for converting to/from int easily. +// The full list is available here: +// https://en.wikipedia.org/wiki/List_of_HTTP_status_codes enum Status { kOK = 200, kCreated = 201, diff --git a/webcc/response.cc b/webcc/response.cc index aa247a7..8d127a1 100644 --- a/webcc/response.cc +++ b/webcc/response.cc @@ -1,71 +1,52 @@ #include "webcc/response.h" -#include "webcc/utility.h" - namespace webcc { -namespace status_strings { - -const std::string OK = "HTTP/1.1 200 OK"; -const std::string CREATED = "HTTP/1.1 201 Created"; -const std::string ACCEPTED = "HTTP/1.1 202 Accepted"; -const std::string NO_CONTENT = "HTTP/1.1 204 No Content"; -const std::string NOT_MODIFIED = "HTTP/1.1 304 Not Modified"; -const std::string BAD_REQUEST = "HTTP/1.1 400 Bad Request"; -const std::string NOT_FOUND = "HTTP/1.1 404 Not Found"; -const std::string INTERNAL_SERVER_ERROR = - "HTTP/1.1 500 Internal Server Error"; -const std::string NOT_IMPLEMENTED = "HTTP/1.1 501 Not Implemented"; -const std::string SERVICE_UNAVAILABLE = "HTTP/1.1 503 Service Unavailable"; - -const std::string& ToString(int status) { - switch (status) { - case Status::kOK: - return OK; - - case Status::kCreated: - return CREATED; - - case Status::kAccepted: - return ACCEPTED; - - case Status::kNoContent: - return NO_CONTENT; - - case Status::kNotModified: - return NOT_MODIFIED; - - case Status::kBadRequest: - return BAD_REQUEST; - - case Status::kNotFound: - return NOT_FOUND; - - case Status::kInternalServerError: - return INTERNAL_SERVER_ERROR; +void Response::Prepare() { + PrepareStatusLine(); - case Status::kNotImplemented: - return NOT_IMPLEMENTED; + SetHeader(headers::kServer, UserAgent()); + SetHeader(headers::kDate, GetTimestamp()); - case Status::kServiceUnavailable: - return SERVICE_UNAVAILABLE; + Message::Prepare(); +} - default: - return NOT_IMPLEMENTED; +static const std::pair kTable[] = { + { Status::kOK, "OK" }, + { Status::kCreated, "Created" }, + { Status::kAccepted, "Accepted" }, + { Status::kNoContent, "No Content" }, + { Status::kNotModified, "Not Modified" }, + { Status::kBadRequest, "Bad Request" }, + { Status::kNotFound, "Not Found" }, + { Status::kInternalServerError, "Internal Server Error" }, + { Status::kNotImplemented, "Not Implemented" }, + { Status::kServiceUnavailable, "Service Unavailable" }, +}; + +static const char* GetReason(int status) { + for (auto& pair : kTable) { + if (pair.first == status) { + return pair.second; + } } + return ""; } -} // namespace status_strings - -void Response::Prepare() { - if (start_line_.empty()) { - start_line_ = status_strings::ToString(status_); +void Response::PrepareStatusLine() { + if (!start_line_.empty()) { + return; } - SetHeader(headers::kServer, UserAgent()); - SetHeader(headers::kDate, GetTimestamp()); + start_line_ = "HTTP/1.1 "; + start_line_ += std::to_string(status_); + start_line_ += " "; - Message::Prepare(); + if (reason_.empty()) { + start_line_ += GetReason(status_); + } else { + start_line_ += reason_; + } } } // namespace webcc diff --git a/webcc/response.h b/webcc/response.h index bc22887..159ce77 100644 --- a/webcc/response.h +++ b/webcc/response.h @@ -37,6 +37,9 @@ public: void Prepare() override; +private: + void PrepareStatusLine(); + private: int status_; // Status code std::string reason_; // Reason phrase