From f2757f777fdfda434ed5c263244d4cc380cca6a2 Mon Sep 17 00:00:00 2001 From: Jessica James Date: Sun, 5 Dec 2021 17:45:59 -0600 Subject: [PATCH] Remove Jupiter::HTTP::HTMLFormResponse; update jessilib (has replacement) --- src/include/Jupiter/Config.h | 2 +- src/include/Jupiter/HTTP.h | 293 +++++++++++++------------ src/include/Jupiter/HTTP_QueryString.h | 177 --------------- src/jessilib | 2 +- 4 files changed, 151 insertions(+), 323 deletions(-) delete mode 100644 src/include/Jupiter/HTTP_QueryString.h diff --git a/src/include/Jupiter/Config.h b/src/include/Jupiter/Config.h index c452bcb..ba1221c 100644 --- a/src/include/Jupiter/Config.h +++ b/src/include/Jupiter/Config.h @@ -26,7 +26,7 @@ #include #include -#include "jessilib/unicode.hpp" +#include "jessilib/unicode_compare.hpp" #include "Jupiter.h" #include "Readable_String.h" // from_string diff --git a/src/include/Jupiter/HTTP.h b/src/include/Jupiter/HTTP.h index 566c61c..daa62e9 100644 --- a/src/include/Jupiter/HTTP.h +++ b/src/include/Jupiter/HTTP.h @@ -24,150 +24,155 @@ * @brief Defines constants related to HTTP */ -namespace Jupiter -{ - namespace HTTP - { - /** - * @brief HTTP status codes - */ - namespace Status - { - /** Informational (1xx) */ - static const int CONTINUE = 100; - static const int SWITCHING_PROTOCOLS = 101; - static const int PROCESSING = 102; // RFC 2518 - - /** Success (2xx) */ - static const int OK = 200; - static const int CREATED = 201; - static const int ACCEPTED = 202; - static const int NONAUTH_INFO = 203; // HTTP/1.1 - static const int NO_CONTENT = 204; - static const int RESET_CONTENT = 205; - static const int PARTIAL_CONTENT = 206; // RFC 7233 - static const int MULTI_STATUS = 207; // RFC 4918 - static const int ALREADY_REPORTED = 208; // RFC 5842 - static const int IM_USED = 226; // RFC 3229 +namespace Jupiter { +namespace HTTP { + +/** +* @brief HTTP status codes +*/ +namespace Status { + +/** Informational (1xx) */ +static constexpr int CONTINUE = 100; +static constexpr int SWITCHING_PROTOCOLS = 101; +static constexpr int PROCESSING = 102; // RFC 2518 + +/** Success (2xx) */ +static constexpr int OK = 200; +static constexpr int CREATED = 201; +static constexpr int ACCEPTED = 202; +static constexpr int NONAUTH_INFO = 203; // HTTP/1.1 +static constexpr int NO_CONTENT = 204; +static constexpr int RESET_CONTENT = 205; +static constexpr int PARTIAL_CONTENT = 206; // RFC 7233 +static constexpr int MULTI_STATUS = 207; // RFC 4918 +static constexpr int ALREADY_REPORTED = 208; // RFC 5842 +static constexpr int IM_USED = 226; // RFC 3229 - /** Redirection (3xx) */ - static const int MULTIPLE_CHOICES = 300; - static const int MOVED_PERMANENTLY = 301; - static const int FOUND = 302; - static const int SEE_OTHER = 303; // HTTP/1.1 - static const int NOT_MODIFIED = 304; // RFC 7232 - static const int USE_PROXY = 305; // HTTP/1.1 - static const int SWITCH_PROXY = 306; // No longer used - static const int TEMPORARY_REDIRECT = 307; // HTTP/1.1 - static const int PERMANENT_REDIRECT = 308; // RFC 7538 - static const int RESUME_INCOMPLETE = 308; // Google - - /** Client Error (4xx) */ - static const int BAD_REQUEST = 400; - static const int UNAUTHORIZED = 401; // RFC 7235 - static const int PAYMENT_REQUIRED = 402; - static const int FORBIDDEN = 403; - static const int NOT_FOUND = 404; - static const int METHOD_NOT_ALLOWED = 405; - static const int NOT_ACCEPTABLE = 406; - static const int PROXY_AUTHENTICATION_REQUIRED = 407; // RFC 7235 - static const int REQUEST_TIMEOUT = 408; - static const int CONFLICT = 409; - static const int GONE = 410; - static const int LENGTH_REQUIRED = 411; - static const int PRECONDITION_FAILED = 412; // RFC 7232 - static const int PAYLOAD_TOO_LARGE = 413; // RFC 7231 - static const int REQUEST_URI_TOO_LONG = 414; - static const int UNSUPPORTED_MEDIA_TYPE = 415; - static const int REQUESTED_RANGE_NOT_SATISFIABLE = 416; // RFC 7233 - static const int EXPECTATION_FAILED = 417; - static const int IM_A_TEAPOT = 418; // RFC 2324 - static const int AUTHENTICATION_TIMEOUT = 419; // Non-RFC - static const int METHOD_FAILURE = 420; // Spring Framework - static const int ENHANCE_YOUR_CALM = 420; // Twitter - static const int MISDIRECTED_REQUEST = 421; // RFC 7540 - static const int UNPROCESSABLE_ENTITY = 422; // RFC 4918 - static const int LOCKED = 423; // RFC 4918 - static const int FAILED_DEPENDENCY = 424; // RFC 4918 - static const int UPGRADE_REQUIRED = 426; - static const int PRECONDITION_REQUIRED = 428; // RFC 6585 - static const int TOO_MANY_REQUESTS = 429; // RFC 6585 - static const int REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC 6585 - static const int LOGIN_TIMEOUT = 440; // Microsoft - static const int NO_RESPONSE = 444; // Nginx - static const int RETRY_WITH = 449; // Microsoft - static const int BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS = 450; // Microsoft - static const int UNAVAILABLE_FOR_LEGAL_REASONS = 451; // "A New HTTP Status Code for Legally-restricted Resources" - static const int REDIRECT = 451; // Microsoft - static const int REQUEST_HEADER_TOO_LARGE = 494; // Nginx - static const int CERT_ERROR = 495; // Nginx - static const int NO_CERT = 496; // Nginx - static const int HTTP_TO_HTTPS = 497; // Nginx - static const int TOKEN_INVALID = 498; // Esri - static const int CLIENT_CLOSED_REQUEST = 499; // Nginx - static const int TOKEN_REQUIRED = 499; // Esri - - /** Server Error (5xx) */ - static const int INTERNAL_SERVER_ERROR = 500; - static const int NOT_IMPLEMENTED = 501; - static const int BAD_GATEWAY = 502; - static const int SERVICE_UNAVAIABLE = 503; - static const int GATEWAY_TIMEOUT = 504; - static const int HTTP_VERSION_NOT_SUPPORTED = 505; - static const int VARIANT_ALSO_NEGOTIATES = 506; // RFC 2295 - static const int INSUFFICIENT_STORAGE = 507; // RFC 4918 - static const int LOOP_DETECTED = 508; // RFC 5842 - static const int BANDWIDTH_LIMIT_EXCEEDED = 509; // Apache - static const int NOT_EXTENDED = 510; // RFC 2774 - static const int NETWORK_AUTHENTICATION_REQUIRED = 511; // RFC 6585 - static const int UNKNOWN_ERROR = 520; // Non-RFC - static const int ORIGIN_CONNECTION_TIMEOUT = 522; // CloudFlare - static const int NETWORK_READ_TIMEOUT = 598; // Microsoft - static const int NETWORK_CONNECTION_TIMEOUT = 599; // Microsoft - } // Jupiter::HTTP::Status namespace - - /** - * @brief Content-type field values - */ - namespace Content - { - /** - * @brief Content-Language values - * TODO: Implement all ISO 639-1 translations - */ - namespace Language { - static constexpr std::string_view ENGLISH = "en"; - static constexpr std::string_view FRENCH = "fr"; - static constexpr std::string_view GERMAN = "gr"; - static constexpr std::string_view RUSSIAN = "ru"; - static constexpr std::string_view JAPANESE = "ja"; - static constexpr std::string_view CHINESE = "zh"; - } - - /** - * @brief Content-Type values - * Note: This is not an exhaustive/exclusive list of values - */ - namespace Type - { - namespace Text - { - namespace Charset - { - static constexpr std::string_view ASCII = "ascii"; - static constexpr std::string_view UTF8 = "utf-8"; - } - - static constexpr std::string_view HTML = "text/html"; - static constexpr std::string_view PLAIN = "text/plain"; - } - namespace Application - { - static constexpr std::string_view OCTET_STREAM = "application/octet-stream"; - } - } - } - } // Jupiter::HTTP namespace -} // Jupiter namespace +/** Redirection (3xx) */ +static constexpr int MULTIPLE_CHOICES = 300; +static constexpr int MOVED_PERMANENTLY = 301; +static constexpr int FOUND = 302; +static constexpr int SEE_OTHER = 303; // HTTP/1.1 +static constexpr int NOT_MODIFIED = 304; // RFC 7232 +static constexpr int USE_PROXY = 305; // HTTP/1.1 +static constexpr int SWITCH_PROXY = 306; // No longer used +static constexpr int TEMPORARY_REDIRECT = 307; // HTTP/1.1 +static constexpr int PERMANENT_REDIRECT = 308; // RFC 7538 +static constexpr int RESUME_INCOMPLETE = 308; // Google + +/** Client Error (4xx) */ +static constexpr int BAD_REQUEST = 400; +static constexpr int UNAUTHORIZED = 401; // RFC 7235 +static constexpr int PAYMENT_REQUIRED = 402; +static constexpr int FORBIDDEN = 403; +static constexpr int NOT_FOUND = 404; +static constexpr int METHOD_NOT_ALLOWED = 405; +static constexpr int NOT_ACCEPTABLE = 406; +static constexpr int PROXY_AUTHENTICATION_REQUIRED = 407; // RFC 7235 +static constexpr int REQUEST_TIMEOUT = 408; +static constexpr int CONFLICT = 409; +static constexpr int GONE = 410; +static constexpr int LENGTH_REQUIRED = 411; +static constexpr int PRECONDITION_FAILED = 412; // RFC 7232 +static constexpr int PAYLOAD_TOO_LARGE = 413; // RFC 7231 +static constexpr int REQUEST_URI_TOO_LONG = 414; +static constexpr int UNSUPPORTED_MEDIA_TYPE = 415; +static constexpr int REQUESTED_RANGE_NOT_SATISFIABLE = 416; // RFC 7233 +static constexpr int EXPECTATION_FAILED = 417; +static constexpr int IM_A_TEAPOT = 418; // RFC 2324 +static constexpr int AUTHENTICATION_TIMEOUT = 419; // Non-RFC +static constexpr int METHOD_FAILURE = 420; // Spring Framework +static constexpr int ENHANCE_YOUR_CALM = 420; // Twitter +static constexpr int MISDIRECTED_REQUEST = 421; // RFC 7540 +static constexpr int UNPROCESSABLE_ENTITY = 422; // RFC 4918 +static constexpr int LOCKED = 423; // RFC 4918 +static constexpr int FAILED_DEPENDENCY = 424; // RFC 4918 +static constexpr int UPGRADE_REQUIRED = 426; +static constexpr int PRECONDITION_REQUIRED = 428; // RFC 6585 +static constexpr int TOO_MANY_REQUESTS = 429; // RFC 6585 +static constexpr int REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC 6585 +static constexpr int LOGIN_TIMEOUT = 440; // Microsoft +static constexpr int NO_RESPONSE = 444; // Nginx +static constexpr int RETRY_WITH = 449; // Microsoft +static constexpr int BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS = 450; // Microsoft +static constexpr int UNAVAILABLE_FOR_LEGAL_REASONS = 451; // "A New HTTP Status Code for Legally-restricted Resources" +static constexpr int REDIRECT = 451; // Microsoft +static constexpr int REQUEST_HEADER_TOO_LARGE = 494; // Nginx +static constexpr int CERT_ERROR = 495; // Nginx +static constexpr int NO_CERT = 496; // Nginx +static constexpr int HTTP_TO_HTTPS = 497; // Nginx +static constexpr int TOKEN_INVALID = 498; // Esri +static constexpr int CLIENT_CLOSED_REQUEST = 499; // Nginx +static constexpr int TOKEN_REQUIRED = 499; // Esri + +/** Server Error (5xx) */ +static constexpr int INTERNAL_SERVER_ERROR = 500; +static constexpr int NOT_IMPLEMENTED = 501; +static constexpr int BAD_GATEWAY = 502; +static constexpr int SERVICE_UNAVAIABLE = 503; +static constexpr int GATEWAY_TIMEOUT = 504; +static constexpr int HTTP_VERSION_NOT_SUPPORTED = 505; +static constexpr int VARIANT_ALSO_NEGOTIATES = 506; // RFC 2295 +static constexpr int INSUFFICIENT_STORAGE = 507; // RFC 4918 +static constexpr int LOOP_DETECTED = 508; // RFC 5842 +static constexpr int BANDWIDTH_LIMIT_EXCEEDED = 509; // Apache +static constexpr int NOT_EXTENDED = 510; // RFC 2774 +static constexpr int NETWORK_AUTHENTICATION_REQUIRED = 511; // RFC 6585 +static constexpr int UNKNOWN_ERROR = 520; // Non-RFC +static constexpr int ORIGIN_CONNECTION_TIMEOUT = 522; // CloudFlare +static constexpr int NETWORK_READ_TIMEOUT = 598; // Microsoft +static constexpr int NETWORK_CONNECTION_TIMEOUT = 599; // Microsoft + +} // namespace Status + +/** +* @brief Content-type field values +*/ +namespace Content { + +/** +* @brief Content-Language values +* TODO: Implement all ISO 639-1 translations +*/ +namespace Language { + +static constexpr std::string_view ENGLISH = "en"; +static constexpr std::string_view FRENCH = "fr"; +static constexpr std::string_view GERMAN = "gr"; +static constexpr std::string_view RUSSIAN = "ru"; +static constexpr std::string_view JAPANESE = "ja"; +static constexpr std::string_view CHINESE = "zh"; + +} // namespace Language + +/** +* @brief Content-Type values +* Note: This is not an exhaustive/exclusive list of values +*/ +namespace Type { + +namespace Text { + +static constexpr std::string_view HTML = "text/html"; +static constexpr std::string_view PLAIN = "text/plain"; + +namespace Charset { + +static constexpr std::string_view ASCII = "ascii"; +static constexpr std::string_view UTF8 = "utf-8"; + +} // namespace Charset + +} // namespace Text + +namespace Application { +static constexpr std::string_view OCTET_STREAM = "application/octet-stream"; +} // namespace Application + +} // namespace Type +} // namespace Content +} // namespace HTTP +} // namespace Jupiter #endif // _HTTP_H_HEADER \ No newline at end of file diff --git a/src/include/Jupiter/HTTP_QueryString.h b/src/include/Jupiter/HTTP_QueryString.h deleted file mode 100644 index 4dc61b0..0000000 --- a/src/include/Jupiter/HTTP_QueryString.h +++ /dev/null @@ -1,177 +0,0 @@ -/** - * Copyright (C) 2016 Jessica James. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Written by Jessica James - */ - -#if !defined _HTTP_QUERYSTRING_H_HEADER -#define _HTTP_QUERYSTRING_H_HEADER - -#include -#include - -/** - * @file HTTP_QueryString.h - * @brief Provides parsing for HTTP Query Strings. - */ - -namespace Jupiter -{ - namespace HTTP - { - /** - * @brief Provides parsing for HTML form responses. - * Note: This is essentially the same thing as QueryString, except key/value pairs are pared into 'table'. - */ - class HTMLFormResponse - { - public: - HTMLFormResponse() = delete; - inline HTMLFormResponse(std::string_view query_string) : HTMLFormResponse(query_string.data(), query_string.size()) {} - inline HTMLFormResponse(const char *ptr, size_t str_size); - using TableType = std::unordered_map; -#ifdef __cpp_lib_generic_unordered_lookup - using InKeyType = std::string_view; -#else // We can't use std::string_view for InKeyType until GCC 11 & clang 12, and I still want to support GCC 9 - using InKeyType = const std::string&; - - template - CastT tableGetCast(std::string_view in_key, const CastT &in_value) const { - return tableGetCast(static_cast(in_key), in_value); - } - - std::string_view tableGet(std::string_view in_key, std::string_view in_value) const { - return tableGet(static_cast(in_key), in_value); - } -#endif // __cpp_lib_generic_unordered_lookup - - template - CastT tableGetCast(InKeyType in_key, const CastT &in_value) const { - CastT result = in_value; - auto item = table.find(in_key); - if (item != table.end()) { - std::from_chars(item->second.data(), item->second.data() + item->second.size(), result); - return result; - } - - return result; - } - - auto tableFind(InKeyType in_key) const { - return table.find(in_key); - } - -#ifndef __cpp_lib_generic_unordered_lookup - auto tableFind(std::string_view in_key) const { - return tableFind(static_cast(in_key)); - } -#endif // __cpp_lib_generic_unordered_lookup - - std::string_view tableGet(InKeyType in_key, std::string_view in_value) const { - auto item = table.find(in_key); - if (item != table.end()) { - return item->second; - } - - return in_value; - } - - TableType table; - std::string m_parsed; - }; - } -} - -/** Implementation */ - -inline Jupiter::HTTP::HTMLFormResponse::HTMLFormResponse(const char *ptr, size_t str_size) { - std::string_view in_view{ ptr, str_size }; - if (str_size < 3) { // not enough room for "%XX", therefore no escaped characters to parse - m_parsed = in_view; - return; - } - m_parsed.resize(in_view.size()); - - const char *end = ptr + str_size - 2; - char* buf = m_parsed.data(); - const char *token_start = buf; - int val; - std::string key; - - while (ptr != end) - { - if (*ptr == '%') - { - if ((val = Jupiter_getHex(*++ptr)) != -1) - { - *buf = static_cast(val) << 4; - if ((val = Jupiter_getHex(*++ptr)) != -1) - *buf |= val; - - ++buf, ++ptr; - if (ptr > end) - { - if (ptr == end + 1) // copy 1 remaining character - { - *buf = *ptr; - ++buf; - } - m_parsed.erase(buf - m_parsed.data()); - return; - } - } - } - else if (*ptr == '&') // End of key/value, start of key - { - if (!key.empty()) { // A key was already set; end of value - Jupiter::HTTP::HTMLFormResponse::table[key] = std::string_view(token_start, buf - token_start); - } - - key = std::string_view{}; - ++buf, ++ptr; - token_start = buf; - } - else if (*ptr == '=') // End of key, start of value - { - key = std::string_view(token_start, buf - token_start); - ++buf, ++ptr; - token_start = buf; - } - else // Copy character - { - *buf = *ptr; - ++buf, ++ptr; - } - } - - // copy last 2 characters - *buf = *ptr; - - if (*buf == '=') // End of key, start of value - { - key = std::string_view(token_start, ++buf - token_start); - *buf = *++ptr; - Jupiter::HTTP::HTMLFormResponse::table[key] = std::string_view(ptr, 1); - } - else - *++buf = *++ptr; - - if (!key.empty()) // A key was already set; end of value - Jupiter::HTTP::HTMLFormResponse::table[key] = std::string_view(token_start, buf - token_start + 1); - - m_parsed.erase(buf + 1 - m_parsed.data()); // TODO: double check where this +1 came from? actually just replace this -} - -#endif // _HTTP_QUERYSTRING_H_HEADER \ No newline at end of file diff --git a/src/jessilib b/src/jessilib index 8d3efe0..ea14492 160000 --- a/src/jessilib +++ b/src/jessilib @@ -1 +1 @@ -Subproject commit 8d3efe083522c94a0dcfd31f34a07130b824f215 +Subproject commit ea14492235d22bad37de6612850b2fef322ba119