|
14 | 14 |
|
15 | 15 | // MARK: HTTPHeaders
|
16 | 16 |
|
| 17 | +import HTTPTypes |
| 18 | + |
17 | 19 | public typealias HTTPHeaders = [String: String]
|
18 | 20 | public typealias HTTPMultiValueHeaders = [String: [String]]
|
19 | 21 |
|
@@ -72,178 +74,31 @@ extension String.UTF8View {
|
72 | 74 | }
|
73 | 75 | }
|
74 | 76 |
|
75 |
| -// MARK: HTTPMethod |
76 |
| - |
77 |
| -public struct HTTPMethod: RawRepresentable, Equatable { |
78 |
| - public var rawValue: String |
79 |
| - |
80 |
| - public init?(rawValue: String) { |
81 |
| - guard rawValue.isValidHTTPToken else { |
82 |
| - return nil |
83 |
| - } |
84 |
| - self.rawValue = rawValue |
85 |
| - } |
86 |
| - |
87 |
| - public static var GET: HTTPMethod { HTTPMethod(rawValue: "GET")! } |
88 |
| - public static var POST: HTTPMethod { HTTPMethod(rawValue: "POST")! } |
89 |
| - public static var PUT: HTTPMethod { HTTPMethod(rawValue: "PUT")! } |
90 |
| - public static var PATCH: HTTPMethod { HTTPMethod(rawValue: "PATCH")! } |
91 |
| - public static var DELETE: HTTPMethod { HTTPMethod(rawValue: "DELETE")! } |
92 |
| - public static var OPTIONS: HTTPMethod { HTTPMethod(rawValue: "OPTIONS")! } |
93 |
| - public static var HEAD: HTTPMethod { HTTPMethod(rawValue: "HEAD")! } |
94 |
| - |
95 |
| - public static func RAW(value: String) -> HTTPMethod? { HTTPMethod(rawValue: value) } |
96 |
| -} |
97 |
| - |
98 |
| -extension HTTPMethod: Codable { |
99 |
| - public init(from decoder: Decoder) throws { |
100 |
| - let container = try decoder.singleValueContainer() |
101 |
| - let rawMethod = try container.decode(String.self) |
102 |
| - |
103 |
| - guard let method = HTTPMethod(rawValue: rawMethod) else { |
104 |
| - throw DecodingError.dataCorruptedError( |
105 |
| - in: container, |
106 |
| - debugDescription: #"Method "\#(rawMethod)" does not conform to allowed http method syntax defined in RFC 7230 Section 3.2.6"# |
107 |
| - ) |
108 |
| - } |
109 |
| - |
110 |
| - self = method |
111 |
| - } |
112 |
| - |
113 |
| - public func encode(to encoder: Encoder) throws { |
| 77 | +extension HTTPResponse.Status: Codable { |
| 78 | + public func encode(to encoder: any Encoder) throws { |
114 | 79 | var container = encoder.singleValueContainer()
|
115 |
| - try container.encode(self.rawValue) |
116 |
| - } |
117 |
| -} |
118 |
| - |
119 |
| -// MARK: HTTPResponseStatus |
120 |
| - |
121 |
| -public struct HTTPResponseStatus { |
122 |
| - public let code: UInt |
123 |
| - public let reasonPhrase: String? |
124 |
| - |
125 |
| - public init(code: UInt, reasonPhrase: String? = nil) { |
126 |
| - self.code = code |
127 |
| - self.reasonPhrase = reasonPhrase |
| 80 | + try container.encode(self.code) |
128 | 81 | }
|
129 | 82 |
|
130 |
| - public static var `continue`: HTTPResponseStatus { HTTPResponseStatus(code: 100) } |
131 |
| - public static var switchingProtocols: HTTPResponseStatus { HTTPResponseStatus(code: 101) } |
132 |
| - public static var processing: HTTPResponseStatus { HTTPResponseStatus(code: 102) } |
133 |
| - public static var earlyHints: HTTPResponseStatus { HTTPResponseStatus(code: 103) } |
134 |
| - |
135 |
| - public static var ok: HTTPResponseStatus { HTTPResponseStatus(code: 200) } |
136 |
| - public static var created: HTTPResponseStatus { HTTPResponseStatus(code: 201) } |
137 |
| - public static var accepted: HTTPResponseStatus { HTTPResponseStatus(code: 202) } |
138 |
| - public static var nonAuthoritativeInformation: HTTPResponseStatus { HTTPResponseStatus(code: 203) } |
139 |
| - public static var noContent: HTTPResponseStatus { HTTPResponseStatus(code: 204) } |
140 |
| - public static var resetContent: HTTPResponseStatus { HTTPResponseStatus(code: 205) } |
141 |
| - public static var partialContent: HTTPResponseStatus { HTTPResponseStatus(code: 206) } |
142 |
| - public static var multiStatus: HTTPResponseStatus { HTTPResponseStatus(code: 207) } |
143 |
| - public static var alreadyReported: HTTPResponseStatus { HTTPResponseStatus(code: 208) } |
144 |
| - public static var imUsed: HTTPResponseStatus { HTTPResponseStatus(code: 226) } |
145 |
| - |
146 |
| - public static var multipleChoices: HTTPResponseStatus { HTTPResponseStatus(code: 300) } |
147 |
| - public static var movedPermanently: HTTPResponseStatus { HTTPResponseStatus(code: 301) } |
148 |
| - public static var found: HTTPResponseStatus { HTTPResponseStatus(code: 302) } |
149 |
| - public static var seeOther: HTTPResponseStatus { HTTPResponseStatus(code: 303) } |
150 |
| - public static var notModified: HTTPResponseStatus { HTTPResponseStatus(code: 304) } |
151 |
| - public static var useProxy: HTTPResponseStatus { HTTPResponseStatus(code: 305) } |
152 |
| - public static var temporaryRedirect: HTTPResponseStatus { HTTPResponseStatus(code: 307) } |
153 |
| - public static var permanentRedirect: HTTPResponseStatus { HTTPResponseStatus(code: 308) } |
154 |
| - |
155 |
| - public static var badRequest: HTTPResponseStatus { HTTPResponseStatus(code: 400) } |
156 |
| - public static var unauthorized: HTTPResponseStatus { HTTPResponseStatus(code: 401) } |
157 |
| - public static var paymentRequired: HTTPResponseStatus { HTTPResponseStatus(code: 402) } |
158 |
| - public static var forbidden: HTTPResponseStatus { HTTPResponseStatus(code: 403) } |
159 |
| - public static var notFound: HTTPResponseStatus { HTTPResponseStatus(code: 404) } |
160 |
| - public static var methodNotAllowed: HTTPResponseStatus { HTTPResponseStatus(code: 405) } |
161 |
| - public static var notAcceptable: HTTPResponseStatus { HTTPResponseStatus(code: 406) } |
162 |
| - public static var proxyAuthenticationRequired: HTTPResponseStatus { HTTPResponseStatus(code: 407) } |
163 |
| - public static var requestTimeout: HTTPResponseStatus { HTTPResponseStatus(code: 408) } |
164 |
| - public static var conflict: HTTPResponseStatus { HTTPResponseStatus(code: 409) } |
165 |
| - public static var gone: HTTPResponseStatus { HTTPResponseStatus(code: 410) } |
166 |
| - public static var lengthRequired: HTTPResponseStatus { HTTPResponseStatus(code: 411) } |
167 |
| - public static var preconditionFailed: HTTPResponseStatus { HTTPResponseStatus(code: 412) } |
168 |
| - public static var payloadTooLarge: HTTPResponseStatus { HTTPResponseStatus(code: 413) } |
169 |
| - public static var uriTooLong: HTTPResponseStatus { HTTPResponseStatus(code: 414) } |
170 |
| - public static var unsupportedMediaType: HTTPResponseStatus { HTTPResponseStatus(code: 415) } |
171 |
| - public static var rangeNotSatisfiable: HTTPResponseStatus { HTTPResponseStatus(code: 416) } |
172 |
| - public static var expectationFailed: HTTPResponseStatus { HTTPResponseStatus(code: 417) } |
173 |
| - public static var imATeapot: HTTPResponseStatus { HTTPResponseStatus(code: 418) } |
174 |
| - public static var misdirectedRequest: HTTPResponseStatus { HTTPResponseStatus(code: 421) } |
175 |
| - public static var unprocessableEntity: HTTPResponseStatus { HTTPResponseStatus(code: 422) } |
176 |
| - public static var locked: HTTPResponseStatus { HTTPResponseStatus(code: 423) } |
177 |
| - public static var failedDependency: HTTPResponseStatus { HTTPResponseStatus(code: 424) } |
178 |
| - public static var upgradeRequired: HTTPResponseStatus { HTTPResponseStatus(code: 426) } |
179 |
| - public static var preconditionRequired: HTTPResponseStatus { HTTPResponseStatus(code: 428) } |
180 |
| - public static var tooManyRequests: HTTPResponseStatus { HTTPResponseStatus(code: 429) } |
181 |
| - public static var requestHeaderFieldsTooLarge: HTTPResponseStatus { HTTPResponseStatus(code: 431) } |
182 |
| - public static var unavailableForLegalReasons: HTTPResponseStatus { HTTPResponseStatus(code: 451) } |
183 |
| - |
184 |
| - public static var internalServerError: HTTPResponseStatus { HTTPResponseStatus(code: 500) } |
185 |
| - public static var notImplemented: HTTPResponseStatus { HTTPResponseStatus(code: 501) } |
186 |
| - public static var badGateway: HTTPResponseStatus { HTTPResponseStatus(code: 502) } |
187 |
| - public static var serviceUnavailable: HTTPResponseStatus { HTTPResponseStatus(code: 503) } |
188 |
| - public static var gatewayTimeout: HTTPResponseStatus { HTTPResponseStatus(code: 504) } |
189 |
| - public static var httpVersionNotSupported: HTTPResponseStatus { HTTPResponseStatus(code: 505) } |
190 |
| - public static var variantAlsoNegotiates: HTTPResponseStatus { HTTPResponseStatus(code: 506) } |
191 |
| - public static var insufficientStorage: HTTPResponseStatus { HTTPResponseStatus(code: 507) } |
192 |
| - public static var loopDetected: HTTPResponseStatus { HTTPResponseStatus(code: 508) } |
193 |
| - public static var notExtended: HTTPResponseStatus { HTTPResponseStatus(code: 510) } |
194 |
| - public static var networkAuthenticationRequired: HTTPResponseStatus { HTTPResponseStatus(code: 511) } |
195 |
| -} |
196 |
| - |
197 |
| -extension HTTPResponseStatus: Equatable { |
198 |
| - public static func == (lhs: Self, rhs: Self) -> Bool { |
199 |
| - lhs.code == rhs.code |
| 83 | + public init(from decoder: any Decoder) throws { |
| 84 | + let code = try decoder.singleValueContainer().decode(Int.self) |
| 85 | + self.init(code: code) |
200 | 86 | }
|
201 | 87 | }
|
202 | 88 |
|
203 |
| -extension HTTPResponseStatus: Codable { |
204 |
| - public init(from decoder: Decoder) throws { |
205 |
| - let container = try decoder.singleValueContainer() |
206 |
| - self.code = try container.decode(UInt.self) |
207 |
| - self.reasonPhrase = nil |
208 |
| - } |
209 |
| - |
210 |
| - public func encode(to encoder: Encoder) throws { |
| 89 | +extension HTTPRequest.Method: Codable { |
| 90 | + public func encode(to encoder: any Encoder) throws { |
211 | 91 | var container = encoder.singleValueContainer()
|
212 |
| - try container.encode(self.code) |
| 92 | + try container.encode(self.rawValue) |
213 | 93 | }
|
214 |
| -} |
215 | 94 |
|
216 |
| -extension String { |
217 |
| - internal var isValidHTTPToken: Bool { |
218 |
| - self.utf8.allSatisfy { char -> Bool in |
219 |
| - switch char { |
220 |
| - case UInt8(ascii: "a") ... UInt8(ascii: "z"), |
221 |
| - UInt8(ascii: "A") ... UInt8(ascii: "Z"), |
222 |
| - UInt8(ascii: "0") ... UInt8(ascii: "9"), |
223 |
| - UInt8(ascii: "!"), |
224 |
| - UInt8(ascii: "#"), |
225 |
| - UInt8(ascii: "$"), |
226 |
| - UInt8(ascii: "%"), |
227 |
| - UInt8(ascii: "&"), |
228 |
| - UInt8(ascii: "'"), |
229 |
| - UInt8(ascii: "*"), |
230 |
| - UInt8(ascii: "+"), |
231 |
| - UInt8(ascii: "-"), |
232 |
| - UInt8(ascii: "."), |
233 |
| - UInt8(ascii: "^"), |
234 |
| - UInt8(ascii: "_"), |
235 |
| - UInt8(ascii: "`"), |
236 |
| - UInt8(ascii: "|"), |
237 |
| - UInt8(ascii: "~"): |
238 |
| - return true |
239 |
| - default: |
240 |
| - return false |
241 |
| - } |
| 95 | + public init(from decoder: any Decoder) throws { |
| 96 | + let container = try decoder.singleValueContainer() |
| 97 | + let rawMethod = try container.decode(String.self) |
| 98 | + guard let method = HTTPRequest.Method(rawMethod) else { |
| 99 | + throw DecodingError.dataCorruptedError(in: container, debugDescription: "\"\(rawMethod)\" is not a valid method") |
242 | 100 | }
|
| 101 | + |
| 102 | + self = method |
243 | 103 | }
|
244 | 104 | }
|
245 |
| - |
246 |
| -#if swift(>=5.6) |
247 |
| -extension HTTPMethod: Sendable {} |
248 |
| -extension HTTPResponseStatus: Sendable {} |
249 |
| -#endif |
0 commit comments