#ifndef WEBCC_GLOBALS_H_ #define WEBCC_GLOBALS_H_ #include #include #include #include #include #include #include "boost/asio/buffer.hpp" // for const_buffer #include "webcc/config.h" #if WEBCC_USE_STD_STRING_VIEW #include #else #include "boost/utility/string_view.hpp" #endif // WEBCC_USE_STD_STRING_VIEW namespace webcc { // ----------------------------------------------------------------------------- #if WEBCC_USE_STD_STRING_VIEW using string_view = std::string_view; #else using string_view = boost::string_view; #endif // WEBCC_USE_STD_STRING_VIEW inline std::string ToString(string_view sv) { #if WEBCC_USE_STD_STRING_VIEW return std::string{ sv.begin(), sv.end() }; #else return sv.to_string(); #endif // WEBCC_USE_STD_STRING_VIEW } // ----------------------------------------------------------------------------- using Strings = std::vector; // Regex sub-matches of the URL (usually resource ID's). // Could also be considered as arguments, so named as UrlArgs. using UrlArgs = std::vector; using Payload = std::vector; using ProgressCallback = std::function; // ----------------------------------------------------------------------------- const char* const kCRLF = "\r\n"; const std::size_t kInvalidLength = -1; // Default timeout for reading response. const int kMaxReadSeconds = 30; // Max size of the HTTP body to dump/log. // If the HTTP, e.g., response, has a very large content, it will be truncated // when dumped/logged. const std::size_t kMaxDumpSize = 2048; // Default buffer size for socket reading. const std::size_t kBufferSize = 1024; // 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 const std::size_t kGzipThreshold = 1400; // ----------------------------------------------------------------------------- namespace literal_buffers { // Buffers for composing payload. // Literal strings can't be used because they have an extra '\0'. extern const char HEADER_SEPARATOR[2]; extern const char CRLF[2]; extern const char DOUBLE_DASHES[2]; } // namespace literal_buffers // ----------------------------------------------------------------------------- namespace methods { // HTTP methods (verbs) in string. // Don't use enum to avoid converting back and forth. const char* const kGet = "GET"; const char* const kHead = "HEAD"; const char* const kPost = "POST"; const char* const kPut = "PUT"; const char* const kDelete = "DELETE"; const char* const kConnect = "CONNECT"; const char* const kOptions = "OPTIONS"; const char* const kTrace = "TRACE"; const char* const kPatch = "PATCH"; } // namespace methods // 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 { kContinue = 100, kSwitchingProtocols = 101, kProcessing = 102, kEarlyHints = 103, kOK = 200, kCreated = 201, kAccepted = 202, kNoContent = 204, kNotModified = 304, kTemporaryRedirect = 307, kPermanentRedirect = 308, kBadRequest = 400, kUnauthorized = 401, kForbidden = 403, kNotFound = 404, kMethodNotAllowed = 405, kNotAcceptable = 406, kProxyAuthenticationRequired = 407, kRequestTimeout = 408, kConflict = 409, kGone = 410, kLocked = 423, kIamATeapot = 418, kInternalServerError = 500, kNotImplemented = 501, kBadGateway = 502, kServiceUnavailable = 503, //Not Standard Code By UnknownObject k_uRequestFormatError = 489, k_uRequestInvalid = 490, k_uSubProcessFalied = 491, k_uURLOutOfRange = 492, k_uInvalidRequestHost = 493, k_uIPBlocked = 494, k_uIllegalUpload = 495, k_uFileFormatError = 496, k_uInvalidFile = 497, k_uFileTooLarge = 498, k_uRPSLimited = 499, k_uServerHateYou = 540, k_uDoSFound = 550, k_uDDoSFound = 551, k_uUnknownServerError = 560 }; namespace headers { // NOTE: Field names are case-insensitive. // See https://stackoverflow.com/a/5259004 for more details. const char* const kHost = "Host"; const char* const kDate = "Date"; const char* const kAuthorization = "Authorization"; const char* const kContentType = "Content-Type"; const char* const kContentLength = "Content-Length"; const char* const kContentEncoding = "Content-Encoding"; const char* const kContentMD5 = "Content-MD5"; const char* const kContentDisposition = "Content-Disposition"; const char* const kConnection = "Connection"; const char* const kTransferEncoding = "Transfer-Encoding"; const char* const kAccept = "Accept"; const char* const kAcceptEncoding = "Accept-Encoding"; const char* const kUserAgent = "User-Agent"; const char* const kServer = "Server"; } // namespace headers namespace media_types { // See the following link for the full list of media types: // https://www.iana.org/assignments/media-types/media-types.xhtml const char* const kApplicationJson = "application/json"; const char* const kApplicationSoapXml = "application/soap+xml"; const char* const kApplicationFormUrlEncoded = "application/x-www-form-urlencoded"; const char* const kTextPlain = "text/plain"; const char* const kTextXml = "text/xml"; // Get media type from file extension. std::string FromExtension(const std::string& ext); } // namespace media_types namespace charsets { const char* const kUtf8 = "utf-8"; } // namespace charsets enum class ContentEncoding { kUnknown, kGzip, kDeflate, }; // ----------------------------------------------------------------------------- // Error or exception (for client only). class Error : public std::exception { public: enum Code { kUnknownError = -1, kOK = 0, kStateError, kSyntaxError, kResolveError, kConnectError, kSocketReadError, kSocketWriteError, kParseError, kFileError, kDataError, }; public: explicit Error(Code code = kOK, string_view message = "") : code_(code), message_(message) { } // Note that `noexcept` is required by GCC. const char* what() const noexcept override { return message_.c_str(); } Code code() const { return code_; } const std::string& message() const { return message_; } void Set(Code code, string_view message) { code_ = code; message_ = ToString(message); } bool timeout() const { return timeout_; } void set_timeout(bool timeout) { timeout_ = timeout; } operator bool() const { return code_ != kOK; } private: Code code_; std::string message_; bool timeout_ = false; }; std::ostream& operator<<(std::ostream& os, const Error& error); } // namespace webcc #endif // WEBCC_GLOBALS_H_