Seppo420
Seppo420

Reputation: 2251

Caching issues w. custom web server. Chrome sends no If-Modified-Since header but still gets 304 every now and then

I'm using a custom web server built on NanoHTTPD, that I've added caching features to. There's only one part in the code that could throw a 304 Not Modified response:

           if(isNotModified(f,header,parms)){// if requested file has not been modified, let's make the browser use it's cache
                Response r= new Response( Response.Status.NOT_MODIFIED, MIME_PLAINTEXT,(String)null,null);
                //r.addHeader(key,val);
                r.addHeader("Last-Modified",""+f.lastModified());//FIXME: doesnt work with wget + prob others as well
                r.addHeader("ETag",f.getPath()+f.lastModified());

                return r;
            }

isNotModified method:

/**
 * check if the file has been modified since the last time client requested it
 * */
public boolean isNotModified(File ff,Properties header, Properties params){
    if(params.getProperty("bust")!= null ||params.getProperty("cachebust")!=null)
        return false; 
    if(ff.getName().endsWith(".pg"))
        return false;
    if(ff.getPath().indexOf("/api/")>=0)
        return false;
    if("no-cache".equalsIgnoreCase(header.getProperty("cache-control")))
        return false;

    String mod = header.getProperty("if-modified-since");//names are converted to lowercase fwiw

    if(mod==null)//this should happen whenever browser sends no if-modified-since
        return false;

    try{
        long l = Long.parseLong(mod);
        if(ff.lastModified()<=l)
            return true;
    }catch(Exception ex){
        ex.printStackTrace();
    }

    return false;
}

For some reason I'm still getting 304 with (at least) Chrome even though there is no If-Modified-Since specified in the header (or anything related to caching). This leads to the browser interpreting the resource as an empty string and breaking things.

Upvotes: 1

Views: 898

Answers (2)

Seppo420
Seppo420

Reputation: 2251

I fixed all the headers and added an Expires header w/o any help, but adding this did the trick:

if("no-cache".equalsIgnoreCase(header.getProperty("pragma")))
        return false;

Upvotes: 0

Mikko Ohtamaa
Mikko Ohtamaa

Reputation: 83358

The response code 304 is used by Chrome to indicate the response was served from a local cache instead of fetched from the server. As this is not a real HTTP response, but a faux object, it may confuse a lot of developers. It properties differ from genuine response objects. This is especially case with AJAX requests.

The suggested workaround is to send Expires header instead of Last-modified so that you have exact control when the browser users local cache and when the browser makes a request to the server.

With the case of Expires header

  • You will get faux HTTP 304 response until the time in Expires header is reached

  • After this the browser makes a real request to the server

Upvotes: 2

Related Questions