Skip to content

Commit ea455f0

Browse files
committed
[Message] Unify Request & Response coding
1 parent d5d2d7b commit ea455f0

File tree

4 files changed

+43
-49
lines changed

4 files changed

+43
-49
lines changed

Sources/HTTP/Client/Client.swift

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import Log
22
import URL
33
import Network
44
import Stream
5-
import DCompression
65

76
public class Client {
87
public var bufferSize = 4096
@@ -77,7 +76,7 @@ public class Client {
7776
try await outputStream.flush()
7877

7978
var response = try await Response.decode(from: inputStream)
80-
try await decode(&response)
79+
try await Coder.decode(&response)
8180
return response
8281
}
8382

@@ -108,25 +107,6 @@ public class Client {
108107
}
109108
request.acceptEncoding = acceptEncoding
110109
}
111-
112-
private func decode(_ response: inout Response) async throws {
113-
guard let contentEncoding = response.contentEncoding else {
114-
return
115-
}
116-
// FIXME: use GZip/Deflate stream
117-
// instead of changing contentLength
118-
let bytes = try await response.readBody()
119-
let stream = InputByteStream(bytes)
120-
if contentEncoding.contains(.gzip) {
121-
let bytes = try await GZip.decode(from: stream)
122-
response.body = .input(bytes)
123-
response.contentLength = bytes.count
124-
} else if contentEncoding.contains(.deflate) {
125-
let bytes = try await Deflate.decode(from: stream)
126-
response.body = .input(bytes)
127-
response.contentLength = bytes.count
128-
}
129-
}
130110
}
131111

132112
extension Client {

Sources/HTTP/Coding/CodableMessage.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@ import Stream
22

33
public protocol DecodableMessage: AnyObject {
44
var contentType: ContentType? { get }
5+
var contentEncoding: [ContentEncoding]? { get }
56
var transferEncoding: [TransferEncoding]? { get }
6-
var contentLength: Int? { get }
7+
var contentLength: Int? { get set }
78
var body: Body { get set }
89
}
910

10-
extension Request: DecodableMessage {}
11-
extension Response: DecodableMessage {}
11+
public protocol EncodableMessage: AnyObject {
12+
var contentType: ContentType? { get set }
13+
var contentLength: Int? { get set }
14+
var body: Body { get set }
15+
}
16+
17+
extension Request: DecodableMessage, EncodableMessage {}
18+
extension Response: DecodableMessage, EncodableMessage {}
1219

1320
extension DecodableMessage {
1421
public func readBody() async throws -> [UInt8] {

Sources/HTTP/Coding/Coder.swift

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import URL
22
import JSON
33
import Stream
44
import Network
5+
import DCompression
56

67
// MARK: Coder
78

@@ -59,24 +60,24 @@ public struct Coder {
5960
}
6061

6162
@usableFromInline
62-
static func encode(
63+
static func encode<Message: EncodableMessage>(
6364
object: Encodable,
64-
to response: Response,
65+
to message: Message,
6566
contentType type: ApplicationSubtype) throws
6667
{
6768
switch type {
6869
case .json:
6970
// TODO: Use stream + chunked?
7071
let bytes = try JSON.encode(encodable: object)
71-
response.body = .output(bytes)
72-
response.contentLength = bytes.count
73-
response.contentType = .json
72+
message.body = .output(bytes)
73+
message.contentLength = bytes.count
74+
message.contentType = .json
7475

7576
case .formURLEncoded:
7677
let bytes = try FormURLEncoded.encode(encodable: object)
77-
response.body = .output(bytes)
78-
response.contentLength = bytes.count
79-
response.contentType = .formURLEncoded
78+
message.body = .output(bytes)
79+
message.contentLength = bytes.count
80+
message.contentType = .formURLEncoded
8081

8182
default:
8283
throw HTTP.Error.unsupportedContentType
@@ -171,3 +172,25 @@ public struct Coder {
171172
return try type.init(from: decoder)
172173
}
173174
}
175+
176+
// GZip, Deflate
177+
extension Coder {
178+
static func decode<Message: DecodableMessage>(_ message: inout Message) async throws {
179+
guard let contentEncoding = message.contentEncoding else {
180+
return
181+
}
182+
// FIXME: use GZip/Deflate stream
183+
// instead of changing contentLength
184+
let bytes = try await message.readBody()
185+
let stream = InputByteStream(bytes)
186+
if contentEncoding.contains(.gzip) {
187+
let bytes = try await GZip.decode(from: stream)
188+
message.body = .input(bytes)
189+
message.contentLength = bytes.count
190+
} else if contentEncoding.contains(.deflate) {
191+
let bytes = try await Deflate.decode(from: stream)
192+
message.body = .input(bytes)
193+
message.contentLength = bytes.count
194+
}
195+
}
196+
}

Sources/HTTP/Message/Request/Request.swift

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,6 @@ extension Request {
6363
contentType type: ApplicationSubtype = .json
6464
) throws {
6565
self.init(url: url, method: method)
66-
67-
switch type {
68-
case .json:
69-
let bytes = try JSON.encode(body)
70-
self.contentType = .json
71-
self.body = .output(bytes)
72-
self.contentLength = bytes.count
73-
74-
case .formURLEncoded:
75-
let bytes = try FormURLEncoded.encode(body)
76-
self.contentType = .formURLEncoded
77-
self.body = .output(bytes)
78-
self.contentLength = bytes.count
79-
80-
default:
81-
throw Error.unsupportedContentType
82-
}
66+
try Coder.encode(object: body, to: self, contentType: type)
8367
}
8468
}

0 commit comments

Comments
 (0)