I have a servlet on App engine which serves images.
The servlet sets HTTP header values properly to indicate that the images should be cached. But App Engine overrides these headers which results in the images not being cached.
Note that the same code worked before, but it doesn't work for some time now.
The App engine documentation states that if Cache-Control
, Expires
and Vary
headers are set by the servlet, they will be left unmodified:
https://developers.google.com/appengine/docs/java/runtime#Responses
This is my sample code:
response.setContentType( "image/jpeg" );
//response.setDateHeader( "Expires", new Date().getTime() + 60L*24*60*60*1000 ); // 60 days cache time
//response.addHeader( "Cache-Control", "public, max-age=5184000" ); // 5_184_000 sec = 60 days cache time
response.addHeader( "Cache-Control", "public, max-age=90000" ); // 90_000 sec = 25 hours cache time
response.getOutputStream().write( data ); // Data is a byte array containing the JPEG image data
(I've tried putting all in that is commented out.)
Examining the HTTP request-response, the response contains the following headers:
HTTP/1.1 200 OK
status: 200 OK
version: HTTP/1.1
cache-control: public, max-age=90000
cache-control: no-cache, must-revalidate
content-length: 6777
content-type: image/jpeg
date: Sat, 05 Jan 2013 14:11:47 GMT
expires: Fri, 01 Jan 1990 00:00:00 GMT
pragma: no-cache
server: Google Frontend
As you can see, App Engine inserts cache-control
, expires
and pragma
headers disabling caching. Note that this is due to the request has a cookie
header. But also the documentation at
https://developers.google.com/appengine/docs/java/runtime#Responses
states that in this case (when cookie is set), App engine will configure caching to be private so browsers will still be able to cache it but not intermediate proxy servers.
The cookies are not even added by me but Google Analytics code (I've enabled Google Analytics on the page).
What am I doing wrong? How can I achieve proper caching of the servlet response?
EDIT: Further investigation showed that cookies are added to requests because I use Google Authentication, and if a user is logged in using his/her Google account, user related cookies are added, understandably. If no user is logged in, the caching is not overridden. So my further question is: Is there a way to cache servlet-served images when the user is logged in with a Google account?
EDIT, SOLUTION: Google App Engine only disables caching if an admin user of the app is the client. In this case, App Engine automatically inserts headers intended only for the admin, for example the estimated cost of the request. This is private info so it is understandable caching is disabled.