How to use Etag with sailsjs - express

I'm trying to improve the cache capabilities on my sails application.
Sails generate a Etag with its response but when I try to do a GET request with a header 'if-None-Match' containing the Etag from the previous answer I can't get a 304 not Modified response from the server (the response is indeed not Modified and the Etag I receive is the same as the previous one).
I'm using POSTMAN to test the server responses.
Is there a way for a sails server to send such status code on unmodified responses ? I can't find any resource for Etag usage in sails doc.
Thank you.

Sails.js is based on Express.js and the ETags are generated by Express.js. And according to this answer, weak ETags are generated using CRC32 (source), strong ETags are generated using MD5 (source).
I use DHC - REST/HTTP API Client with If-None-Match header, it works perfect (return 304 Not Modified).
And I found that's because POSTMAN send NO-CACHE header to the server for testing purpose
'cache-control': 'no-cache',
You can follow this answer and turn off this feature then everything will be fine.

Related

Does the must-revalidate cache-control header tell the browser to only download a cached file if it has changed?

If I want browsers to load PDF files from cache until they changed on the server, do I have to use max-age=0 and must-revalidate as cache-control headers?
If I would use another value (larger than 0) for max-age would that mean the revalidation would only happen once the max-age value was exceeded?
What would happen if I would only set the must-revalidate header without max-age?
I was reading through this question and I am not 100% sure.
Also, what exactly does revalidate mean? Does it mean the client asks the server if the file has changed?
On the contrary, I've read that cache-control no-cache pretty much does what I want to achieve. Cache and check with the server if there is a new version... so whats the correct way?
I assume you are asking about which headers should you configure to be sent from your server, and by "client" you mean "modern web browser"? Then the quoted question/answer is correct, so:
Yes, you should set both, but max-age=0 is enough, (must-revalidate is the default behavior)
Yes, correct, the response would be served from local cache until max-age expires, after that it would be revalidated (once), then again served from local cache and so on
It is kind of undefined, and differs between browsers and the way you send request (clicking link from html, hitting reload button, typing directly in address bar and hitting enter). Generally, response should not be served directly from cache but it could either just be revalidated or full response can be requested from server.
Revalidate means that client asks server to send the content only if it has been changed since it was last retrieved. In order for this to work, in response to initial request server will send either one or both of:
Etag header (which contains hashed value of the content), which client will cache and send back in revalidation request as If-None-Match header, so server can compare clients cached Etag value with the current Etag on server side. If the value did not change, server will respond with 304 Not Modified (and empty body), and if the value changed, server will respond with 200 and full (new) content
Last-Modified (which contains timestamp of the last content modification), and client will send that in revalidation request in If-Modified-Since header, which will be used on server side to detirmine the response (304 or 200)
Cache-control: no-cache might achieve the same effect in most of the (simple) cases. The situation where things get complicated is when there are intermediate caches between client and the server, or when you want to tweak client behavior (for example when sending AJAX requests) and that is when most of the caching directives come into use

HTTPS is required for GCM on iOS?

I am trying to create an app with Cordova which receives push notifications from my server. Can anyone tell me that I need a https:// connection for the APNS to work or it should work with http:// as well?
All FCM/GCM endpoints are https, the same endpoints are used whether you are sending to Android, iOS or web so you should always use https when sending messages through FCM/GCM.
Based from this documentation, the sample POST request should be https://gcm-http.googleapis.com/gcm/send.
A message request is made of 2 parts: HTTP header and HTTP body.
The HTTP header must contain the following headers:
Authorization: key=YOUR_API_KEY
Content-Type: application/json for JSON; application/x-www-form-urlencoded;charset=UTF-8 for plain text. If
Content-Type is omitted, the format is assumed to be plain text.
The HTTP body content depends on whether you're using JSON or plain
text.
You can follow this tutorial.

how does alamofire know when there is a change in a JSON online?

im working on an app which fetches json from a website. everything is working properly and im using alamofire .
but for some reason, when i post new content on the website and the json file changes, alamofire doesnt get the new content. instead, it loads the content from the cache instead of redownloading the new content.
the only workaround to this is to clear the cache which is a way that i do not prefer since the user will have to download the content all over again at each view load.
so what im asking is, is there a way to notify the alamofire method about the new content and try to load the new content instead of having me to implement a method to clear the cache?
Alamofire uses the Foundation URL loading system, which relies on NSURLCache. The cache behavior for HTTP requests is determined by the contents of your HTTP response's Cache-Control headers. For example, you may wish to configure your server to specify must-revalidate:
Cache-Control: max-age=3600, must-revalidate
You should also make sure your server is specifying ETag and Content-Length headers to make it easy to tell when content has changed.
NSHipster's writeup on NSURLCache has a few good examples. If you're totally new to web caching, I recommend you read the very helpful section 13 of the HTTP 1.1 spec, and possibly also this caching tutorial.

Restful Webservices Caching Data

Want to know where exactly data will be cached in Restful Webservices? Please avoid saying browsers cache Restful webservices data.
REST is based on HTTP.
In HTTP you do not know if you data is cached somewhere. It may be in the browser or in any node in between the client and the server.
However your REST-Server may add the Cache-Control HTTP header to its response, e.g. Cache-Control: No-Cache to mark the response as not to cache.
It is not assured if this will not be ignored by a proxy or whatever.
Your client can also request to not cache data. In jquery you just add cache: no to the AJAX-request and it will do the trick.
If jquery is not available you will have to use the if-modified-since header (http://www.w3.org/Protocols/HTTP/HTRQ_Headers.html#if-modified-since).
Probably this post cleared my doubt.
http://www.openlogic.com/wazi/bid/283625/Caching-web-service-results-can-enhance-Apache-application-performance.

Caching proxy with authenticated REST requests

Consider following scenario:
I have RESTful URL /articles that returns list of articles
user provide his credentials using Authorization HTTP header on each request
articles may vary from user to user based on his privileges
Its possible to use caching proxy, like Squid, for this scenario?
Proxy will see only URL /articles so it may return list of articles only valid for first user that generates the cache. Other users requesting URL /articles can see articles they don't have access to, which is not desirable of course.
Should I roll my own cache or some caching proxy software can be configured to base its cache on Authorization HTTP header?
One possibility to try is using the Vary: Authorization response header to instruct downstream caches to be careful about caching by varying the cached documents based on the request's Authorization header.
You may already be using this header if you use response-compression. The user generally requests a resource with the header Accept-Encoding: gzip, deflate; if the server is configured to support compression, then the response might come with the headers Content-Encoding: gzip and Vary: Accept-Encoding already.
By the HTTP/1.1 RFC section 14.8 (https://www.rfc-editor.org/rfc/rfc2616#section-14.8):
When a shared cache (see section 13.7) receives a request
containing an Authorization field, it MUST NOT return the
corresponding response as a reply to any other request, unless one
of the following specific exceptions holds:
1. If the response includes the "s-maxage" cache-control
directive, the cache MAY use that response in replying to a
subsequent request. But (if the specified maximum age has
passed) a proxy cache MUST first revalidate it with the origin
server, using the request-headers from the new request to allow
the origin server to authenticate the new request. (This is the
defined behavior for s-maxage.) If the response includes "s-
maxage=0", the proxy MUST always revalidate it before re-using
it.
2. If the response includes the "must-revalidate" cache-control
directive, the cache MAY use that response in replying to a
subsequent request. But if the response is stale, all caches
MUST first revalidate it with the origin server, using the
request-headers from the new request to allow the origin server
to authenticate the new request.
3. If the response includes the "public" cache-control directive,
it MAY be returned in reply to any subsequent request.