views:

2707

answers:

3

I'm having a small problem with request caching using NSURLConnection asynchronous connections on the iPhone. I don't know if I understood something incorrectly, or if Cocoa is doing the opposite to what it's supposed to do...

The documentation for NSURLRequest says that:

NSURLRequestReloadIgnoringLocalCacheData

Specifies that the data for the URL load should be loaded from the originating source. No existing cache data should be used to satisfy a URL load request.

and:

NSURLRequestReloadIgnoringLocalAndRemoteCacheData

Specifies that not only should the local cache data be ignored, but that proxies and other intermediates should be instructed to disregard their caches so far as the protocol allows.

Now, if I send an NSURLRequest with NSURLRequestReloadIgnoringLocalCacheData (which is supposed to ignore local cache, but use remote cache if available), the headers that are sent are:

GET /dashboard HTTP/1.1
User-Agent: XBlip1.0 CFNetwork/422.15.2 Darwin/9.6.0 (i386) (iMac8%2C1)
X-Blip-Api: 0.02
Accept: application/json
Authorization: Basic (...)
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: api.blip.pl

And the status is 200 OK. But if I use NSURLRequestReloadIgnoringLocalAndRemoteCacheData, which is supposed to ignore both local and remote caches, as the name suggests, one additional header is added:

If-None-Match: "d751713988987e9331980363e24189ce"

And the response is 304 Not Modified. I've checked the HTTP RFC, and for "If-None-Match" it says that:

If any of the entity tags match the entity tag of the entity that would have been returned in the response to a similar GET request (without the If-None-Match header) on that resource, (...) then the server MUST NOT perform the requested method (...) Instead, if the request method was GET or HEAD, the server SHOULD respond with a 304 (Not Modified) response

So it seems that if I use NSURLRequestReloadIgnoringLocalAndRemoteCacheData, instead of ignoring the remote cache, Cocoa tells the remote server explicitly that it should use remote cache, and if I use NSURLRequestReloadIgnoringLocalCacheData, it doesn't add that line and in effect the remote cache is not used.

So what exactly is happening here? Did I miss something, or is Cocoa setting a wrong header?

+1  A: 

By adding the NSURLRequestReloadIgnoringLocalAndRemoteCacheData parameter you are instructing the local cache and any proxy servers which may handle the request between your client and the target server that they are not to return their own version of the response data. I think the key-component here is that the RemoteCache is likely to be a proxy and you are just identifying that the request should always reach the real server and not a proxied copy.

Adding the "stupidly-long-named" parameter you are inferring that your application already has a previous copy of the request and so is only interested in actually receiving data from the server if it has changed, that is why you are getting a response of "304 Not Modified" from the server.

This behaviour does seem counter-intuitive as you are explicitly instructing the client not to use its own cache, which would imply that you would want to discard anything in there and certainly not use it as a reference for any subsequent requests. I believe the advanced cache parameters are provided to allow the developer to handle their own level of caching, ie. be notified if data hasn't been updated on the server so they can avoid needless re-processing.

+1  A: 

Note the "proxies and other intermediates" part. You're only avoiding caches not residing on the original server. The original server can still return a 304.

Can Berk Güder
+2  A: 

From the documentation:

Specifies that not only should the local cache data be ignored, but that proxies and other intermediates should be instructed to disregard their caches so far as the protocol allows.

From NSURLRequest.h (10.5 SDK)

Specifies that not only should the local cache data be ignored, but that proxies and other intermediates should be instructed to disregard their caches so far as the protocol allows. Unimplemented.

Notice the difference: Unimplemented

Time for bug reporting...

0xced