New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added headers not sent when following redirects #798
Comments
|
Thanks for filing this issue @eburi. I'll need to put some tests together to figure out exactly why the headers are being dropped. Are you overriding any of the session delegate closures? |
|
Okay @eburi, you're going to have to take this one up with Apple. I've added a fairly robust test in cdeb5c1 that demonstrates the behavior. It appears that most headers are passed through from the original to the redirect request with the exception of the func testThatRedirectedRequestContainsAllHeadersFromOriginalRequest() {
// Given
let redirectURLString = "https://httpbin.org/get"
let URLString = "https://httpbin.org/redirect-to?url=\(redirectURLString)"
let headers = [
"Authorization": "1234",
"Custom-Header": "foobar",
]
// NOTE: It appears that most headers are maintained during a redirect with the exception of the `Authorization`
// header. It appears that Apple's strips the `Authorization` header from the redirected URL request. If you
// need to maintain the `Authorization` header, you need to manually append it to the redirected request.
Alamofire.Manager.sharedInstance.delegate.taskWillPerformHTTPRedirection = { session, task, response, request in
var redirectedRequest = request
if let
originalRequest = task.originalRequest,
headers = originalRequest.allHTTPHeaderFields,
authorizationHeaderValue = headers["Authorization"]
{
let mutableRequest = request.mutableCopy() as! NSMutableURLRequest
mutableRequest.setValue(authorizationHeaderValue, forHTTPHeaderField: "Authorization")
redirectedRequest = mutableRequest
}
return redirectedRequest
}
let expectation = expectationWithDescription("Request should redirect to \(redirectURLString)")
var response: Response<AnyObject, NSError>?
// When
Alamofire.request(.GET, URLString, headers: headers)
.responseJSON { closureResponse in
response = closureResponse
expectation.fulfill()
}
waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
// Then
XCTAssertNotNil(response?.request, "request should not be nil")
XCTAssertNotNil(response?.response, "response should not be nil")
XCTAssertNotNil(response?.data, "data should not be nil")
XCTAssertTrue(response?.result.isSuccess ?? false, "response result should be a success")
if let
JSON = response?.result.value as? [String: AnyObject],
headers = JSON["headers"] as? [String: String]
{
XCTAssertEqual(headers["Custom-Header"], "foobar", "Custom-Header should be equal to foobar")
XCTAssertEqual(headers["Authorization"], "1234", "Authorization header should be equal to 1234")
}
}All you need to do is override the Cheers. |
|
Thanks, for the quick reply! And now we know how to work around it! |
|
@cnoon I may be missing something, but why doesn't Alamofire just implement this in the Is it because, since Apple is doing it this way, we are assuming it's a security issue? If you are willing to accept a PR that implements this, I'd be happy to make one. I think it shouldn't be too difficult. However, I also understand if you don't want to do this, as it may be seen as a way to work around Apple's own security measures. |
|
It's most likely not implemented that way for security purposes, but more for usability. Forwarding on the If you do need to append the headers to the redirected request, you'll need to do so manually as shown in the test logic above. |
|
This work around does not work if you are using Is there a way for me to avoid manually building the Authorization header? |
How replicate this with Alamofire 5? |
|
You can control redirects through the |
|
Thanks @jshier for the helpful suggestion. If anyone wants a head start on the implementation, here's a quick Alamofire 5 example I put together once I got it working: let authorizationHeaderPreservingRedirectHandler: Redirector = {
let behavior = Redirector.Behavior.modify {
(task, request, response) in
var redirectedRequest = request
if let originalRequest = task.originalRequest,
let headers = originalRequest.allHTTPHeaderFields,
let authorizationHeaderValue = headers["Authorization"] {
redirectedRequest.setValue(authorizationHeaderValue, forHTTPHeaderField: "Authorization")
}
return redirectedRequest
}
let redirector = Redirector(behavior: behavior)
return redirector
}()
// --- Example request
let redirectURLString = "https://httpbingo.org/get"
let urlString = "https://httpbingo.org/redirect-to?url=\(redirectURLString)"
let accessToken = "1234example"
let headers = HTTPHeaders([HTTPHeader.authorization(bearerToken: accessToken)])
// ---
AF.request(urlString, method: .get, headers: headers)
.redirect(using: authorizationHeaderPreservingRedirectHandler)
.response {
response in
debugPrint(response)
} |
|
@larrylegend your code is solving my problems. thanks again |
|
Wow it's so long |
Xcode 7, iOS 9, Alamofire 2.0.1
When following a redirect, the headers added to the original request, will not be added to the new request.
Example (#788):
If the server responds with a 301 Moved permanently, a new request is made to the location returned. But the new request will not have the Authorization-Header set.
I saw #314, #317, and #424 But I think this is a different issue. IMHO Alamofire should either follow redirects and add the headers added to the original-request or it should not follow redirects at all and report them to the user. In #788 I found out the hard way looking at what was sent over the wire.
As a user of Alamofire, I don't get any notification/log-message, when the library is following a redirect. This is very handy, but I would expect, that the my extra-headers would also be applied to the new-request.
The text was updated successfully, but these errors were encountered: