| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 |
- /// A HTTP response status code.
- public enum HTTPResponseStatus {
- /* use custom if you want to use a non-standard response code or
- have it available in a (UInt, String) pair from a higher-level web framework. */
- case custom(code: UInt, reasonPhrase: String)
- /* all the codes from http://www.iana.org/assignments/http-status-codes */
- // 1xx
- case `continue`
- case switchingProtocols
- case processing
- // TODO: add '103: Early Hints' (requires bumping SemVer major).
- // 2xx
- case ok
- case created
- case accepted
- case nonAuthoritativeInformation
- case noContent
- case resetContent
- case partialContent
- case multiStatus
- case alreadyReported
- case imUsed
- // 3xx
- case multipleChoices
- case movedPermanently
- case found
- case seeOther
- case notModified
- case useProxy
- case temporaryRedirect
- case permanentRedirect
- // 4xx
- case badRequest
- case unauthorized
- case paymentRequired
- case forbidden
- case notFound
- case methodNotAllowed
- case notAcceptable
- case proxyAuthenticationRequired
- case requestTimeout
- case conflict
- case gone
- case lengthRequired
- case preconditionFailed
- case payloadTooLarge
- case uriTooLong
- case unsupportedMediaType
- case rangeNotSatisfiable
- case expectationFailed
- case imATeapot
- case misdirectedRequest
- case unprocessableEntity
- case locked
- case failedDependency
- case upgradeRequired
- case preconditionRequired
- case tooManyRequests
- case requestHeaderFieldsTooLarge
- case unavailableForLegalReasons
- // 5xx
- case internalServerError
- case notImplemented
- case badGateway
- case serviceUnavailable
- case gatewayTimeout
- case httpVersionNotSupported
- case variantAlsoNegotiates
- case insufficientStorage
- case loopDetected
- case notExtended
- case networkAuthenticationRequired
- /// Whether responses with this status code may have a response body.
- public var mayHaveResponseBody: Bool {
- switch self {
- case .continue,
- .switchingProtocols,
- .processing,
- .noContent,
- .custom where (code < 200) && (code >= 100):
- return false
- default:
- return true
- }
- }
- /// Initialize a `HTTPResponseStatus` from a given status and reason.
- ///
- /// - Parameter statusCode: The integer value of the HTTP response status code
- /// - Parameter reasonPhrase: The textual reason phrase from the response. This will be
- /// discarded in favor of the default if the `statusCode` matches one that we know.
- public init(statusCode: Int, reasonPhrase: String = "") {
- switch statusCode {
- case 100:
- self = .continue
- case 101:
- self = .switchingProtocols
- case 102:
- self = .processing
- case 200:
- self = .ok
- case 201:
- self = .created
- case 202:
- self = .accepted
- case 203:
- self = .nonAuthoritativeInformation
- case 204:
- self = .noContent
- case 205:
- self = .resetContent
- case 206:
- self = .partialContent
- case 207:
- self = .multiStatus
- case 208:
- self = .alreadyReported
- case 226:
- self = .imUsed
- case 300:
- self = .multipleChoices
- case 301:
- self = .movedPermanently
- case 302:
- self = .found
- case 303:
- self = .seeOther
- case 304:
- self = .notModified
- case 305:
- self = .useProxy
- case 307:
- self = .temporaryRedirect
- case 308:
- self = .permanentRedirect
- case 400:
- self = .badRequest
- case 401:
- self = .unauthorized
- case 402:
- self = .paymentRequired
- case 403:
- self = .forbidden
- case 404:
- self = .notFound
- case 405:
- self = .methodNotAllowed
- case 406:
- self = .notAcceptable
- case 407:
- self = .proxyAuthenticationRequired
- case 408:
- self = .requestTimeout
- case 409:
- self = .conflict
- case 410:
- self = .gone
- case 411:
- self = .lengthRequired
- case 412:
- self = .preconditionFailed
- case 413:
- self = .payloadTooLarge
- case 414:
- self = .uriTooLong
- case 415:
- self = .unsupportedMediaType
- case 416:
- self = .rangeNotSatisfiable
- case 417:
- self = .expectationFailed
- case 418:
- self = .imATeapot
- case 421:
- self = .misdirectedRequest
- case 422:
- self = .unprocessableEntity
- case 423:
- self = .locked
- case 424:
- self = .failedDependency
- case 426:
- self = .upgradeRequired
- case 428:
- self = .preconditionRequired
- case 429:
- self = .tooManyRequests
- case 431:
- self = .requestHeaderFieldsTooLarge
- case 451:
- self = .unavailableForLegalReasons
- case 500:
- self = .internalServerError
- case 501:
- self = .notImplemented
- case 502:
- self = .badGateway
- case 503:
- self = .serviceUnavailable
- case 504:
- self = .gatewayTimeout
- case 505:
- self = .httpVersionNotSupported
- case 506:
- self = .variantAlsoNegotiates
- case 507:
- self = .insufficientStorage
- case 508:
- self = .loopDetected
- case 510:
- self = .notExtended
- case 511:
- self = .networkAuthenticationRequired
- default:
- self = .custom(code: UInt(statusCode), reasonPhrase: reasonPhrase)
- }
- }
- }
- extension HTTPResponseStatus: Equatable {
- public static func == (lhs: HTTPResponseStatus, rhs: HTTPResponseStatus) -> Bool {
- switch (lhs, rhs) {
- case let (.custom(lcode, lreason), .custom(rcode, rreason)):
- return lcode == rcode && lreason == rreason
- case (.custom, _), (_, .custom):
- return false
- default:
- return lhs.code == rhs.code
- }
- }
- }
- extension HTTPResponseStatus {
- /// The numerical status code for a given HTTP response status.
- public var code: UInt {
- switch self {
- case .continue:
- return 100
- case .switchingProtocols:
- return 101
- case .processing:
- return 102
- case .ok:
- return 200
- case .created:
- return 201
- case .accepted:
- return 202
- case .nonAuthoritativeInformation:
- return 203
- case .noContent:
- return 204
- case .resetContent:
- return 205
- case .partialContent:
- return 206
- case .multiStatus:
- return 207
- case .alreadyReported:
- return 208
- case .imUsed:
- return 226
- case .multipleChoices:
- return 300
- case .movedPermanently:
- return 301
- case .found:
- return 302
- case .seeOther:
- return 303
- case .notModified:
- return 304
- case .useProxy:
- return 305
- case .temporaryRedirect:
- return 307
- case .permanentRedirect:
- return 308
- case .badRequest:
- return 400
- case .unauthorized:
- return 401
- case .paymentRequired:
- return 402
- case .forbidden:
- return 403
- case .notFound:
- return 404
- case .methodNotAllowed:
- return 405
- case .notAcceptable:
- return 406
- case .proxyAuthenticationRequired:
- return 407
- case .requestTimeout:
- return 408
- case .conflict:
- return 409
- case .gone:
- return 410
- case .lengthRequired:
- return 411
- case .preconditionFailed:
- return 412
- case .payloadTooLarge:
- return 413
- case .uriTooLong:
- return 414
- case .unsupportedMediaType:
- return 415
- case .rangeNotSatisfiable:
- return 416
- case .expectationFailed:
- return 417
- case .imATeapot:
- return 418
- case .misdirectedRequest:
- return 421
- case .unprocessableEntity:
- return 422
- case .locked:
- return 423
- case .failedDependency:
- return 424
- case .upgradeRequired:
- return 426
- case .preconditionRequired:
- return 428
- case .tooManyRequests:
- return 429
- case .requestHeaderFieldsTooLarge:
- return 431
- case .unavailableForLegalReasons:
- return 451
- case .internalServerError:
- return 500
- case .notImplemented:
- return 501
- case .badGateway:
- return 502
- case .serviceUnavailable:
- return 503
- case .gatewayTimeout:
- return 504
- case .httpVersionNotSupported:
- return 505
- case .variantAlsoNegotiates:
- return 506
- case .insufficientStorage:
- return 507
- case .loopDetected:
- return 508
- case .notExtended:
- return 510
- case .networkAuthenticationRequired:
- return 511
- case .custom(code: let code, reasonPhrase: _):
- return code
- }
- }
- /// The string reason phrase for a given HTTP response status.
- public var reasonPhrase: String {
- switch self {
- case .continue:
- return "Continue"
- case .switchingProtocols:
- return "Switching Protocols"
- case .processing:
- return "Processing"
- case .ok:
- return "OK"
- case .created:
- return "Created"
- case .accepted:
- return "Accepted"
- case .nonAuthoritativeInformation:
- return "Non-Authoritative Information"
- case .noContent:
- return "No Content"
- case .resetContent:
- return "Reset Content"
- case .partialContent:
- return "Partial Content"
- case .multiStatus:
- return "Multi-Status"
- case .alreadyReported:
- return "Already Reported"
- case .imUsed:
- return "IM Used"
- case .multipleChoices:
- return "Multiple Choices"
- case .movedPermanently:
- return "Moved Permanently"
- case .found:
- return "Found"
- case .seeOther:
- return "See Other"
- case .notModified:
- return "Not Modified"
- case .useProxy:
- return "Use Proxy"
- case .temporaryRedirect:
- return "Temporary Redirect"
- case .permanentRedirect:
- return "Permanent Redirect"
- case .badRequest:
- return "Bad Request"
- case .unauthorized:
- return "Unauthorized"
- case .paymentRequired:
- return "Payment Required"
- case .forbidden:
- return "Forbidden"
- case .notFound:
- return "Not Found"
- case .methodNotAllowed:
- return "Method Not Allowed"
- case .notAcceptable:
- return "Not Acceptable"
- case .proxyAuthenticationRequired:
- return "Proxy Authentication Required"
- case .requestTimeout:
- return "Request Timeout"
- case .conflict:
- return "Conflict"
- case .gone:
- return "Gone"
- case .lengthRequired:
- return "Length Required"
- case .preconditionFailed:
- return "Precondition Failed"
- case .payloadTooLarge:
- return "Payload Too Large"
- case .uriTooLong:
- return "URI Too Long"
- case .unsupportedMediaType:
- return "Unsupported Media Type"
- case .rangeNotSatisfiable:
- return "Range Not Satisfiable"
- case .expectationFailed:
- return "Expectation Failed"
- case .imATeapot:
- return "I'm a teapot"
- case .misdirectedRequest:
- return "Misdirected Request"
- case .unprocessableEntity:
- return "Unprocessable Entity"
- case .locked:
- return "Locked"
- case .failedDependency:
- return "Failed Dependency"
- case .upgradeRequired:
- return "Upgrade Required"
- case .preconditionRequired:
- return "Precondition Required"
- case .tooManyRequests:
- return "Too Many Requests"
- case .requestHeaderFieldsTooLarge:
- return "Request Header Fields Too Large"
- case .unavailableForLegalReasons:
- return "Unavailable For Legal Reasons"
- case .internalServerError:
- return "Internal Server Error"
- case .notImplemented:
- return "Not Implemented"
- case .badGateway:
- return "Bad Gateway"
- case .serviceUnavailable:
- return "Service Unavailable"
- case .gatewayTimeout:
- return "Gateway Timeout"
- case .httpVersionNotSupported:
- return "HTTP Version Not Supported"
- case .variantAlsoNegotiates:
- return "Variant Also Negotiates"
- case .insufficientStorage:
- return "Insufficient Storage"
- case .loopDetected:
- return "Loop Detected"
- case .notExtended:
- return "Not Extended"
- case .networkAuthenticationRequired:
- return "Network Authentication Required"
- case .custom(code: _, reasonPhrase: let phrase):
- return phrase
- }
- }
- }
|