| 1 | // Copyright (c) 2020 Justin E. Jones. All rights reserved. |
| 2 | // Use of this source code is governed by an MIT license |
| 3 | // that can be found in the LICENSE file. |
| 4 | module http |
| 5 | |
| 6 | // The status codes listed here are based on the comprehensive list, |
| 7 | // available at: |
| 8 | // https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml |
| 9 | pub enum Status { |
| 10 | unknown = -1 |
| 11 | unassigned = 0 |
| 12 | cont = 100 |
| 13 | switching_protocols = 101 |
| 14 | processing = 102 |
| 15 | checkpoint_draft = 103 |
| 16 | ok = 200 |
| 17 | created = 201 |
| 18 | accepted = 202 |
| 19 | non_authoritative_information = 203 |
| 20 | no_content = 204 |
| 21 | reset_content = 205 |
| 22 | partial_content = 206 |
| 23 | multi_status = 207 |
| 24 | already_reported = 208 |
| 25 | im_used = 226 |
| 26 | multiple_choices = 300 |
| 27 | moved_permanently = 301 |
| 28 | found = 302 |
| 29 | see_other = 303 |
| 30 | not_modified = 304 |
| 31 | use_proxy = 305 |
| 32 | switch_proxy = 306 |
| 33 | temporary_redirect = 307 |
| 34 | permanent_redirect = 308 |
| 35 | bad_request = 400 |
| 36 | unauthorized = 401 |
| 37 | payment_required = 402 |
| 38 | forbidden = 403 |
| 39 | not_found = 404 |
| 40 | method_not_allowed = 405 |
| 41 | not_acceptable = 406 |
| 42 | proxy_authentication_required = 407 |
| 43 | request_timeout = 408 |
| 44 | conflict = 409 |
| 45 | gone = 410 |
| 46 | length_required = 411 |
| 47 | precondition_failed = 412 |
| 48 | request_entity_too_large = 413 |
| 49 | request_uri_too_long = 414 |
| 50 | unsupported_media_type = 415 |
| 51 | requested_range_not_satisfiable = 416 |
| 52 | expectation_failed = 417 |
| 53 | im_a_teapot = 418 |
| 54 | misdirected_request = 421 |
| 55 | unprocessable_entity = 422 |
| 56 | locked = 423 |
| 57 | failed_dependency = 424 |
| 58 | unordered_collection = 425 |
| 59 | upgrade_required = 426 |
| 60 | precondition_required = 428 |
| 61 | too_many_requests = 429 |
| 62 | request_header_fields_too_large = 431 |
| 63 | unavailable_for_legal_reasons = 451 |
| 64 | client_closed_request = 499 |
| 65 | internal_server_error = 500 |
| 66 | not_implemented = 501 |
| 67 | bad_gateway = 502 |
| 68 | service_unavailable = 503 |
| 69 | gateway_timeout = 504 |
| 70 | http_version_not_supported = 505 |
| 71 | variant_also_negotiates = 506 |
| 72 | insufficient_storage = 507 |
| 73 | loop_detected = 508 |
| 74 | bandwidth_limit_exceeded = 509 |
| 75 | not_extended = 510 |
| 76 | network_authentication_required = 511 |
| 77 | } |
| 78 | |
| 79 | // status_from_int returns the corresponding enum field of Status |
| 80 | // given the `code` in integer value. |
| 81 | pub fn status_from_int(code int) Status { |
| 82 | return match code { |
| 83 | 100 { Status.cont } |
| 84 | 101 { Status.switching_protocols } |
| 85 | 102 { Status.processing } |
| 86 | 103 { Status.checkpoint_draft } |
| 87 | 104...199 { Status.unassigned } |
| 88 | 200 { Status.ok } |
| 89 | 201 { Status.created } |
| 90 | 202 { Status.accepted } |
| 91 | 203 { Status.non_authoritative_information } |
| 92 | 204 { Status.no_content } |
| 93 | 205 { Status.reset_content } |
| 94 | 206 { Status.partial_content } |
| 95 | 207 { Status.multi_status } |
| 96 | 208 { Status.already_reported } |
| 97 | 209...225 { Status.unassigned } |
| 98 | 226 { Status.im_used } |
| 99 | 227...299 { Status.unassigned } |
| 100 | 300 { Status.multiple_choices } |
| 101 | 301 { Status.moved_permanently } |
| 102 | 302 { Status.found } |
| 103 | 303 { Status.see_other } |
| 104 | 304 { Status.not_modified } |
| 105 | 305 { Status.use_proxy } |
| 106 | 306 { Status.switch_proxy } |
| 107 | 307 { Status.temporary_redirect } |
| 108 | 308 { Status.permanent_redirect } |
| 109 | 309...399 { Status.unassigned } |
| 110 | 400 { Status.bad_request } |
| 111 | 401 { Status.unauthorized } |
| 112 | 402 { Status.payment_required } |
| 113 | 403 { Status.forbidden } |
| 114 | 404 { Status.not_found } |
| 115 | 405 { Status.method_not_allowed } |
| 116 | 406 { Status.not_acceptable } |
| 117 | 407 { Status.proxy_authentication_required } |
| 118 | 408 { Status.request_timeout } |
| 119 | 409 { Status.conflict } |
| 120 | 410 { Status.gone } |
| 121 | 411 { Status.length_required } |
| 122 | 412 { Status.precondition_failed } |
| 123 | 413 { Status.request_entity_too_large } |
| 124 | 414 { Status.request_uri_too_long } |
| 125 | 415 { Status.unsupported_media_type } |
| 126 | 416 { Status.requested_range_not_satisfiable } |
| 127 | 417 { Status.expectation_failed } |
| 128 | 418 { Status.im_a_teapot } |
| 129 | 419...420 { Status.unassigned } |
| 130 | 421 { Status.misdirected_request } |
| 131 | 422 { Status.unprocessable_entity } |
| 132 | 423 { Status.locked } |
| 133 | 424 { Status.failed_dependency } |
| 134 | 425 { Status.unordered_collection } |
| 135 | 426 { Status.upgrade_required } |
| 136 | 428 { Status.precondition_required } |
| 137 | 429 { Status.too_many_requests } |
| 138 | 431 { Status.request_header_fields_too_large } |
| 139 | 432...450 { Status.unassigned } |
| 140 | 451 { Status.unavailable_for_legal_reasons } |
| 141 | 452...499 { Status.unassigned } |
| 142 | 500 { Status.internal_server_error } |
| 143 | 501 { Status.not_implemented } |
| 144 | 502 { Status.bad_gateway } |
| 145 | 503 { Status.service_unavailable } |
| 146 | 504 { Status.gateway_timeout } |
| 147 | 505 { Status.http_version_not_supported } |
| 148 | 506 { Status.variant_also_negotiates } |
| 149 | 507 { Status.insufficient_storage } |
| 150 | 508 { Status.loop_detected } |
| 151 | 509 { Status.bandwidth_limit_exceeded } |
| 152 | 510 { Status.not_extended } |
| 153 | 511 { Status.network_authentication_required } |
| 154 | 512...599 { Status.unassigned } |
| 155 | else { Status.unknown } |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | // str returns the string representation of Status `code`. |
| 160 | pub fn (code Status) str() string { |
| 161 | return match code { |
| 162 | .cont { 'Continue' } |
| 163 | .switching_protocols { 'Switching Protocols' } |
| 164 | .processing { 'Processing' } |
| 165 | .checkpoint_draft { 'Checkpoint Draft' } |
| 166 | .ok { 'OK' } |
| 167 | .created { 'Created' } |
| 168 | .accepted { 'Accepted' } |
| 169 | .non_authoritative_information { 'Non Authoritative Information' } |
| 170 | .no_content { 'No Content' } |
| 171 | .reset_content { 'Reset Content' } |
| 172 | .partial_content { 'Partial Content' } |
| 173 | .multi_status { 'Multi Status' } |
| 174 | .already_reported { 'Already Reported' } |
| 175 | .im_used { 'IM Used' } |
| 176 | .multiple_choices { 'Multiple Choices' } |
| 177 | .moved_permanently { 'Moved Permanently' } |
| 178 | .found { 'Found' } |
| 179 | .see_other { 'See Other' } |
| 180 | .not_modified { 'Not Modified' } |
| 181 | .use_proxy { 'Use Proxy' } |
| 182 | .switch_proxy { 'Switch Proxy' } |
| 183 | .temporary_redirect { 'Temporary Redirect' } |
| 184 | .permanent_redirect { 'Permanent Redirect' } |
| 185 | .bad_request { 'Bad Request' } |
| 186 | .unauthorized { 'Unauthorized' } |
| 187 | .payment_required { 'Payment Required' } |
| 188 | .forbidden { 'Forbidden' } |
| 189 | .not_found { 'Not Found' } |
| 190 | .method_not_allowed { 'Method Not Allowed' } |
| 191 | .not_acceptable { 'Not Acceptable' } |
| 192 | .proxy_authentication_required { 'Proxy Authentication Required' } |
| 193 | .request_timeout { 'Request Timeout' } |
| 194 | .conflict { 'Conflict' } |
| 195 | .gone { 'Gone' } |
| 196 | .length_required { 'Length Required' } |
| 197 | .precondition_failed { 'Precondition Failed' } |
| 198 | .request_entity_too_large { 'Request Entity Too Large' } |
| 199 | .request_uri_too_long { 'Request URI Too Long' } |
| 200 | .unsupported_media_type { 'Unsupported Media Type' } |
| 201 | .requested_range_not_satisfiable { 'Requested Range Not Satisfiable' } |
| 202 | .expectation_failed { 'Expectation Failed' } |
| 203 | .im_a_teapot { 'Im a teapot' } |
| 204 | .misdirected_request { 'Misdirected Request' } |
| 205 | .unprocessable_entity { 'Unprocessable Entity' } |
| 206 | .locked { 'Locked' } |
| 207 | .failed_dependency { 'Failed Dependency' } |
| 208 | .unordered_collection { 'Unordered Collection' } |
| 209 | .upgrade_required { 'Upgrade Required' } |
| 210 | .precondition_required { 'Precondition Required' } |
| 211 | .too_many_requests { 'Too Many Requests' } |
| 212 | .request_header_fields_too_large { 'Request Header Fields Too Large' } |
| 213 | .unavailable_for_legal_reasons { 'Unavailable For Legal Reasons' } |
| 214 | .internal_server_error { 'Internal Server Error' } |
| 215 | .not_implemented { 'Not Implemented' } |
| 216 | .bad_gateway { 'Bad Gateway' } |
| 217 | .service_unavailable { 'Service Unavailable' } |
| 218 | .gateway_timeout { 'Gateway Timeout' } |
| 219 | .http_version_not_supported { 'HTTP Version Not Supported' } |
| 220 | .variant_also_negotiates { 'Variant Also Negotiates' } |
| 221 | .insufficient_storage { 'Insufficient Storage' } |
| 222 | .loop_detected { 'Loop Detected' } |
| 223 | .bandwidth_limit_exceeded { 'Bandwidth Limit Exceeded' } |
| 224 | .not_extended { 'Not Extended' } |
| 225 | .network_authentication_required { 'Network Authentication Required' } |
| 226 | .unassigned { 'Unassigned' } |
| 227 | else { 'Unknown' } |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | // int converts an assigned and known Status to its integral equivalent. |
| 232 | // if a Status is unknown or unassigned, this method will return zero |
| 233 | pub fn (code Status) int() int { |
| 234 | if code in [.unknown, .unassigned] { |
| 235 | return 0 |
| 236 | } |
| 237 | return int(code) |
| 238 | } |
| 239 | |
| 240 | // is_valid returns true if the status code is assigned and known |
| 241 | pub fn (code Status) is_valid() bool { |
| 242 | number := code.int() |
| 243 | return number >= 100 && number < 600 |
| 244 | } |
| 245 | |
| 246 | // is_error will return true if the status code represents either a client or |
| 247 | // a server error; otherwise will return false |
| 248 | pub fn (code Status) is_error() bool { |
| 249 | number := code.int() |
| 250 | return number >= 400 && number < 600 |
| 251 | } |
| 252 | |
| 253 | // is_success will return true if the status code represents either an |
| 254 | // informational, success, or redirection response; otherwise will return false |
| 255 | pub fn (code Status) is_success() bool { |
| 256 | number := code.int() |
| 257 | return number >= 100 && number < 400 |
| 258 | } |
| 259 | |