Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions Source/ARTNSMutableURLRequest+ARTUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,27 @@

@implementation NSMutableURLRequest (ARTUtils)

- (void)appendQueryItem:(NSURLQueryItem *)item {
- (void)setQueryItemNamed:(NSString *)name withValue:(NSString *)value {
NSURLComponents *components = [NSURLComponents componentsWithURL:self.URL resolvingAgainstBaseURL:YES];
if(components == nil) {
if (components == nil) {
return;
}

NSMutableArray<NSURLQueryItem *> *mutableQueryItems = [NSMutableArray arrayWithArray:components.queryItems];
[mutableQueryItems addObject:item];
NSMutableArray<NSURLQueryItem *> *mutableQueryItems = [NSMutableArray arrayWithArray:components.queryItems ?: @[]];

// Remove existing query item with the same name if it exists
NSMutableIndexSet *indicesToRemove = [NSMutableIndexSet indexSet];
for (NSUInteger i = 0; i < mutableQueryItems.count; i++) {
if ([mutableQueryItems[i].name isEqualToString:name]) {
[indicesToRemove addIndex:i];
}
}
[mutableQueryItems removeObjectsAtIndexes:indicesToRemove];

// Add the new query item
NSURLQueryItem *newItem = [NSURLQueryItem queryItemWithName:name value:value];
[mutableQueryItems addObject:newItem];

components.queryItems = mutableQueryItems;

NSURL *modifiedURL = components.URL;
Expand Down
4 changes: 2 additions & 2 deletions Source/ARTRest.m
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ - (NSString *)agentIdentifierWithWrapperSDKAgents:(nullable NSDictionary<NSStrin
requestId = [[randomId dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
}

[mutableRequest appendQueryItem:[NSURLQueryItem queryItemWithName:@"request_id" value:requestId]];
[mutableRequest setQueryItemNamed:@"request_id" withValue:requestId];
}

// RSC15f - reset the successed fallback host on fallbackRetryTimeout expiration
Expand Down Expand Up @@ -464,7 +464,7 @@ - (NSString *)agentIdentifierWithWrapperSDKAgents:(nullable NSDictionary<NSStrin
task = [self executeRequest:newRequest
fallbacks:blockFallbacks
retries:retries + 1
originalRequestId:originalRequestId
originalRequestId:requestId
wrapperSDKAgents:wrapperSDKAgents
completion:callback];
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ NS_ASSUME_NONNULL_BEGIN
If for some reasons new URL constructed by URLComponents is `nil`, old URL is a valiid URL for this request.
*/
- (void)replaceHostWith:(NSString *)host;
- (void)appendQueryItem:(NSURLQueryItem *)item;
- (void)setQueryItemNamed:(NSString *)name withValue:(NSString *)value;

@end

Expand Down
30 changes: 29 additions & 1 deletion Test/AblyTests/Test Utilities/TestUtilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1541,7 +1541,35 @@ extension String {
func replace(_ value: String, withString string: String) -> String {
return self.replacingOccurrences(of: value, with: string, options: NSString.CompareOptions.literal, range: nil)
}


func substring(after: String) -> String? {
guard let range = self.range(of: after) else {
return nil
}
let startIndex = range.upperBound
return String(self[startIndex...])
}

func substring(before: String) -> String? {
guard let range = self.range(of: before) else {
return nil
}
let endIndex = range.lowerBound
return String(self[..<endIndex])
}

func substring(between: String, andString: String) -> String? {
guard let startRange = self.range(of: between) else {
return nil
}
let searchStartIndex = startRange.upperBound
let remainingString = String(self[searchStartIndex...])
guard let endRange = remainingString.range(of: andString) else {
return nil
}
let endIndex = endRange.lowerBound
return String(remainingString[..<endIndex])
}
}

extension ARTRealtime {
Expand Down
45 changes: 18 additions & 27 deletions Test/AblyTests/Tests/RestClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2078,39 +2078,30 @@ class RestClientTests: XCTestCase {
let test = Test()
let options = ARTClientOptions(key: "xxxx:xxxx")
options.addRequestIds = true
let client = ARTRest(options: options)
let internalLog = InternalLog(clientOptions: options)
let mockHTTP = MockHTTP(logger: internalLog)
testHTTPExecutor = TestProxyHTTPExecutor(http: mockHTTP, logger: internalLog)
client.internal.httpExecutor = testHTTPExecutor
mockHTTP.setNetworkState(network: .hostUnreachable, resetAfter: 2)
let channel = client.channels.get(test.uniqueChannelName())

let restA = ARTRest(options: options)
let mockHttpExecutor = MockHTTPExecutor()
restA.internal.httpExecutor = mockHttpExecutor
waitUntil(timeout: testTimeout) { done in
restA.channels.get(test.uniqueChannelName()).publish(nil, data: "something") { error in
XCTAssertNil(error)
guard let url = mockHttpExecutor.requests.first?.url else {
fail("No requests found")
return
}
expect(url.query).to(contain("request_id"))
done()
}
}

mockHttpExecutor.reset()

options.addRequestIds = false
let restB = ARTRest(options: options)
restB.internal.httpExecutor = mockHttpExecutor
waitUntil(timeout: testTimeout) { done in
restB.channels.get(test.uniqueChannelName()).publish(nil, data: "something") { error in
channel.publish(nil, data: "") { error in
XCTAssertNil(error)
XCTAssertEqual(mockHttpExecutor.requests.count, 1)
guard let url = mockHttpExecutor.requests.first?.url else {
fail("No requests found")
return
}
XCTAssertNil(url.query)
done()
}
}

let requests = testHTTPExecutor.requests
XCTAssertEqual(requests.count, 3)
let capturedURLs = requests.map { $0.url!.absoluteString }
XCTAssertTrue(NSRegularExpression.match(capturedURLs.at(0), pattern: "//rest.ably.io"))
XCTAssertTrue(NSRegularExpression.match(capturedURLs.at(1), pattern: "//[a-e].ably-realtime.com"))
XCTAssertTrue(NSRegularExpression.match(capturedURLs.at(2), pattern: "//[a-e].ably-realtime.com"))

let requestIds = capturedURLs.map { $0.substring(after: "request_id=") }
XCTAssertEqual(Set(requestIds).count, 1) // all requestIds are equal
}

func test__096__RestClient__request_IDs__should_remain_the_same_if_a_request_is_retried_to_a_fallback_host() {
Expand Down
Loading