Skip to content

Commit 93e7b16

Browse files
committed
Write data in chunks
1 parent c172d4f commit 93e7b16

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

Package.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,21 @@ let package = Package(
2121
.package(
2222
url: "https://github.com/PureSwift/Socket.git",
2323
branch: "main"
24+
),
25+
.package(
26+
url: "https://github.com/apple/swift-algorithms.git",
27+
from: "1.0.0"
2428
)
2529
],
2630
targets: [
2731
.target(
2832
name: "HTTP",
2933
dependencies: [
30-
"Socket"
34+
"Socket",
35+
.product(
36+
name: "Algorithms",
37+
package: "swift-algorithms"
38+
)
3139
]
3240
),
3341
.testTarget(

Sources/HTTP/Server.swift

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import Foundation
99
import Socket
10+
import Algorithms
1011

1112
public final class HTTPServer {
1213

@@ -106,6 +107,12 @@ internal extension HTTPServer {
106107
}
107108
}
108109

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+
109116
// MARK: - Supporting Types
110117

111118
public extension HTTPServer {
@@ -222,23 +229,33 @@ internal extension HTTPServer {
222229
}
223230

224231
private func read(_ length: Int) async throws {
225-
let chunkSize = 536 // The default TCP Maximum Segment Size is 536
232+
let chunkSize = HTTPServer.chunkSize
226233
var readLength = 0
227234
var readMore = true
235+
var chunkCount = 0
228236
while readMore {
229-
let chunk = try await socket.read(chunkSize)
237+
let readSize = min(chunkSize, length)
238+
let chunk = try await socket.read(readSize)
230239
readLength += chunk.count
240+
chunkCount += 1
231241
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)
233252
}
234-
self.server.log?("[\(address)] Read \(readLength) bytes")
253+
self.server.log?("[\(address)] Wrote \(data.count) bytes (\(chunks.count) chunks)")
235254
}
236255

237256
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)
240258
self.server.log?("[\(address)] Response \(response.code.rawValue) \(response.status) \(response.body.count) bytes")
241-
try await socket.write(data)
242259
await socket.close()
243260
}
244261

0 commit comments

Comments
 (0)