@@ -92,10 +92,33 @@ class _TCPSocket {
9292 _ = try attempt ( " read " , valid: isNotNegative, CInt ( read ( connectionSocket, & buffer, 4096 ) ) )
9393 return String ( cString: & buffer)
9494 }
95+
96+ func split( _ str: String , _ count: Int ) -> [ String ] {
97+ return stride ( from: 0 , to: str. characters. count, by: count) . map { i -> String in
98+ let startIndex = str. index ( str. startIndex, offsetBy: i)
99+ let endIndex = str. index ( startIndex, offsetBy: count, limitedBy: str. endIndex) ?? str. endIndex
100+ return str [ startIndex..< endIndex]
101+ }
102+ }
95103
96- func writeData( data: String ) throws {
97- var bytes = Array ( data. utf8)
98- _ = try attempt ( " write " , valid: isNotNegative, CInt ( write ( connectionSocket, & bytes, data. utf8. count) ) )
104+ func writeData( header: String , body: String , sendDelay: TimeInterval ? = nil , bodyChunks: Int ? = nil ) throws {
105+ var header = Array ( header. utf8)
106+ _ = try attempt ( " write " , valid: isNotNegative, CInt ( write ( connectionSocket, & header, header. count) ) )
107+
108+ if let sendDelay = sendDelay, let bodyChunks = bodyChunks {
109+ let count = max ( 1 , Int ( Double ( body. utf8. count) / Double( bodyChunks) ) )
110+ let texts = split ( body, count)
111+
112+ for item in texts {
113+ sleep ( UInt32 ( sendDelay) )
114+ var bytes = Array ( item. utf8)
115+ print ( item)
116+ _ = try attempt ( " write " , valid: isNotNegative, CInt ( write ( connectionSocket, & bytes, bytes. count) ) )
117+ }
118+ } else {
119+ var bytes = Array ( body. utf8)
120+ _ = try attempt ( " write " , valid: isNotNegative, CInt ( write ( connectionSocket, & bytes, bytes. count) ) )
121+ }
99122 }
100123
101124 func shutdown( ) {
@@ -128,8 +151,24 @@ class _HTTPServer {
128151 return _HTTPRequest ( request: try socket. readData ( ) )
129152 }
130153
131- public func respond( with response: _HTTPResponse ) throws {
132- try socket. writeData ( data: response. description)
154+ public func respond( with response: _HTTPResponse , startDelay: TimeInterval ? = nil , sendDelay: TimeInterval ? = nil , bodyChunks: Int ? = nil ) throws {
155+ let semaphore = DispatchSemaphore ( value: 0 )
156+ let deadlineTime : DispatchTime
157+
158+ if let startDelay = startDelay {
159+ deadlineTime = . now( ) + . seconds( Int ( startDelay) )
160+ } else {
161+ deadlineTime = . now( )
162+ }
163+
164+ DispatchQueue . main. asyncAfter ( deadline: deadlineTime) {
165+ do {
166+ try self . socket. writeData ( header: response. header, body: response. body, sendDelay: sendDelay, bodyChunks: bodyChunks)
167+ semaphore. signal ( )
168+ } catch { }
169+ }
170+ semaphore. wait ( )
171+
133172 }
134173}
135174
@@ -160,17 +199,17 @@ struct _HTTPResponse {
160199 }
161200 private let responseCode : Response
162201 private let headers : String
163- private let body : String
202+ public let body : String
164203
165204 public init ( response: Response , headers: String = _HTTPUtils. EMPTY, body: String ) {
166205 self . responseCode = response
167206 self . headers = headers
168207 self . body = body
169208 }
170209
171- public var description : String {
210+ public var header : String {
172211 let statusLine = _HTTPUtils. VERSION + _HTTPUtils. SPACE + " \( responseCode. rawValue) " + _HTTPUtils. SPACE + " \( responseCode) "
173- return statusLine + ( headers != _HTTPUtils. EMPTY ? _HTTPUtils. CRLF + headers : _HTTPUtils. EMPTY) + _HTTPUtils. CRLF2 + body
212+ return statusLine + ( headers != _HTTPUtils. EMPTY ? _HTTPUtils. CRLF + headers : _HTTPUtils. EMPTY) + _HTTPUtils. CRLF2
174213 }
175214}
176215
@@ -181,18 +220,24 @@ public class TestURLSessionServer {
181220 " USA " : " Washington, D.C. " ,
182221 " country.txt " : " A country is a region that is identified as a distinct national entity in political geography " ]
183222 let httpServer : _HTTPServer
223+ let startDelay : TimeInterval ?
224+ let sendDelay : TimeInterval ?
225+ let bodyChunks : Int ?
184226
185- public init ( port: UInt16 ) throws {
227+ public init ( port: UInt16 , startDelay : TimeInterval ? = nil , sendDelay : TimeInterval ? = nil , bodyChunks : Int ? = nil ) throws {
186228 httpServer = try _HTTPServer. create ( port: port)
229+ self . startDelay = startDelay
230+ self . sendDelay = sendDelay
231+ self . bodyChunks = bodyChunks
187232 }
188233 public func start( started: ServerSemaphore ) throws {
189234 started. signal ( )
190235 try httpServer. listen ( notify: started)
191236 }
192237
193238 public func readAndRespond( ) throws {
194- try httpServer. respond ( with: process ( request: httpServer. request ( ) ) )
195- }
239+ try httpServer. respond ( with: process ( request: httpServer. request ( ) ) , startDelay : self . startDelay , sendDelay : self . sendDelay , bodyChunks : self . bodyChunks )
240+ }
196241
197242 func process( request: _HTTPRequest ) -> _HTTPResponse {
198243 if request. method == . GET {
0 commit comments