Skip to content

Commit 51fe785

Browse files
Merge pull request #663 from algolia/fix/url-parameters-percent-encoding
Add explicit percent encoding for plus sign for the browsing cursor
2 parents 9ecbce2 + ed18f78 commit 51fe785

File tree

4 files changed

+28
-28
lines changed

4 files changed

+28
-28
lines changed

Sources/AlgoliaSearchClient/Command/Command+Search.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ extension Command {
4040
}
4141

4242
init(indexName: IndexName, cursor: Cursor? = nil, requestOptions: RequestOptions?) {
43-
self.requestOptions = requestOptions.updateOrCreate(cursor.flatMap { [.cursor: $0.rawValue] } ?? [:])
43+
self.requestOptions = requestOptions.updateOrCreate(cursor.flatMap { [.cursor: $0.rawValue.addingPercentEncoding(withAllowedCharacters: .uriAllowed)] } ?? [:])
4444
let path = .indexesV1 >>> .index(indexName) >>> IndexCompletion.browse
4545
urlRequest = .init(method: .get, path: path, requestOptions: self.requestOptions)
4646
}

Sources/AlgoliaSearchClient/Transport/URLSession/URLRequest+Convenience.swift

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ import Foundation
99

1010
extension URLRequest: Builder {}
1111

12+
extension CharacterSet {
13+
14+
static var uriAllowed = CharacterSet.urlQueryAllowed.subtracting(.init(charactersIn: "+"))
15+
16+
}
17+
1218
extension URLRequest {
1319

1420
subscript(header key: HTTPHeaderKey) -> String? {
@@ -28,41 +34,35 @@ extension URLRequest {
2834
var urlComponents = URLComponents()
2935
urlComponents.scheme = "https"
3036
urlComponents.path = path.fullPath
37+
38+
if let urlParameters = requestOptions?.urlParameters {
39+
urlComponents.queryItems = urlParameters.map { (key, value) in .init(name: key.rawValue, value: value) }
40+
}
3141

3242
var request = URLRequest(url: urlComponents.url!)
3343

3444
request.httpMethod = method.rawValue
3545
request.httpBody = body
36-
46+
3747
if let requestOptions = requestOptions {
38-
request.setRequestOptions(requestOptions)
48+
49+
requestOptions.headers.forEach { header in
50+
let (value, field) = (header.value, header.key.rawValue)
51+
request.setValue(value, forHTTPHeaderField: field)
52+
}
53+
54+
// If body is set in query parameters, it will override the body passed as parameter to this function
55+
if let body = requestOptions.body, !body.isEmpty {
56+
let jsonEncodedBody = try? JSONSerialization.data(withJSONObject: body, options: [])
57+
request.httpBody = jsonEncodedBody
58+
}
59+
3960
}
40-
61+
62+
request.httpBody = body
4163
self = request
4264
}
4365

44-
mutating func setRequestOptions(_ requestOptions: RequestOptions) {
45-
46-
// Append headers
47-
requestOptions.headers.forEach { setValue($0.value, forHTTPHeaderField: $0.key.rawValue) }
48-
49-
// Append query items
50-
if let url = url, var currentComponents = URLComponents(string: url.absoluteString) {
51-
let requestOptionsItems = requestOptions.urlParameters.map { URLQueryItem(name: $0.key.rawValue, value: $0.value) }
52-
var existingItems = currentComponents.queryItems ?? []
53-
existingItems.append(contentsOf: requestOptionsItems)
54-
currentComponents.queryItems = existingItems
55-
self.url = currentComponents.url
56-
}
57-
58-
// Set body
59-
if
60-
let body = requestOptions.body,
61-
let jsonData = try? JSONSerialization.data(withJSONObject: body, options: []) {
62-
httpBody = jsonData
63-
}
64-
}
65-
6666
}
6767

6868
extension URLRequest {

Tests/AlgoliaSearchClientTests/Unit/Command/SearchCommandTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class SearchCommandTests: XCTestCase, AlgoliaCommandTest {
3939
callType: .read,
4040
method: .get,
4141
urlPath: "/1/indexes/testIndex/browse",
42-
queryItems: [.init(name: "testParameter", value: "testParameterValue"), .init(name: "cursor", value: "testCursor")],
42+
queryItems: [.init(name: "testParameter", value: "testParameterValue"), .init(name: "cursor", value: "AgA%2BBgg4MTUyNTQ0Mg==")],
4343
body: nil,
4444
requestOptions: test.requestOptions)
4545
}

Tests/AlgoliaSearchClientTests/Unit/TestValues.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ struct TestValues {
2828
}()
2929
let taskID: TaskID = "testTaskID"
3030
let requestOptions = RequestOptions(headers: ["testHeader": "testHeaderValue"], urlParameters: ["testParameter": "testParameterValue"])
31-
let cursor: Cursor = "testCursor"
31+
let cursor: Cursor = "AgA+Bgg4MTUyNTQ0Mg=="
3232
let userID: UserID = "testUserID"
3333
let clusterName: ClusterName = "testClusterName"
3434

0 commit comments

Comments
 (0)