|
7 | 7 |
|
8 | 8 | import Foundation |
9 | 9 | import Socket |
| 10 | +import Algorithms |
10 | 11 |
|
11 | 12 | public final class HTTPServer { |
12 | 13 |
|
@@ -106,6 +107,12 @@ internal extension HTTPServer { |
106 | 107 | } |
107 | 108 | } |
108 | 109 |
|
| 110 | +internal extension HTTPServer { |
| 111 | + |
| 112 | + /// Total Length is the length of the datagram, measured in octets, including internet header and data. This field allows the length of a datagram to be up to 65,535 octets. |
| 113 | + static var chunkSize: Int { 65_535 } |
| 114 | +} |
| 115 | + |
109 | 116 | // MARK: - Supporting Types |
110 | 117 |
|
111 | 118 | public extension HTTPServer { |
@@ -222,23 +229,33 @@ internal extension HTTPServer { |
222 | 229 | } |
223 | 230 |
|
224 | 231 | private func read(_ length: Int) async throws { |
225 | | - let chunkSize = 536 // The default TCP Maximum Segment Size is 536 |
| 232 | + let chunkSize = HTTPServer.chunkSize |
226 | 233 | var readLength = 0 |
227 | 234 | var readMore = true |
| 235 | + var chunkCount = 0 |
228 | 236 | while readMore { |
229 | | - let chunk = try await socket.read(chunkSize) |
| 237 | + let readSize = min(chunkSize, length) |
| 238 | + let chunk = try await socket.read(readSize) |
230 | 239 | readLength += chunk.count |
| 240 | + chunkCount += 1 |
231 | 241 | self.readData.append(chunk) |
232 | | - readMore = readLength < length && chunk.count == chunkSize // need more data and read max |
| 242 | + readMore = readLength < length && chunk.count == readSize // need more data and read max |
| 243 | + } |
| 244 | + self.server.log?("[\(address)] Read \(readLength) bytes (\(chunkCount) chunks)") |
| 245 | + } |
| 246 | + |
| 247 | + private func write(_ data: Data) async throws { |
| 248 | + let chunkSize = HTTPServer.chunkSize |
| 249 | + let chunks = data.chunks(ofCount: chunkSize) |
| 250 | + for chunk in chunks { |
| 251 | + try await socket.write(chunk) |
233 | 252 | } |
234 | | - self.server.log?("[\(address)] Read \(readLength) bytes") |
| 253 | + self.server.log?("[\(address)] Wrote \(data.count) bytes (\(chunks.count) chunks)") |
235 | 254 | } |
236 | 255 |
|
237 | 256 | private func respond(_ response: HTTPResponse) async throws { |
238 | | - let chunkSize = 536 // The default TCP Maximum Segment Size is 536 |
239 | | - let data = response.data |
| 257 | + try await self.write(response.data) |
240 | 258 | self.server.log?("[\(address)] Response \(response.code.rawValue) \(response.status) \(response.body.count) bytes") |
241 | | - try await socket.write(data) |
242 | 259 | await socket.close() |
243 | 260 | } |
244 | 261 |
|
|
0 commit comments