1 #ifndef SIMPLE_WEB_STATUS_CODE_HPP 2 #define SIMPLE_WEB_STATUS_CODE_HPP 3 4 #include <cstdlib> 5 #include <map> 6 #include <string> 7 #include <unordered_map> 8 #include <vector> 9 10 namespace SimpleWeb { 11 enum class StatusCode { 12 unknown = 0, 13 information_continue = 100, 14 information_switching_protocols, 15 information_processing, 16 success_ok = 200, 17 success_created, 18 success_accepted, 19 success_non_authoritative_information, 20 success_no_content, 21 success_reset_content, 22 success_partial_content, 23 success_multi_status, 24 success_already_reported, 25 success_im_used = 226, 26 redirection_multiple_choices = 300, 27 redirection_moved_permanently, 28 redirection_found, 29 redirection_see_other, 30 redirection_not_modified, 31 redirection_use_proxy, 32 redirection_switch_proxy, 33 redirection_temporary_redirect, 34 redirection_permanent_redirect, 35 client_error_bad_request = 400, 36 client_error_unauthorized, 37 client_error_payment_required, 38 client_error_forbidden, 39 client_error_not_found, 40 client_error_method_not_allowed, 41 client_error_not_acceptable, 42 client_error_proxy_authentication_required, 43 client_error_request_timeout, 44 client_error_conflict, 45 client_error_gone, 46 client_error_length_required, 47 client_error_precondition_failed, 48 client_error_payload_too_large, 49 client_error_uri_too_long, 50 client_error_unsupported_media_type, 51 client_error_range_not_satisfiable, 52 client_error_expectation_failed, 53 client_error_im_a_teapot, 54 client_error_misdirection_required = 421, 55 client_error_unprocessable_entity, 56 client_error_locked, 57 client_error_failed_dependency, 58 client_error_upgrade_required = 426, 59 client_error_precondition_required = 428, 60 client_error_too_many_requests, 61 client_error_request_header_fields_too_large = 431, 62 client_error_unavailable_for_legal_reasons = 451, 63 server_error_internal_server_error = 500, 64 server_error_not_implemented, 65 server_error_bad_gateway, 66 server_error_service_unavailable, 67 server_error_gateway_timeout, 68 server_error_http_version_not_supported, 69 server_error_variant_also_negotiates, 70 server_error_insufficient_storage, 71 server_error_loop_detected, 72 server_error_not_extended = 510, 73 server_error_network_authentication_required 74 }; 75 status_code_strings()76 inline const std::map<StatusCode, std::string> &status_code_strings() { 77 static const std::map<StatusCode, std::string> status_code_strings = { 78 {StatusCode::unknown, ""}, 79 {StatusCode::information_continue, "100 Continue"}, 80 {StatusCode::information_switching_protocols, "101 Switching Protocols"}, 81 {StatusCode::information_processing, "102 Processing"}, 82 {StatusCode::success_ok, "200 OK"}, 83 {StatusCode::success_created, "201 Created"}, 84 {StatusCode::success_accepted, "202 Accepted"}, 85 {StatusCode::success_non_authoritative_information, "203 Non-Authoritative Information"}, 86 {StatusCode::success_no_content, "204 No Content"}, 87 {StatusCode::success_reset_content, "205 Reset Content"}, 88 {StatusCode::success_partial_content, "206 Partial Content"}, 89 {StatusCode::success_multi_status, "207 Multi-Status"}, 90 {StatusCode::success_already_reported, "208 Already Reported"}, 91 {StatusCode::success_im_used, "226 IM Used"}, 92 {StatusCode::redirection_multiple_choices, "300 Multiple Choices"}, 93 {StatusCode::redirection_moved_permanently, "301 Moved Permanently"}, 94 {StatusCode::redirection_found, "302 Found"}, 95 {StatusCode::redirection_see_other, "303 See Other"}, 96 {StatusCode::redirection_not_modified, "304 Not Modified"}, 97 {StatusCode::redirection_use_proxy, "305 Use Proxy"}, 98 {StatusCode::redirection_switch_proxy, "306 Switch Proxy"}, 99 {StatusCode::redirection_temporary_redirect, "307 Temporary Redirect"}, 100 {StatusCode::redirection_permanent_redirect, "308 Permanent Redirect"}, 101 {StatusCode::client_error_bad_request, "400 Bad Request"}, 102 {StatusCode::client_error_unauthorized, "401 Unauthorized"}, 103 {StatusCode::client_error_payment_required, "402 Payment Required"}, 104 {StatusCode::client_error_forbidden, "403 Forbidden"}, 105 {StatusCode::client_error_not_found, "404 Not Found"}, 106 {StatusCode::client_error_method_not_allowed, "405 Method Not Allowed"}, 107 {StatusCode::client_error_not_acceptable, "406 Not Acceptable"}, 108 {StatusCode::client_error_proxy_authentication_required, "407 Proxy Authentication Required"}, 109 {StatusCode::client_error_request_timeout, "408 Request Timeout"}, 110 {StatusCode::client_error_conflict, "409 Conflict"}, 111 {StatusCode::client_error_gone, "410 Gone"}, 112 {StatusCode::client_error_length_required, "411 Length Required"}, 113 {StatusCode::client_error_precondition_failed, "412 Precondition Failed"}, 114 {StatusCode::client_error_payload_too_large, "413 Payload Too Large"}, 115 {StatusCode::client_error_uri_too_long, "414 URI Too Long"}, 116 {StatusCode::client_error_unsupported_media_type, "415 Unsupported Media Type"}, 117 {StatusCode::client_error_range_not_satisfiable, "416 Range Not Satisfiable"}, 118 {StatusCode::client_error_expectation_failed, "417 Expectation Failed"}, 119 {StatusCode::client_error_im_a_teapot, "418 I'm a teapot"}, 120 {StatusCode::client_error_misdirection_required, "421 Misdirected Request"}, 121 {StatusCode::client_error_unprocessable_entity, "422 Unprocessable Entity"}, 122 {StatusCode::client_error_locked, "423 Locked"}, 123 {StatusCode::client_error_failed_dependency, "424 Failed Dependency"}, 124 {StatusCode::client_error_upgrade_required, "426 Upgrade Required"}, 125 {StatusCode::client_error_precondition_required, "428 Precondition Required"}, 126 {StatusCode::client_error_too_many_requests, "429 Too Many Requests"}, 127 {StatusCode::client_error_request_header_fields_too_large, "431 Request Header Fields Too Large"}, 128 {StatusCode::client_error_unavailable_for_legal_reasons, "451 Unavailable For Legal Reasons"}, 129 {StatusCode::server_error_internal_server_error, "500 Internal Server Error"}, 130 {StatusCode::server_error_not_implemented, "501 Not Implemented"}, 131 {StatusCode::server_error_bad_gateway, "502 Bad Gateway"}, 132 {StatusCode::server_error_service_unavailable, "503 Service Unavailable"}, 133 {StatusCode::server_error_gateway_timeout, "504 Gateway Timeout"}, 134 {StatusCode::server_error_http_version_not_supported, "505 HTTP Version Not Supported"}, 135 {StatusCode::server_error_variant_also_negotiates, "506 Variant Also Negotiates"}, 136 {StatusCode::server_error_insufficient_storage, "507 Insufficient Storage"}, 137 {StatusCode::server_error_loop_detected, "508 Loop Detected"}, 138 {StatusCode::server_error_not_extended, "510 Not Extended"}, 139 {StatusCode::server_error_network_authentication_required, "511 Network Authentication Required"}}; 140 return status_code_strings; 141 } 142 status_code(const std::string & status_code_string)143 inline StatusCode status_code(const std::string &status_code_string) noexcept { 144 if(status_code_string.size() < 3) 145 return StatusCode::unknown; 146 147 auto number = status_code_string.substr(0, 3); 148 if(number[0] < '0' || number[0] > '9' || number[1] < '0' || number[1] > '9' || number[2] < '0' || number[2] > '9') 149 return StatusCode::unknown; 150 151 class StringToStatusCode : public std::unordered_map<std::string, SimpleWeb::StatusCode> { 152 public: 153 StringToStatusCode() { 154 for(auto &status_code : status_code_strings()) 155 emplace(status_code.second.substr(0, 3), status_code.first); 156 } 157 }; 158 static StringToStatusCode string_to_status_code; 159 160 auto pos = string_to_status_code.find(number); 161 if(pos == string_to_status_code.end()) 162 return static_cast<StatusCode>(atoi(number.c_str())); 163 return pos->second; 164 } 165 status_code(StatusCode status_code_enum)166 inline const std::string &status_code(StatusCode status_code_enum) noexcept { 167 auto pos = status_code_strings().find(status_code_enum); 168 if(pos == status_code_strings().end()) { 169 static std::string empty_string; 170 return empty_string; 171 } 172 return pos->second; 173 } 174 } // namespace SimpleWeb 175 176 #endif // SIMPLE_WEB_STATUS_CODE_HPP 177