@@ -104,6 +104,12 @@ class _TCPSocket {
104
104
return String ( str [ startIndex..< endIndex] )
105
105
}
106
106
}
107
+
108
+ func writeRawData( _ data: Data ) throws {
109
+ let x = try data. withUnsafeBytes { ptr in
110
+ try attempt ( " write " , valid: isNotNegative, CInt ( write ( connectionSocket, ptr, data. count) ) )
111
+ }
112
+ }
107
113
108
114
func writeData( header: String , body: String , sendDelay: TimeInterval ? = nil , bodyChunks: Int ? = nil ) throws {
109
115
var header = Array ( header. utf8)
@@ -173,6 +179,69 @@ class _HTTPServer {
173
179
semaphore. wait ( )
174
180
175
181
}
182
+
183
+ func respondWithBrokenResponses( uri: String ) throws {
184
+ let responseData : Data
185
+ switch uri {
186
+ case " /LandOfTheLostCities/Pompeii " :
187
+ /* this is an example of what you get if you connect to an HTTP2
188
+ server using HTTP/1.1. Curl interprets that as a HTTP/0.9
189
+ simple-response and therefore sends this back as a response
190
+ body. Go figure! */
191
+ responseData = Data ( bytes: [
192
+ 0x00 , 0x00 , 0x18 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
193
+ 0x01 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
194
+ 0x01 , 0x00 , 0x05 , 0x00 , 0x00 , 0x40 , 0x00 , 0x00 , 0x06 , 0x00 ,
195
+ 0x00 , 0x1f , 0x40 , 0x00 , 0x00 , 0x86 , 0x07 , 0x00 , 0x00 , 0x00 ,
196
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ,
197
+ 0x48 , 0x54 , 0x54 , 0x50 , 0x2f , 0x32 , 0x20 , 0x63 , 0x6c , 0x69 ,
198
+ 0x65 , 0x6e , 0x74 , 0x20 , 0x70 , 0x72 , 0x65 , 0x66 , 0x61 , 0x63 ,
199
+ 0x65 , 0x20 , 0x73 , 0x74 , 0x72 , 0x69 , 0x6e , 0x67 , 0x20 , 0x6d ,
200
+ 0x69 , 0x73 , 0x73 , 0x69 , 0x6e , 0x67 , 0x20 , 0x6f , 0x72 , 0x20 ,
201
+ 0x63 , 0x6f , 0x72 , 0x72 , 0x75 , 0x70 , 0x74 , 0x2e , 0x20 , 0x48 ,
202
+ 0x65 , 0x78 , 0x20 , 0x64 , 0x75 , 0x6d , 0x70 , 0x20 , 0x66 , 0x6f ,
203
+ 0x72 , 0x20 , 0x72 , 0x65 , 0x63 , 0x65 , 0x69 , 0x76 , 0x65 , 0x64 ,
204
+ 0x20 , 0x62 , 0x79 , 0x74 , 0x65 , 0x73 , 0x3a , 0x20 , 0x34 , 0x37 ,
205
+ 0x34 , 0x35 , 0x35 , 0x34 , 0x32 , 0x30 , 0x32 , 0x66 , 0x33 , 0x33 ,
206
+ 0x32 , 0x66 , 0x36 , 0x34 , 0x36 , 0x35 , 0x37 , 0x36 , 0x36 , 0x39 ,
207
+ 0x36 , 0x33 , 0x36 , 0x35 , 0x32 , 0x66 , 0x33 , 0x31 , 0x33 , 0x32 ,
208
+ 0x33 , 0x33 , 0x33 , 0x34 , 0x33 , 0x35 , 0x33 , 0x36 , 0x33 , 0x37 ,
209
+ 0x33 , 0x38 , 0x33 , 0x39 , 0x33 , 0x30 ] )
210
+ case " /LandOfTheLostCities/Sodom " :
211
+ /* a technically valid HTTP/0.9 simple-response */
212
+ responseData = ( " technically, this is a valid HTTP/0.9 " +
213
+ " simple-response. I know it's odd but CURL supports it " +
214
+ " still... \r \n Find out more in those URLs: \r \n " +
215
+ " - https://www.w3.org/Protocols/HTTP/1.0/spec.html#Message-Types \r \n " +
216
+ " - https://github.com/curl/curl/issues/467 \r \n " ) . data ( using: . utf8) !
217
+ case " /LandOfTheLostCities/Gomorrah " :
218
+ /* just broken, hope that's not officially HTTP/0.9 :p */
219
+ responseData = " HTTP/1.1 \r \n \r \n \r \n " . data ( using: . utf8) !
220
+ case " /LandOfTheLostCities/Myndus " :
221
+ responseData = ( " HTTP/1.1 200 OK \r \n " +
222
+ " \r \n " +
223
+ " this is a body that isn't legal as it's " +
224
+ " neither chunked encoding nor any Content-Length \r \n " ) . data ( using: . utf8) !
225
+ case " /LandOfTheLostCities/Kameiros " :
226
+ responseData = ( " HTTP/1.1 999 Wrong Code \r \n " +
227
+ " illegal: status code (too large) \r \n " +
228
+ " \r \n " ) . data ( using: . utf8) !
229
+ case " /LandOfTheLostCities/Dinavar " :
230
+ responseData = ( " HTTP/1.1 20 Too Few Digits \r \n " +
231
+ " illegal: status code (too few digits) \r \n " +
232
+ " \r \n " ) . data ( using: . utf8) !
233
+ case " /LandOfTheLostCities/Kuhikugu " :
234
+ responseData = ( " HTTP/1.1 2000 Too Many Digits \r \n " +
235
+ " illegal: status code (too many digits) \r \n " +
236
+ " \r \n " ) . data ( using: . utf8) !
237
+ default :
238
+ responseData = ( " HTTP/1.1 500 Internal Server Error \r \n " +
239
+ " case-missing-in: TestFoundation/HTTPServer.swift \r \n " +
240
+ " \r \n " ) . data ( using: . utf8) !
241
+ }
242
+ try self . socket. writeRawData ( responseData)
243
+ }
244
+
176
245
}
177
246
178
247
struct _HTTPRequest {
@@ -249,7 +318,13 @@ public class TestURLSessionServer {
249
318
}
250
319
251
320
public func readAndRespond( ) throws {
252
- try httpServer. respond ( with: process ( request: httpServer. request ( ) ) , startDelay: self . startDelay, sendDelay: self . sendDelay, bodyChunks: self . bodyChunks)
321
+ let req = try httpServer. request ( )
322
+ if req. uri. hasPrefix ( " /LandOfTheLostCities/ " ) {
323
+ /* these are all misbehaving servers */
324
+ try httpServer. respondWithBrokenResponses ( uri: req. uri)
325
+ } else {
326
+ try httpServer. respond ( with: process ( request: req) , startDelay: self . startDelay, sendDelay: self . sendDelay, bodyChunks: self . bodyChunks)
327
+ }
253
328
}
254
329
255
330
func process( request: _HTTPRequest ) -> _HTTPResponse {
0 commit comments