Alamofire/Alamofire

In iOS 8 custom `NSURLProtocol`s will not inherit Alamofire's configured session headers

jonah-williams opened this issue · 5 comments

See http://www.openradar.appspot.com/17809816

When adding `HTTPAdditionalHeaders` to an `NSURLSession` and setting it up with an `NSURLProtocol`, the request seen by `NSURLProtocol` should contain all the HTTP headers, including the ones from HTTPAdditionalHeaders.

Expected Results:
In the protocol’s `startLoading` method, `self.request.allHTTPHeaderFields` should contain both the headers added to this specific request, and the additional headers setup on the session

Actual Results:
In iOS8, this isn't the case. Only the request-specific headers are present.

So this isn't a bug in Alamofire. However it is a surprising failure for anyone using the library. It also means that the approach to keeping network activity indicators in sync with Alamofire requests suggested in #185 is incompatible with custom (or Alamofire's default) headers in iOS 8.

While I hate to add OS version conditional code it might be worthwhile to copy the session configuration's headers onto each request rather than count on the session to apply them.

Unfortunately I don't see a way the NSURLProtocol which exposes this issue could solve it because by the time the protocol receives the request it does not have access to the session or the session's configuration so there's no convenient way for the URL protocol to retrieve and apply that configuration.

mattt commented

Thanks for bringing this behavior to our attention, but I don't really see how this is related to #185. Why would an NSURLProtocol need to be aware of a session's additional HTTP headers?

I mean to say that an NSURLProtocol implementation like https://github.com/marcelofabri/BigBrother does not have an opportunity to add the HTTPAdditionalHeaders to the request. Since this is an issue only when using a custom NSURLProtocol my first reaction was to try to find a protocol implementation which could support the expected behavior however that does not seem to be an option. Instead I think any workaround to include these headers needs to be performed by Alamofire.

cnoon commented

Hi @jonah-williams, while I see where you are coming from, I don't think this very specific case is something the Alamofire should attempt to handle for all users. The client logic could append the additional headers to each NSURLRequest directly, rather than attaching them to the NSURLSessionConfiguration.

Additionally, we are going to add header support to the request, download and upload convenience methods in the upcoming 1.3.0 release. This should also make handling this edge case much easier until Apple corrects the underlying issue.

Thoughts?

As I continue to work on an app using Alamofire I'm increasingly uncertain that Alamofire should recommend custom NSURLProtocol implementations as a means of adding behavior around Alamofire managed requests.

In addition to not having access to session configured headers, a custom NSURLProtocol also requires re-implementing cache control and any other features I haven't noticed I'm missing from the default protocol implementations. Since NSURLProtocols are not chainable, a user of the library has to compose any and all desired behaviors into a single protocol implementation. This means that those protocol implementations are difficult to share and distribute.

Rather than a workaround here perhaps a more appropriate change would be to provide hooks into the Alamofire request queue so that other components could react to requests starting and stopping; for example to update a network activity indicator.

cnoon commented

Thank you very much for your detailed assessment @jonah-williams. After digging into this, I completely agree with your overall frame of mind. The NSURLProtocol does not respect all aspects of the session configuration which can lead to all sorts of problems as you have already pointed out.

I created a URLProtocolTestCase to replicate this behavior in b92f4e0. This at least let's us track this behavior on all our tested platforms. I'm sure we'll end up adding more tests in the future here. If you can think of any other useful test cases here or would be willing to write some others, I would be much obliged.

With all that said, I think it is probably wise to no longer recommend using an NSURLProtocol with Alamofire for anything other than for mocking out test responses. I think it could be very useful here and this is something that we're interested in documenting in a future release.