Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cache-related HTTP headers are overridden in Servlet response on App Engine

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.

like image 403
icza Avatar asked Jan 05 '13 14:01

icza


1 Answers

According to the docs, the headers should only be overwritten if the logged-in user is an administrator. Did you check if this is the case?

like image 157
Patrick Simpson Avatar answered Sep 24 '22 13:09

Patrick Simpson