You've already forked cpp-httplib
Refactoring
This commit is contained in:
368
httplib.h
368
httplib.h
@@ -1015,6 +1015,10 @@ void default_socket_options(socket_t sock);
|
||||
|
||||
const char *status_message(int status);
|
||||
|
||||
std::string to_string(Error error);
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const Error &obj);
|
||||
|
||||
std::string get_bearer_token_auth(const Request &req);
|
||||
|
||||
namespace detail {
|
||||
@@ -2307,82 +2311,6 @@ inline void default_socket_options(socket_t sock) {
|
||||
1);
|
||||
}
|
||||
|
||||
inline const char *status_message(int status) {
|
||||
switch (status) {
|
||||
case StatusCode::Continue_100: return "Continue";
|
||||
case StatusCode::SwitchingProtocol_101: return "Switching Protocol";
|
||||
case StatusCode::Processing_102: return "Processing";
|
||||
case StatusCode::EarlyHints_103: return "Early Hints";
|
||||
case StatusCode::OK_200: return "OK";
|
||||
case StatusCode::Created_201: return "Created";
|
||||
case StatusCode::Accepted_202: return "Accepted";
|
||||
case StatusCode::NonAuthoritativeInformation_203:
|
||||
return "Non-Authoritative Information";
|
||||
case StatusCode::NoContent_204: return "No Content";
|
||||
case StatusCode::ResetContent_205: return "Reset Content";
|
||||
case StatusCode::PartialContent_206: return "Partial Content";
|
||||
case StatusCode::MultiStatus_207: return "Multi-Status";
|
||||
case StatusCode::AlreadyReported_208: return "Already Reported";
|
||||
case StatusCode::IMUsed_226: return "IM Used";
|
||||
case StatusCode::MultipleChoices_300: return "Multiple Choices";
|
||||
case StatusCode::MovedPermanently_301: return "Moved Permanently";
|
||||
case StatusCode::Found_302: return "Found";
|
||||
case StatusCode::SeeOther_303: return "See Other";
|
||||
case StatusCode::NotModified_304: return "Not Modified";
|
||||
case StatusCode::UseProxy_305: return "Use Proxy";
|
||||
case StatusCode::unused_306: return "unused";
|
||||
case StatusCode::TemporaryRedirect_307: return "Temporary Redirect";
|
||||
case StatusCode::PermanentRedirect_308: return "Permanent Redirect";
|
||||
case StatusCode::BadRequest_400: return "Bad Request";
|
||||
case StatusCode::Unauthorized_401: return "Unauthorized";
|
||||
case StatusCode::PaymentRequired_402: return "Payment Required";
|
||||
case StatusCode::Forbidden_403: return "Forbidden";
|
||||
case StatusCode::NotFound_404: return "Not Found";
|
||||
case StatusCode::MethodNotAllowed_405: return "Method Not Allowed";
|
||||
case StatusCode::NotAcceptable_406: return "Not Acceptable";
|
||||
case StatusCode::ProxyAuthenticationRequired_407:
|
||||
return "Proxy Authentication Required";
|
||||
case StatusCode::RequestTimeout_408: return "Request Timeout";
|
||||
case StatusCode::Conflict_409: return "Conflict";
|
||||
case StatusCode::Gone_410: return "Gone";
|
||||
case StatusCode::LengthRequired_411: return "Length Required";
|
||||
case StatusCode::PreconditionFailed_412: return "Precondition Failed";
|
||||
case StatusCode::PayloadTooLarge_413: return "Payload Too Large";
|
||||
case StatusCode::UriTooLong_414: return "URI Too Long";
|
||||
case StatusCode::UnsupportedMediaType_415: return "Unsupported Media Type";
|
||||
case StatusCode::RangeNotSatisfiable_416: return "Range Not Satisfiable";
|
||||
case StatusCode::ExpectationFailed_417: return "Expectation Failed";
|
||||
case StatusCode::ImATeapot_418: return "I'm a teapot";
|
||||
case StatusCode::MisdirectedRequest_421: return "Misdirected Request";
|
||||
case StatusCode::UnprocessableContent_422: return "Unprocessable Content";
|
||||
case StatusCode::Locked_423: return "Locked";
|
||||
case StatusCode::FailedDependency_424: return "Failed Dependency";
|
||||
case StatusCode::TooEarly_425: return "Too Early";
|
||||
case StatusCode::UpgradeRequired_426: return "Upgrade Required";
|
||||
case StatusCode::PreconditionRequired_428: return "Precondition Required";
|
||||
case StatusCode::TooManyRequests_429: return "Too Many Requests";
|
||||
case StatusCode::RequestHeaderFieldsTooLarge_431:
|
||||
return "Request Header Fields Too Large";
|
||||
case StatusCode::UnavailableForLegalReasons_451:
|
||||
return "Unavailable For Legal Reasons";
|
||||
case StatusCode::NotImplemented_501: return "Not Implemented";
|
||||
case StatusCode::BadGateway_502: return "Bad Gateway";
|
||||
case StatusCode::ServiceUnavailable_503: return "Service Unavailable";
|
||||
case StatusCode::GatewayTimeout_504: return "Gateway Timeout";
|
||||
case StatusCode::HttpVersionNotSupported_505:
|
||||
return "HTTP Version Not Supported";
|
||||
case StatusCode::VariantAlsoNegotiates_506: return "Variant Also Negotiates";
|
||||
case StatusCode::InsufficientStorage_507: return "Insufficient Storage";
|
||||
case StatusCode::LoopDetected_508: return "Loop Detected";
|
||||
case StatusCode::NotExtended_510: return "Not Extended";
|
||||
case StatusCode::NetworkAuthenticationRequired_511:
|
||||
return "Network Authentication Required";
|
||||
|
||||
default:
|
||||
case StatusCode::InternalServerError_500: return "Internal Server Error";
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string get_bearer_token_auth(const Request &req) {
|
||||
if (req.has_header("Authorization")) {
|
||||
constexpr auto bearer_header_prefix_len = detail::str_len("Bearer ");
|
||||
@@ -2416,57 +2344,6 @@ Server::set_idle_interval(const std::chrono::duration<Rep, Period> &duration) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline std::string to_string(const Error error) {
|
||||
switch (error) {
|
||||
case Error::Success: return "Success (no error)";
|
||||
case Error::Unknown: return "Unknown";
|
||||
case Error::Connection: return "Could not establish connection";
|
||||
case Error::BindIPAddress: return "Failed to bind IP address";
|
||||
case Error::Read: return "Failed to read connection";
|
||||
case Error::Write: return "Failed to write connection";
|
||||
case Error::ExceedRedirectCount: return "Maximum redirect count exceeded";
|
||||
case Error::Canceled: return "Connection handling canceled";
|
||||
case Error::SSLConnection: return "SSL connection failed";
|
||||
case Error::SSLLoadingCerts: return "SSL certificate loading failed";
|
||||
case Error::SSLServerVerification: return "SSL server verification failed";
|
||||
case Error::SSLServerHostnameVerification:
|
||||
return "SSL server hostname verification failed";
|
||||
case Error::UnsupportedMultipartBoundaryChars:
|
||||
return "Unsupported HTTP multipart boundary characters";
|
||||
case Error::Compression: return "Compression failed";
|
||||
case Error::ConnectionTimeout: return "Connection timed out";
|
||||
case Error::ProxyConnection: return "Proxy connection failed";
|
||||
case Error::ConnectionClosed: return "Connection closed by server";
|
||||
case Error::Timeout: return "Read timeout";
|
||||
case Error::ResourceExhaustion: return "Resource exhaustion";
|
||||
case Error::TooManyFormDataFiles: return "Too many form data files";
|
||||
case Error::ExceedMaxPayloadSize: return "Exceeded maximum payload size";
|
||||
case Error::ExceedUriMaxLength: return "Exceeded maximum URI length";
|
||||
case Error::ExceedMaxSocketDescriptorCount:
|
||||
return "Exceeded maximum socket descriptor count";
|
||||
case Error::InvalidRequestLine: return "Invalid request line";
|
||||
case Error::InvalidHTTPMethod: return "Invalid HTTP method";
|
||||
case Error::InvalidHTTPVersion: return "Invalid HTTP version";
|
||||
case Error::InvalidHeaders: return "Invalid headers";
|
||||
case Error::MultipartParsing: return "Multipart parsing failed";
|
||||
case Error::OpenFile: return "Failed to open file";
|
||||
case Error::Listen: return "Failed to listen on socket";
|
||||
case Error::GetSockName: return "Failed to get socket name";
|
||||
case Error::UnsupportedAddressFamily: return "Unsupported address family";
|
||||
case Error::HTTPParsing: return "HTTP parsing failed";
|
||||
case Error::InvalidRangeHeader: return "Invalid Range header";
|
||||
default: break;
|
||||
}
|
||||
|
||||
return "Invalid";
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os, const Error &obj) {
|
||||
os << to_string(obj);
|
||||
os << " (" << static_cast<std::underlying_type<Error>::type>(obj) << ')';
|
||||
return os;
|
||||
}
|
||||
|
||||
inline size_t Result::get_request_header_value_u64(const std::string &key,
|
||||
size_t def,
|
||||
size_t id) const {
|
||||
@@ -2866,54 +2743,14 @@ private:
|
||||
// NOTE: https://www.rfc-editor.org/rfc/rfc9110#section-5
|
||||
namespace fields {
|
||||
|
||||
inline bool is_token_char(char c) {
|
||||
return std::isalnum(c) || c == '!' || c == '#' || c == '$' || c == '%' ||
|
||||
c == '&' || c == '\'' || c == '*' || c == '+' || c == '-' ||
|
||||
c == '.' || c == '^' || c == '_' || c == '`' || c == '|' || c == '~';
|
||||
}
|
||||
|
||||
inline bool is_token(const std::string &s) {
|
||||
if (s.empty()) { return false; }
|
||||
for (auto c : s) {
|
||||
if (!is_token_char(c)) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool is_field_name(const std::string &s) { return is_token(s); }
|
||||
|
||||
inline bool is_vchar(char c) { return c >= 33 && c <= 126; }
|
||||
|
||||
inline bool is_obs_text(char c) { return 128 <= static_cast<unsigned char>(c); }
|
||||
|
||||
inline bool is_field_vchar(char c) { return is_vchar(c) || is_obs_text(c); }
|
||||
|
||||
inline bool is_field_content(const std::string &s) {
|
||||
if (s.empty()) { return true; }
|
||||
|
||||
if (s.size() == 1) {
|
||||
return is_field_vchar(s[0]);
|
||||
} else if (s.size() == 2) {
|
||||
return is_field_vchar(s[0]) && is_field_vchar(s[1]);
|
||||
} else {
|
||||
size_t i = 0;
|
||||
|
||||
if (!is_field_vchar(s[i])) { return false; }
|
||||
i++;
|
||||
|
||||
while (i < s.size() - 1) {
|
||||
auto c = s[i++];
|
||||
if (c == ' ' || c == '\t' || is_field_vchar(c)) {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return is_field_vchar(s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool is_field_value(const std::string &s) { return is_field_content(s); }
|
||||
bool is_token_char(char c);
|
||||
bool is_token(const std::string &s);
|
||||
bool is_field_name(const std::string &s);
|
||||
bool is_vchar(char c);
|
||||
bool is_obs_text(char c);
|
||||
bool is_field_vchar(char c);
|
||||
bool is_field_content(const std::string &s);
|
||||
bool is_field_value(const std::string &s);
|
||||
|
||||
} // namespace fields
|
||||
|
||||
@@ -6845,8 +6682,189 @@ private:
|
||||
ContentProviderWithoutLength content_provider_;
|
||||
};
|
||||
|
||||
// NOTE: https://www.rfc-editor.org/rfc/rfc9110#section-5
|
||||
namespace fields {
|
||||
|
||||
inline bool is_token_char(char c) {
|
||||
return std::isalnum(c) || c == '!' || c == '#' || c == '$' || c == '%' ||
|
||||
c == '&' || c == '\'' || c == '*' || c == '+' || c == '-' ||
|
||||
c == '.' || c == '^' || c == '_' || c == '`' || c == '|' || c == '~';
|
||||
}
|
||||
|
||||
inline bool is_token(const std::string &s) {
|
||||
if (s.empty()) { return false; }
|
||||
for (auto c : s) {
|
||||
if (!is_token_char(c)) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool is_field_name(const std::string &s) { return is_token(s); }
|
||||
|
||||
inline bool is_vchar(char c) { return c >= 33 && c <= 126; }
|
||||
|
||||
inline bool is_obs_text(char c) { return 128 <= static_cast<unsigned char>(c); }
|
||||
|
||||
inline bool is_field_vchar(char c) { return is_vchar(c) || is_obs_text(c); }
|
||||
|
||||
inline bool is_field_content(const std::string &s) {
|
||||
if (s.empty()) { return true; }
|
||||
|
||||
if (s.size() == 1) {
|
||||
return is_field_vchar(s[0]);
|
||||
} else if (s.size() == 2) {
|
||||
return is_field_vchar(s[0]) && is_field_vchar(s[1]);
|
||||
} else {
|
||||
size_t i = 0;
|
||||
|
||||
if (!is_field_vchar(s[i])) { return false; }
|
||||
i++;
|
||||
|
||||
while (i < s.size() - 1) {
|
||||
auto c = s[i++];
|
||||
if (c == ' ' || c == '\t' || is_field_vchar(c)) {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return is_field_vchar(s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool is_field_value(const std::string &s) { return is_field_content(s); }
|
||||
|
||||
} // namespace fields
|
||||
|
||||
} // namespace detail
|
||||
|
||||
inline const char *status_message(int status) {
|
||||
switch (status) {
|
||||
case StatusCode::Continue_100: return "Continue";
|
||||
case StatusCode::SwitchingProtocol_101: return "Switching Protocol";
|
||||
case StatusCode::Processing_102: return "Processing";
|
||||
case StatusCode::EarlyHints_103: return "Early Hints";
|
||||
case StatusCode::OK_200: return "OK";
|
||||
case StatusCode::Created_201: return "Created";
|
||||
case StatusCode::Accepted_202: return "Accepted";
|
||||
case StatusCode::NonAuthoritativeInformation_203:
|
||||
return "Non-Authoritative Information";
|
||||
case StatusCode::NoContent_204: return "No Content";
|
||||
case StatusCode::ResetContent_205: return "Reset Content";
|
||||
case StatusCode::PartialContent_206: return "Partial Content";
|
||||
case StatusCode::MultiStatus_207: return "Multi-Status";
|
||||
case StatusCode::AlreadyReported_208: return "Already Reported";
|
||||
case StatusCode::IMUsed_226: return "IM Used";
|
||||
case StatusCode::MultipleChoices_300: return "Multiple Choices";
|
||||
case StatusCode::MovedPermanently_301: return "Moved Permanently";
|
||||
case StatusCode::Found_302: return "Found";
|
||||
case StatusCode::SeeOther_303: return "See Other";
|
||||
case StatusCode::NotModified_304: return "Not Modified";
|
||||
case StatusCode::UseProxy_305: return "Use Proxy";
|
||||
case StatusCode::unused_306: return "unused";
|
||||
case StatusCode::TemporaryRedirect_307: return "Temporary Redirect";
|
||||
case StatusCode::PermanentRedirect_308: return "Permanent Redirect";
|
||||
case StatusCode::BadRequest_400: return "Bad Request";
|
||||
case StatusCode::Unauthorized_401: return "Unauthorized";
|
||||
case StatusCode::PaymentRequired_402: return "Payment Required";
|
||||
case StatusCode::Forbidden_403: return "Forbidden";
|
||||
case StatusCode::NotFound_404: return "Not Found";
|
||||
case StatusCode::MethodNotAllowed_405: return "Method Not Allowed";
|
||||
case StatusCode::NotAcceptable_406: return "Not Acceptable";
|
||||
case StatusCode::ProxyAuthenticationRequired_407:
|
||||
return "Proxy Authentication Required";
|
||||
case StatusCode::RequestTimeout_408: return "Request Timeout";
|
||||
case StatusCode::Conflict_409: return "Conflict";
|
||||
case StatusCode::Gone_410: return "Gone";
|
||||
case StatusCode::LengthRequired_411: return "Length Required";
|
||||
case StatusCode::PreconditionFailed_412: return "Precondition Failed";
|
||||
case StatusCode::PayloadTooLarge_413: return "Payload Too Large";
|
||||
case StatusCode::UriTooLong_414: return "URI Too Long";
|
||||
case StatusCode::UnsupportedMediaType_415: return "Unsupported Media Type";
|
||||
case StatusCode::RangeNotSatisfiable_416: return "Range Not Satisfiable";
|
||||
case StatusCode::ExpectationFailed_417: return "Expectation Failed";
|
||||
case StatusCode::ImATeapot_418: return "I'm a teapot";
|
||||
case StatusCode::MisdirectedRequest_421: return "Misdirected Request";
|
||||
case StatusCode::UnprocessableContent_422: return "Unprocessable Content";
|
||||
case StatusCode::Locked_423: return "Locked";
|
||||
case StatusCode::FailedDependency_424: return "Failed Dependency";
|
||||
case StatusCode::TooEarly_425: return "Too Early";
|
||||
case StatusCode::UpgradeRequired_426: return "Upgrade Required";
|
||||
case StatusCode::PreconditionRequired_428: return "Precondition Required";
|
||||
case StatusCode::TooManyRequests_429: return "Too Many Requests";
|
||||
case StatusCode::RequestHeaderFieldsTooLarge_431:
|
||||
return "Request Header Fields Too Large";
|
||||
case StatusCode::UnavailableForLegalReasons_451:
|
||||
return "Unavailable For Legal Reasons";
|
||||
case StatusCode::NotImplemented_501: return "Not Implemented";
|
||||
case StatusCode::BadGateway_502: return "Bad Gateway";
|
||||
case StatusCode::ServiceUnavailable_503: return "Service Unavailable";
|
||||
case StatusCode::GatewayTimeout_504: return "Gateway Timeout";
|
||||
case StatusCode::HttpVersionNotSupported_505:
|
||||
return "HTTP Version Not Supported";
|
||||
case StatusCode::VariantAlsoNegotiates_506: return "Variant Also Negotiates";
|
||||
case StatusCode::InsufficientStorage_507: return "Insufficient Storage";
|
||||
case StatusCode::LoopDetected_508: return "Loop Detected";
|
||||
case StatusCode::NotExtended_510: return "Not Extended";
|
||||
case StatusCode::NetworkAuthenticationRequired_511:
|
||||
return "Network Authentication Required";
|
||||
|
||||
default:
|
||||
case StatusCode::InternalServerError_500: return "Internal Server Error";
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string to_string(const Error error) {
|
||||
switch (error) {
|
||||
case Error::Success: return "Success (no error)";
|
||||
case Error::Unknown: return "Unknown";
|
||||
case Error::Connection: return "Could not establish connection";
|
||||
case Error::BindIPAddress: return "Failed to bind IP address";
|
||||
case Error::Read: return "Failed to read connection";
|
||||
case Error::Write: return "Failed to write connection";
|
||||
case Error::ExceedRedirectCount: return "Maximum redirect count exceeded";
|
||||
case Error::Canceled: return "Connection handling canceled";
|
||||
case Error::SSLConnection: return "SSL connection failed";
|
||||
case Error::SSLLoadingCerts: return "SSL certificate loading failed";
|
||||
case Error::SSLServerVerification: return "SSL server verification failed";
|
||||
case Error::SSLServerHostnameVerification:
|
||||
return "SSL server hostname verification failed";
|
||||
case Error::UnsupportedMultipartBoundaryChars:
|
||||
return "Unsupported HTTP multipart boundary characters";
|
||||
case Error::Compression: return "Compression failed";
|
||||
case Error::ConnectionTimeout: return "Connection timed out";
|
||||
case Error::ProxyConnection: return "Proxy connection failed";
|
||||
case Error::ConnectionClosed: return "Connection closed by server";
|
||||
case Error::Timeout: return "Read timeout";
|
||||
case Error::ResourceExhaustion: return "Resource exhaustion";
|
||||
case Error::TooManyFormDataFiles: return "Too many form data files";
|
||||
case Error::ExceedMaxPayloadSize: return "Exceeded maximum payload size";
|
||||
case Error::ExceedUriMaxLength: return "Exceeded maximum URI length";
|
||||
case Error::ExceedMaxSocketDescriptorCount:
|
||||
return "Exceeded maximum socket descriptor count";
|
||||
case Error::InvalidRequestLine: return "Invalid request line";
|
||||
case Error::InvalidHTTPMethod: return "Invalid HTTP method";
|
||||
case Error::InvalidHTTPVersion: return "Invalid HTTP version";
|
||||
case Error::InvalidHeaders: return "Invalid headers";
|
||||
case Error::MultipartParsing: return "Multipart parsing failed";
|
||||
case Error::OpenFile: return "Failed to open file";
|
||||
case Error::Listen: return "Failed to listen on socket";
|
||||
case Error::GetSockName: return "Failed to get socket name";
|
||||
case Error::UnsupportedAddressFamily: return "Unsupported address family";
|
||||
case Error::HTTPParsing: return "HTTP parsing failed";
|
||||
case Error::InvalidRangeHeader: return "Invalid Range header";
|
||||
default: break;
|
||||
}
|
||||
|
||||
return "Invalid";
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os, const Error &obj) {
|
||||
os << to_string(obj);
|
||||
os << " (" << static_cast<std::underlying_type<Error>::type>(obj) << ')';
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::string hosted_at(const std::string &hostname) {
|
||||
std::vector<std::string> addrs;
|
||||
hosted_at(hostname, addrs);
|
||||
|
||||
Reference in New Issue
Block a user