Skip to content

Commit 79cd718

Browse files
authored
preserve trailing slash in uri path (swift-server#107)
1 parent 6efe214 commit 79cd718

File tree

3 files changed

+74
-4
lines changed

3 files changed

+74
-4
lines changed

‎Sources/AsyncHTTPClient/HTTPHandler.swift‎

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -385,14 +385,48 @@ extension HTTPClientResponseDelegate{
385385
publicfunc didReceiveError(task:HTTPClient.Task<Response>, _:Error){}
386386
}
387387

388-
internalextensionURL{
388+
extensionURL{
389+
varpercentEncodedPath:String{
390+
ifself.path.isEmpty {
391+
return"/"
392+
}
393+
returnself.path.addingPercentEncoding(withAllowedCharacters:.urlPathAllowed)??self.path
394+
}
395+
396+
varpathHasTrailingSlash:Bool{
397+
if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0,*){
398+
returnself.hasDirectoryPath
399+
}else{
400+
// Most platforms should use `self.hasDirectoryPath`, but on older darwin platforms
401+
// we have this approximation instead.
402+
leturl=self.absoluteString
403+
404+
varpathEndIndex= url.index(before: url.endIndex)
405+
iflet queryIndex = url.firstIndex(of:"?"){
406+
pathEndIndex = url.index(before: queryIndex)
407+
}elseiflet fragmentIndex = url.suffix(from: url.firstIndex(of:"@")?? url.startIndex).lastIndex(of:"#"){
408+
pathEndIndex = url.index(before: fragmentIndex)
409+
}
410+
411+
returnurl[pathEndIndex]=="/"
412+
}
413+
}
414+
389415
varuri:String{
390-
leturlEncodedPath= path.addingPercentEncoding(withAllowedCharacters:.urlPathAllowed)?? path
391-
return path.isEmpty ?"/": urlEncodedPath +(query.map{"?"+ $0 }??"")
416+
varuri=self.percentEncodedPath
417+
ifself.pathHasTrailingSlash, uri !="/"{
418+
uri +="/"
419+
}
420+
421+
iflet query =self.query {
422+
uri +="?"+ query
423+
}
424+
425+
return uri
392426
}
393427

394428
func hasTheSameOrigin(as other:URL)->Bool{
395-
return host == other.host && scheme == other.scheme && port == other.port
429+
returnself.host == other.host && self.scheme == other.scheme && self.port == other.port
396430
}
397431
}
398432

‎Tests/AsyncHTTPClientTests/HTTPClientInternalTests+XCTest.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ extension HTTPClientInternalTests{
3030
("testProxyStreaming", testProxyStreaming),
3131
("testProxyStreamingFailure", testProxyStreamingFailure),
3232
("testUploadStreamingBackpressure", testUploadStreamingBackpressure),
33+
("testRequestURITrailingSlash", testRequestURITrailingSlash),
3334
]
3435
}
3536
}

‎Tests/AsyncHTTPClientTests/HTTPClientInternalTests.swift‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,39 @@ class HTTPClientInternalTests: XCTestCase{
193193

194194
XCTAssertEqual(delegate.reads,3)
195195
}
196+
197+
func testRequestURITrailingSlash()throws{
198+
letrequest1=tryRequest(url:"https://someserver.com:8888/some/path?foo=bar#ref")
199+
XCTAssertEqual(request1.url.uri,"/some/path?foo=bar")
200+
201+
letrequest2=tryRequest(url:"https://someserver.com:8888/some/path/?foo=bar#ref")
202+
XCTAssertEqual(request2.url.uri,"/some/path/?foo=bar")
203+
204+
letrequest3=tryRequest(url:"https://someserver.com:8888?foo=bar#ref")
205+
XCTAssertEqual(request3.url.uri,"/?foo=bar")
206+
207+
letrequest4=tryRequest(url:"https://someserver.com:8888/?foo=bar#ref")
208+
XCTAssertEqual(request4.url.uri,"/?foo=bar")
209+
210+
letrequest5=tryRequest(url:"https://someserver.com:8888/some/path")
211+
XCTAssertEqual(request5.url.uri,"/some/path")
212+
213+
letrequest6=tryRequest(url:"https://someserver.com:8888/some/path/")
214+
XCTAssertEqual(request6.url.uri,"/some/path/")
215+
216+
letrequest7=tryRequest(url:"https://someserver.com:8888")
217+
XCTAssertEqual(request7.url.uri,"/")
218+
219+
letrequest8=tryRequest(url:"https://someserver.com:8888/")
220+
XCTAssertEqual(request8.url.uri,"/")
221+
222+
letrequest9=tryRequest(url:"https://someserver.com:8888#ref")
223+
XCTAssertEqual(request9.url.uri,"/")
224+
225+
letrequest10=tryRequest(url:"https://someserver.com:8888/#ref")
226+
XCTAssertEqual(request10.url.uri,"/")
227+
228+
letrequest11=tryRequest(url:"https://someserver.com/some%20path")
229+
XCTAssertEqual(request11.url.uri,"/some%20path")
230+
}
196231
}

0 commit comments

Comments
(0)