Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ETag and If-None-Match HTTP Headers are not working

I have a file in my webserver and I am downloading that to my app everytime I access it because its possible that file content might be changed But If it is changed I would like to download that time only so bandwidth can be saved and fortunately that's what this ETag and If-None-Match header fields are for.

  • When I make a request first time ,I retrieve the ETag from the HTTP response headers

First time request to the file

  • In the subsequent requests to download that file I'd attach the Etag value for If-None-Match headerfield so that if there is no change then I'd get HTTP response status code 304 or else I'd get 200 if there is a change in the file.

    Second time request for same file

Note:

When I try the above steps in Advanced REST Client Application in chrome it works fine as it is supposed to be but when I try that in iOS I always get the response code 200 but it should have given me 304 for the subsequent requests.

Here is the sample code I use

var request1 =  NSMutableURLRequest(URL:NSURL(string: "http://10.12.1.101/Etag/ringtone1.mp3")!)
let Etagvalue="\"36170-52c1cc36d9b40\""
var session1 = NSURLSession.sharedSession()
request1.HTTPMethod = "GET"
var err: NSError?
request1.addValue(Etagvalue, forHTTPHeaderField: "If-None-Match")

var task = session1.dataTaskWithRequest(request1, completionHandler: {data, response, error -> Void in
       print("response: \(response)")

})

Here is the response

response: Optional( { URL: http://10.12.1.101/Etag/ringtone1.mp3 } { status code: 200, headers { "Accept-Ranges" = bytes; Connection = "Keep-Alive"; "Content-Length" = 221552; "Content-Type" = "audio/mpeg"; Date = "Wed, 24 Feb 2016 14:57:53 GMT"; Etag = "\"36170-52c1cc36d9b40\""; "Keep-Alive" = "timeout=5, max=100"; "Last-Modified" = "Fri, 19 Feb 2016 10:15:33 GMT"; Server = "Apache/2.4.16 (Unix) PHP/5.5.29"; } })

What am I doing wrong here ?

like image 256
Durai Amuthan.H Avatar asked Feb 24 '16 16:02

Durai Amuthan.H


People also ask

What is if-none-match in HTTP header?

The If-None-Match HTTP request header makes the request conditional. For GET and HEAD methods, the server will return the requested resource, with a 200 status, only if it doesn't have an ETag matching the given ones.

What is ETag in HTTP header?

An ETag (entity tag) is an HTTP header that is used to validate that the client (such as a mobile device) has the most recent version of a record. When a GET request is made, the ETag is returned as a response header. The ETag also allows the client to make conditional requests.

Is ETag a weak validator?

ETag supports strong and weak validation of the resource. Strong ETag indicates that resource content is same for response body and the response headers. Weak ETag indicates that the two representations are semantically equivalent.


2 Answers

I've encountered the same problem. I've discovered that it's because of cachePolicy. You need to set it as follows:

request.cachePolicy = .ReloadIgnoringLocalAndRemoteCacheData

And you will be OK

like image 70
Andrey M. Avatar answered Sep 27 '22 22:09

Andrey M.


CachePolicy naming convention is confusing and better yet it actually does not implement some of them...

This article explains them well. http://nshipster.com/nsurlcache/

Also, if you let the Cache Policy to use UseProtocolCachePolicy then your NSURLSession will receive Status code 200 with response generated from Cache.

like image 40
naqi Avatar answered Sep 27 '22 21:09

naqi