Question

I am trying to configure an Expires header for static files on nginx (0.7.67). The static files are served from a Golang reverse proxy:

location /rev/ {
  proxy_pass http://localhost:8910/;
  proxy_redirect off;
  proxy_set_header  Host               $host;
  proxy_set_header  X-Real-IP          $remote_addr;
  proxy_set_header  X-Forwarded-For    $proxy_add_x_forwarded_for;
  proxy_set_header  X-Forwarded-Proto  https;

  # I am putting this here, because nginx only uses one location. Is this OK?
  location ~* \.(js|css|jpg|jpeg|gif|png|svg|ico|pdf|html|htm)$ {
    expires 30d;
  }
}

When I do it this way there is no error restarting nginx, but the static files are not served anymore.

I already tried the following constellation, but it's not working:

server {
  ...
  location /rev/ {
    proxy_pass http://localhost:8910/;
    proxy_redirect off;
    proxy_set_header  Host               $host;
    proxy_set_header  X-Real-IP          $remote_addr;
    proxy_set_header  X-Forwarded-For    $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto  https;
  }

  location ~* \.(js|css|jpg|jpeg|gif|png|svg|ico|pdf|html|htm)$ {
      expires 30d;
  }
}

Question: How can I apply an expires header for static files which are located on an application behind a reverse proxy?

Was it helpful?

Solution

The only way i have managed to accomplish it was this way:

location / {
    proxy_pass  http://tomcat;
}

# CACHING WITH NO LOGGING
location ~* ^.+\.(atom|bmp|bz2|doc|docx|eot|exe|gif|gz|ico|jpeg|jpg|mid|midi|mp4|ogg|ogv|otf|pdf|png|ppt|pptx|rar|rss|rtf|svg|svgz|swf|tar|tgz|ttf|txt|wav|woff|xls|zip)$ {
    access_log  off;
    log_not_found   off;
    expires     max;
    proxy_pass  http://tomcat;
}

# CACHING WITH 404 LOGGING
location ~* ^.+\.(css|js|xml)$ {
    access_log  off;
    log_not_found   on;
    expires     max;
    proxy_pass  http://tomcat;
}

Hope it helps!

OTHER TIPS

From reading the docs at http://wiki.nginx.org/HttpProxyModule I find mentions of using the proxy_cache_* directives to achieve similar functionality, although not exactly what you're after. The docs state that:

Upstream cache-related directives have priority over proxy_cache_valid value,
in particular the order is:

X-Accel-Expires
Expires/Cache-Control
proxy_cache_valid

So it seems that setting the Expires header at the proxy level may not be supported, or recommended.

I have a feeling that you should be setting the Expires header up-stream. This can be done in Go (slightly hackishly, I'm sure there's a nicer way to fix the time-zone in the string) by setting the header on the http.ResponseWriter in your http handler function:

w.Header().Set("Expires", strings.Replace(time.Now().AddDate(0, 0, 30).Format(time.RFC1123), "UTC", "GMT", 1))

As previously stated, this replaces UTC with GMT in the output string. I'm not sure if it's necessary, but I've noticed this seems to be the common form in any HTTP headers I've inspected. I haven't looked up the spec to see if UTC would be equally accepted by browsers, but I don't see why not.

Sorry it's not really an Nginx answer, hopefully it helps!

I think the expires directive or add_header is what you return to the browser.

If you blindly want to cache what comes from the backend, you can try:

proxy_cache_valid any 1m;

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_valid

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top