From 119c7ffd079a21f1d1e42038f49a03fea0564522 Mon Sep 17 00:00:00 2001 From: Scott Berrevoets Date: Fri, 14 Sep 2018 17:25:10 -0700 Subject: [PATCH 1/5] Drop special headers from redirected requests --- CHANGELOG.md | 3 ++ OHHTTPStubs/Sources/OHHTTPStubs.m | 18 +++++++--- .../UnitTests/Test Suites/NSURLSessionTests.m | 36 ++++++++++--------- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48377a3e..2d287010 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ * Added `isMethodHEAD()` to the `Swift` helpers. [@Simon-Kaz](https://github.com/Simon-Kaz) [#294](https://github.com/AliSoftware/OHHTTPStubs/pull/294) +* Fixed issue with not preserving correct headers when following 3xx + redirects. + [@sberrevoets](https://github.com/sberrevoets) ## [6.1.0](https://github.com/AliSoftware/OHHTTPStubs/releases/tag/6.1.0) diff --git a/OHHTTPStubs/Sources/OHHTTPStubs.m b/OHHTTPStubs/Sources/OHHTTPStubs.m index ff21e64f..34fbab10 100644 --- a/OHHTTPStubs/Sources/OHHTTPStubs.m +++ b/OHHTTPStubs/Sources/OHHTTPStubs.m @@ -360,12 +360,12 @@ - (id)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLRespons + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request { - return request; + return request; } - (NSCachedURLResponse *)cachedResponse { - return nil; + return nil; } - (void)startLoading @@ -442,13 +442,23 @@ - (void)startLoading case 301: case 302: case 307: - case 308: + case 308: { //Preserve the original request method and body, and set the new location URL mReq = [self.request mutableCopy]; [mReq setURL:redirectLocationURL]; + + // Drop certain headers in accordance with + // https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1411532-httpadditionalheaders + [mReq setValue:nil forHTTPHeaderField:@"Authorization"]; + [mReq setValue:nil forHTTPHeaderField:@"Connection"]; + [mReq setValue:nil forHTTPHeaderField:@"Host"]; + [mReq setValue:nil forHTTPHeaderField:@"Proxy-Authenticate"]; + [mReq setValue:nil forHTTPHeaderField:@"Proxy-Authorization"]; + [mReq setValue:nil forHTTPHeaderField:@"WWW-Authenticate"]; redirectRequest = (NSURLRequest*)[mReq copy]; - break; + break; + } default: redirectRequest = [NSURLRequest requestWithURL:redirectLocationURL]; break; diff --git a/OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m b/OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m index cc84b104..66d93de0 100644 --- a/OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m +++ b/OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m @@ -105,10 +105,11 @@ - (void)_test_NSURLSession:(NSURLSession*)session - (void)_test_redirect_NSURLSession:(NSURLSession*)session httpMethod:(NSString *)requestHTTPMethod + headers:(NSDictionary *)headers jsonBody:(NSDictionary*)json delays:(NSTimeInterval)delay redirectStatusCode:(int)redirectStatusCode - completion:(void(^)(NSString* redirectedRequestMethod, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse))completion + completion:(void(^)(NSString* redirectedRequestMethod, NSDictionary * redirectedRequestHeaders, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse))completion { if ([NSURLSession class]) { @@ -116,6 +117,7 @@ - (void)_test_redirect_NSURLSession:(NSURLSession*)session const NSTimeInterval responseTime = delay; __block __strong NSString* capturedRedirectedRequestMethod = nil; + __block __strong NSDictionary* capturedRedirectedRequestHeaders = nil; __block __strong id capturedRedirectedRequestJSONBody = nil; __block __strong NSHTTPURLResponse* capturedRedirectHTTPResponse = nil; __block __strong id capturedResponseJSONBody = nil; @@ -139,6 +141,7 @@ - (void)_test_redirect_NSURLSession:(NSURLSession*)session return [[[request URL] path] isEqualToString:@"/newlocation"]; } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *redirectedRequest) { capturedRedirectedRequestMethod = redirectedRequest.HTTPMethod; + capturedRedirectedRequestHeaders = redirectedRequest.allHTTPHeaderFields; if (redirectedRequest.OHHTTPStubs_HTTPBody) { capturedRedirectedRequestJSONBody = [NSJSONSerialization JSONObjectWithData:redirectedRequest.OHHTTPStubs_HTTPBody options:0 error:NULL]; } else { @@ -155,6 +158,7 @@ - (void)_test_redirect_NSURLSession:(NSURLSession*)session // Building the initial request. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"foo://unknownhost:666/oldlocation"]]; request.HTTPMethod = requestHTTPMethod; + request.allHTTPHeaderFields = headers; if (requestBody) { request.HTTPBody = requestBody; @@ -193,7 +197,7 @@ - (void)_test_redirect_NSURLSession:(NSURLSession*)session [task resume]; [self waitForExpectationsWithTimeout:(requestTime+responseTime)*2+0.1 handler:nil]; - completion(capturedRedirectedRequestMethod, capturedRedirectedRequestJSONBody, + completion(capturedRedirectedRequestMethod, capturedRedirectedRequestHeaders, capturedRedirectedRequestJSONBody, capturedRedirectHTTPResponse, capturedResponseJSONBody, capturedResponseError); } @@ -214,8 +218,8 @@ - (void)test_SharedNSURLSession XCTAssertEqualObjects(jsonResponse, json, @"Unexpected data received"); }]; - [self _test_redirect_NSURLSession:session httpMethod:@"GET" jsonBody:nil delays:0.1 redirectStatusCode:301 - completion:^(NSString *redirectedRequestMethod, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) + [self _test_redirect_NSURLSession:session httpMethod:@"GET" headers:nil jsonBody:nil delays:0.1 redirectStatusCode:301 + completion:^(NSString *redirectedRequestMethod, NSDictionary *redirectedRequestHeaders, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) { XCTAssertEqualObjects(redirectedRequestMethod, @"GET", @"Expected redirected request to use GET method"); XCTAssertNil(redirectedRequestJSONBody, @"Expected redirected request to have empty body"); @@ -245,8 +249,8 @@ - (void)test_NSURLSessionDefaultConfig XCTAssertEqualObjects(jsonResponse, json, @"Unexpected data received"); }]; - [self _test_redirect_NSURLSession:session httpMethod:@"GET" jsonBody:nil delays:0.1 redirectStatusCode:301 - completion:^(NSString *redirectedRequestMethod, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) + [self _test_redirect_NSURLSession:session httpMethod:@"GET" headers:nil jsonBody:nil delays:0.1 redirectStatusCode:301 + completion:^(NSString *redirectedRequestMethod, NSDictionary *redirectedRequestHeaders, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) { XCTAssertEqualObjects(redirectedRequestMethod, @"GET", @"Expected redirected request to use GET method"); XCTAssertNil(redirectedRequestJSONBody, @"Expected redirected request to have empty body"); @@ -272,8 +276,8 @@ - (void)test_NSURLSessionDefaultConfig_notFollowingRedirects NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:delegate delegateQueue:nil]; - [self _test_redirect_NSURLSession:session httpMethod:@"GET" jsonBody:nil delays:0.1 redirectStatusCode:301 - completion:^(NSString *redirectedRequestMethod, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) + [self _test_redirect_NSURLSession:session httpMethod:@"GET" headers:nil jsonBody:nil delays:0.1 redirectStatusCode:301 + completion:^(NSString *redirectedRequestMethod, NSDictionary *redirectedRequestHeaders, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) { XCTAssertNil(redirectedRequestMethod, @"Expected no redirected request to fire"); XCTAssertNil(redirectedRequestJSONBody, @"Expected no redirected request to fire"); @@ -313,8 +317,8 @@ - (void)test_NSURLSessionDefaultConfig_MethodAndDataRetentionOnRedirect NSURLSessionTestDelegate* delegate = [NSURLSessionTestDelegate delegateFollowingRedirects:YES fulfillOnCompletion:nil]; NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:delegate delegateQueue:nil]; - [self _test_redirect_NSURLSession:session httpMethod:method jsonBody:json delays:0.0 redirectStatusCode:statusCode - completion:^(NSString *redirectedRequestMethod, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) + [self _test_redirect_NSURLSession:session httpMethod:method headers:nil jsonBody:json delays:0.0 redirectStatusCode:statusCode + completion:^(NSString *redirectedRequestMethod, NSDictionary *redirectedRequestHeaders, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) { XCTAssertEqualObjects(redirectedRequestMethod, method, @"Expected the HTTP method to be unchanged after %d redirect", statusCode); @@ -338,8 +342,8 @@ - (void)test_NSURLSessionDefaultConfig_MethodAndDataRetentionOnRedirect NSURLSessionTestDelegate* delegate = [NSURLSessionTestDelegate delegateFollowingRedirects:YES fulfillOnCompletion:nil]; NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:delegate delegateQueue:nil]; - [self _test_redirect_NSURLSession:session httpMethod:method jsonBody:json delays:0.0 redirectStatusCode:303 - completion:^(NSString *redirectedRequestMethod, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) + [self _test_redirect_NSURLSession:session httpMethod:method headers:nil jsonBody:json delays:0.0 redirectStatusCode:303 + completion:^(NSString *redirectedRequestMethod, NSDictionary *redirectedRequestHeaders, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) { XCTAssertEqualObjects(redirectedRequestMethod, @"GET", @"Expected 303 redirected request HTTP method to be reset to GET"); XCTAssertNil(redirectedRequestJSONBody, @"Expected 303-redirected request to have empty body"); @@ -371,8 +375,8 @@ - (void)test_NSURLSessionEphemeralConfig XCTAssertEqualObjects(jsonResponse, json, @"Unexpected data received"); }]; - [self _test_redirect_NSURLSession:session httpMethod:@"GET" jsonBody:json delays:0.1 redirectStatusCode:301 - completion:^(NSString *redirectedRequestMethod, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) + [self _test_redirect_NSURLSession:session httpMethod:@"GET" headers:nil jsonBody:json delays:0.1 redirectStatusCode:301 + completion:^(NSString *redirectedRequestMethod, NSDictionary *redirectedRequestHeaders, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) { XCTAssertEqualObjects(redirectedRequestMethod, @"GET", @"Expected the HTTP method of redirected request to be GET"); XCTAssertEqualObjects(redirectedRequestJSONBody, json, @"Expected redirected request to have the same body as the original request"); @@ -404,8 +408,8 @@ - (void)test_NSURLSessionDefaultConfig_Disabled XCTAssertNil(jsonResponse, @"Data should not have been received as stubs should be disabled"); }]; - [self _test_redirect_NSURLSession:session httpMethod:@"GET" jsonBody:json delays:0.1 redirectStatusCode:301 - completion:^(NSString *redirectedRequestMethod, id redirectedRequestJSONBody, NSHTTPURLResponse *finalHTTPResponse, id finalJSONResponse, NSError *errorResponse) + [self _test_redirect_NSURLSession:session httpMethod:@"GET" headers:nil jsonBody:json delays:0.1 redirectStatusCode:301 + completion:^(NSString *redirectedRequestMethod, NSDictionary *redirectedRequestHeaders, id redirectedRequestJSONBody, NSHTTPURLResponse *finalHTTPResponse, id finalJSONResponse, NSError *errorResponse) { // Stubs were disabled for this session, so we should get an error instead of the stubs data XCTAssertNotNil(errorResponse, @"Expected error but none found"); From 2fecbdad3f4be1437109ea2570098cd67d2d041b Mon Sep 17 00:00:00 2001 From: Jeff Lett <2142301+jeffctown@users.noreply.github.com> Date: Fri, 8 Mar 2019 14:27:03 -0500 Subject: [PATCH 2/5] Update CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d287010..dfad2642 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,14 +3,14 @@ ## [Future release] * Enabled application extension API only. [@lightsprint09](https://github.com/lightsprint09) -* Disabled a flaky redirect test and adding the known issue with redirects to the README. +* Disabled a flaky redirect test and adding the known issue with redirects to the README. [@jeffctown](https://github.com/jeffctown) [#301](https://github.com/AliSoftware/OHHTTPStubs/pull/301) * Added `isMethodHEAD()` to the `Swift` helpers. [@Simon-Kaz](https://github.com/Simon-Kaz) [#294](https://github.com/AliSoftware/OHHTTPStubs/pull/294) * Fixed issue with not preserving correct headers when following 3xx - redirects. + redirects. [@sberrevoets](https://github.com/sberrevoets) ## [6.1.0](https://github.com/AliSoftware/OHHTTPStubs/releases/tag/6.1.0) From ed1379453316e50638e3b2b905ed82919832f778 Mon Sep 17 00:00:00 2001 From: Jeff Lett Date: Fri, 8 Mar 2019 18:00:27 -0500 Subject: [PATCH 3/5] =?UTF-8?q?Put=20clearing=20of=20auth=20headers=20in?= =?UTF-8?q?=20it=E2=80=99s=20own=20method=20and=20using=20a=20for=20loop.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OHHTTPStubs/Sources/OHHTTPStubs.m | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/OHHTTPStubs/Sources/OHHTTPStubs.m b/OHHTTPStubs/Sources/OHHTTPStubs.m index 34fbab10..3a0eaf8f 100644 --- a/OHHTTPStubs/Sources/OHHTTPStubs.m +++ b/OHHTTPStubs/Sources/OHHTTPStubs.m @@ -368,6 +368,24 @@ - (NSCachedURLResponse *)cachedResponse return nil; } +/** Drop certain headers in accordance with + * https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1411532-httpadditionalheaders + */ +- (NSMutableURLRequest *)clearAuthHeadersForRequest:(NSMutableURLRequest *)request { + NSArray* authHeadersToRemove = @[ + @"Authorization", + @"Connection", + @"Host", + @"Proxy-Authenticate", + @"Proxy-Authorization", + @"WWW-Authenticate" + ]; + for (NSString* header in authHeadersToRemove) { + [request setValue:nil forHTTPHeaderField:header]; + } + return request; +} + - (void)startLoading { self.clientRunLoop = CFRunLoopGetCurrent(); @@ -446,17 +464,10 @@ - (void)startLoading //Preserve the original request method and body, and set the new location URL mReq = [self.request mutableCopy]; [mReq setURL:redirectLocationURL]; - - // Drop certain headers in accordance with - // https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1411532-httpadditionalheaders - [mReq setValue:nil forHTTPHeaderField:@"Authorization"]; - [mReq setValue:nil forHTTPHeaderField:@"Connection"]; - [mReq setValue:nil forHTTPHeaderField:@"Host"]; - [mReq setValue:nil forHTTPHeaderField:@"Proxy-Authenticate"]; - [mReq setValue:nil forHTTPHeaderField:@"Proxy-Authorization"]; - [mReq setValue:nil forHTTPHeaderField:@"WWW-Authenticate"]; + + mReq = [self clearAuthHeadersForRequest:mReq]; + redirectRequest = (NSURLRequest*)[mReq copy]; - break; } default: From 4d0f05b9e5ebccfc1e54269697a6a9091a691b9e Mon Sep 17 00:00:00 2001 From: Scott Berrevoets Date: Fri, 8 Mar 2019 15:37:26 -0800 Subject: [PATCH 4/5] Re-introduce header retention policy tests for 3xx --- .../UnitTests/Test Suites/NSURLSessionTests.m | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m b/OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m index 66d93de0..18829c47 100644 --- a/OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m +++ b/OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m @@ -360,6 +360,51 @@ - (void)test_NSURLSessionDefaultConfig_MethodAndDataRetentionOnRedirect NSLog(@"/!\\ Test skipped because the NSURLSession class is not available on this OS version. Run the tests a target with a more recent OS.\n"); } } + +- (void)test_NSURLSessionDefaultConfig_HeaderRetentionPolicyOnRedirect { + if ([NSURLSessionConfiguration class] && [NSURLSession class]) + { + NSArray* allMethods = @[@"GET", @"HEAD", @"POST", @"PATCH", @"PUT"]; + + /** 301, 302, 307, 308: GET, HEAD, POST, PATCH, PUT should all maintain most HTTP headers unchanged **/ + for (NSNumber* redirectStatusCode in @[@301, @302, @307, @308]) { + int statusCode = redirectStatusCode.intValue; + for (NSString* method in allMethods) { + + NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration]; + NSURLSessionTestDelegate* delegate = [NSURLSessionTestDelegate delegateFollowingRedirects:YES fulfillOnCompletion:nil]; + NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:delegate delegateQueue:nil]; + + NSDictionary *headers = @{ + @"Authorization": @"authorization", + @"Connection": @"connection", + @"Host": @"host", + @"Proxy-Authenticate": @"proxy-authenticate", + @"Proxy-Authorization": @"proxy-authorization", + @"WWW-Authenticate": @"www-authenticate", + @"Preserved": @"preserved" + }; + [self _test_redirect_NSURLSession:session httpMethod:method headers:headers jsonBody:nil delays:0.0 redirectStatusCode:statusCode + completion:^(NSString *redirectedRequestMethod, NSDictionary *redirectedRequestHeaders, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) + { + XCTAssertNil(redirectedRequestHeaders[@"Authorization"], @"Authorization header is preserved when following redirects"); + XCTAssertNil(redirectedRequestHeaders[@"Connection"], @"Connection header is preserved when following redirects"); + XCTAssertNil(redirectedRequestHeaders[@"Host"], @"Host header is preserved when following redirects"); + XCTAssertNil(redirectedRequestHeaders[@"Proxy-Authenticate"], @"Proxy-Authenticate header is preserved when following redirects"); + XCTAssertNil(redirectedRequestHeaders[@"Proxy-Authorization"], @"Proxy-Authorization header is preserved when following redirects"); + XCTAssertNil(redirectedRequestHeaders[@"WWW-Authenticate"], @"WWW-Authenticate header is preserved when following redirects"); + XCTAssertEqual(redirectedRequestHeaders[@"Preserved"], @"preserved", @"Regular header is not preserved when following redirects"); + }]; + + [session finishTasksAndInvalidate]; + } + } + } + else + { + NSLog(@"/!\\ Test skipped because the NSURLSession class is not available on this OS version. Run the tests a target with a more recent OS.\n"); + } +} #endif - (void)test_NSURLSessionEphemeralConfig From 29ff8d80a31aa460b52338ae1a5ed2c808d7e1be Mon Sep 17 00:00:00 2001 From: Scott Berrevoets Date: Fri, 8 Mar 2019 16:06:08 -0800 Subject: [PATCH 5/5] fixup! Re-introduce header retention policy tests for 3xx --- OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m b/OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m index 18829c47..6ac3e93f 100644 --- a/OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m +++ b/OHHTTPStubs/UnitTests/Test Suites/NSURLSessionTests.m @@ -378,11 +378,12 @@ - (void)test_NSURLSessionDefaultConfig_HeaderRetentionPolicyOnRedirect { NSDictionary *headers = @{ @"Authorization": @"authorization", @"Connection": @"connection", + @"Preserved1": @"preserved" @"Host": @"host", @"Proxy-Authenticate": @"proxy-authenticate", @"Proxy-Authorization": @"proxy-authorization", + @"Preserved2": @"preserved", @"WWW-Authenticate": @"www-authenticate", - @"Preserved": @"preserved" }; [self _test_redirect_NSURLSession:session httpMethod:method headers:headers jsonBody:nil delays:0.0 redirectStatusCode:statusCode completion:^(NSString *redirectedRequestMethod, NSDictionary *redirectedRequestHeaders, id redirectedRequestJSONBody, NSHTTPURLResponse *redirectHTTPResponse, id finalJSONResponse, NSError *errorResponse) @@ -393,7 +394,8 @@ - (void)test_NSURLSessionDefaultConfig_HeaderRetentionPolicyOnRedirect { XCTAssertNil(redirectedRequestHeaders[@"Proxy-Authenticate"], @"Proxy-Authenticate header is preserved when following redirects"); XCTAssertNil(redirectedRequestHeaders[@"Proxy-Authorization"], @"Proxy-Authorization header is preserved when following redirects"); XCTAssertNil(redirectedRequestHeaders[@"WWW-Authenticate"], @"WWW-Authenticate header is preserved when following redirects"); - XCTAssertEqual(redirectedRequestHeaders[@"Preserved"], @"preserved", @"Regular header is not preserved when following redirects"); + XCTAssertEqual(redirectedRequestHeaders[@"Preserved1"], @"preserved", @"Regular header is not preserved when following redirects"); + XCTAssertEqual(redirectedRequestHeaders[@"Preserved2"], @"preserved", @"Regular header is not preserved when following redirects"); }]; [session finishTasksAndInvalidate];