diff --git a/HTTPStatusCodes.swift b/HTTPStatusCodes.swift new file mode 100644 index 0000000..5b2eed2 --- /dev/null +++ b/HTTPStatusCodes.swift @@ -0,0 +1,166 @@ +// +// HTTPStatusCodes.swift +// +// Created by Richard Hodgkins on 11/01/2015. +// Copyright (c) 2015 Richard Hodgkins. All rights reserved. +// + +import Foundation + +/** + HTTP status codes as per http://en.wikipedia.org/wiki/List_of_HTTP_status_codes + + The RF2616 standard is completely covered (http://www.ietf.org/rfc/rfc2616.txt) + */ +public enum HTTPStatusCode : Int { + // Informational + case Continue = 100 + case SwitchingProtocols = 101 + case Processing = 102 + + // Success + case OK = 200 + case Created = 201 + case Accepted = 202 + case NonAuthoritativeInformation = 203 + case NoContent = 204 + case ResetContent = 205 + case PartialContent = 206 + case MultiStatus = 207 + case AlreadyReported = 208 + case IMUsed = 226 + + // Redirections + case MultipleChoices = 300 + case MovedPermanently = 301 + case Found = 302 + case SeeOther = 303 + case NotModified = 304 + case UseProxy = 305 + case SwitchProxy = 306 + case TemporaryRedirect = 307 + case PermanentRedirect = 308 + + // Client Errors + case BadRequest = 400 + case Unauthorized = 401 + case PaymentRequired = 402 + case Forbidden = 403 + case NotFound = 404 + case MethodNotAllowed = 405 + case NotAcceptable = 406 + case ProxyAuthenticationRequired = 407 + case RequestTimeout = 408 + case Conflict = 409 + case Gone = 410 + case LengthRequired = 411 + case PreconditionFailed = 412 + case RequestEntityTooLarge = 413 + case RequestURITooLong = 414 + case UnsupportedMediaType = 415 + case RequestedRangeNotSatisfiable = 416 + case ExpectationFailed = 417 + case ImATeapot = 418 + case AuthenticationTimeout = 419 + case UnprocessableEntity = 422 + case Locked = 423 + case FailedDependency = 424 + case UpgradeRequired = 426 + case PreconditionRequired = 428 + case TooManyRequests = 429 + case RequestHeaderFieldsTooLarge = 431 + case LoginTimeout = 440 + case NoResponse = 444 + case RetryWith = 449 + case UnavailableForLegalReasons = 451 + case RequestHeaderTooLarge = 494 + case CertError = 495 + case NoCert = 496 + case HTTPToHTTPS = 497 + case TokenExpired = 498 + case ClientClosedRequest = 499 + + // Server Errors + case InternalServerError = 500 + case NotImplemented = 501 + case BadGateway = 502 + case ServiceUnavailable = 503 + case GatewayTimeout = 504 + case HTTPVersionNotSupported = 505 + case VariantAlsoNegotiates = 506 + case InsufficientStorage = 507 + case LoopDetected = 508 + case BandwidthLimitExceeded = 509 + case NotExtended = 510 + case NetworkAuthenticationRequired = 511 + case NetworkTimeoutError = 599 +} + +public extension HTTPStatusCode { + /// Informational - Request received, continuing process. + public var isInformational: Bool { + return inRange(100...200) + } + /// Success - The action was successfully received, understood, and accepted. + public var isSuccess: Bool { + return inRange(200...299) + } + /// Redirection - Further action must be taken in order to complete the request. + public var isRedirection: Bool { + return inRange(300...399) + } + /// Client Error - The request contains bad syntax or cannot be fulfilled. + public var isClientError: Bool { + return inRange(400...499) + } + /// Server Error - The server failed to fulfill an apparently valid request. + public var isServerError: Bool { + return inRange(500...599) + } + + /// :returns: true if the status code is in the provided range, false otherwise. + private func inRange(range: Range) -> Bool { + return contains(range, rawValue) + } +} + +public extension HTTPStatusCode { + public var localizedReasonPhrase: String { + return NSHTTPURLResponse.localizedStringForStatusCode(rawValue) + } +} + +// MARK: - Printing + +extension HTTPStatusCode: DebugPrintable, Printable { + public var description: String { + return "\(rawValue) - \(localizedReasonPhrase)" + } + public var debugDescription: String { + return "HTTPStatusCode:\(description)" + } +} + +// MARK: - HTTP URL Response + +public extension HTTPStatusCode { + /// Obtains a possible status code from an optional HTTP URL response. + public init?(HTTPResponse: NSHTTPURLResponse?) { + if let value = HTTPResponse?.statusCode { + self.init(rawValue: value) + } else { + return nil + } + } +} + +public extension NSHTTPURLResponse { + public var statusCodeValue: HTTPStatusCode? { + return HTTPStatusCode(HTTPResponse: self) + } + + @availability(iOS, introduced=7.0) + public convenience init?(URL url: NSURL, statusCode: HTTPStatusCode, HTTPVersion: String?, headerFields: [NSObject : AnyObject]?) { + self.init(URL: url, statusCode: statusCode.rawValue, HTTPVersion: HTTPVersion, headerFields: headerFields) + } +}