Setting expire headers for static content with nginx - nginx

I'm using Nginx in front of Glassfish (java application server) to serve my static content. I'm using following setting to set the expire headers
location /javax.faces.resource/images/ {
proxy_pass http://xx.xxx.xx:8080/javax.faces.resource/images/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
expires 365d;
add_header Pragma public;
add_header Cache-Control "public";
}
I have also CSS and JS files inside /javax.faces.resource/ and want to set another expire header. How can I achieve this without breaking the setting for images?
Another question: I noticed that sometimes there is many Cache-Control entries in Response header. Is there a possibility to reset the properties instead of using add_header? Thanks
EDITED
server {
listen xx.x.yy.xxx:80;
server_name mydomain.com www.mydomain.com ;
rewrite ^/(.*) https://www.$server_name/$1 permanent;
}
server {
listen xx.x.yy.xxx:443; ## listen for ipv4
server_name www.mydomain.com;
ssl on;
ssl_certificate /etc/ssl/www.mydomain.com.2018.pem;
# Path to an SSL certificate;
ssl_certificate_key /etc/ssl/www.mydomain.com.2018.key;
# Path to the key for the SSL certificate;
client_max_body_size 20M;
access_log /var/log/nginx/mydomain.com.access.log upstreamlog;
error_log /var/log/nginx/mydomain.com.error.log;
rewrite_log on;
location / {
proxy_pass http://xx.x.yy.xxx:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header HTTPS "on";
}
location /nginx_status {
stub_status on;
access_log off;
# allow 1.1.1.1;
# deny all;
}
location /images/ {
proxy_pass http://xx.x.yy.xxx:8080/images/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
expires 365d;
add_header Pragma public;
add_header Cache-Control "public";
#add_header X-Cache-Status $upstream_cache_status;
#add_header Strict-Transport-Security max-age=15768000;
}
location /resources/desktop/images/ {
proxy_pass http://xx.x.yy.xxx:8080/resources/desktop/images/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
expires 365d;
add_header Pragma public;
add_header Cache-Control "public";
#add_header X-Cache-Status $upstream_cache_status;
#add_header Strict-Transport-Security max-age=15768000;
}
location /javax.faces.resource/images/ {
proxy_pass http://xx.x.yy.xxx:8080/javax.faces.resource/images/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
expires 365d;
add_header Pragma public;
add_header Cache-Control "public";
}
}

Related

Nginx proxy_cache miss if URI has slash

My nginx location block is:
location ^~ /get/preview {
add_header X-Proxy-Cache $upstream_cache_status;
proxy_buffering on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_ignore_headers Cache-Control Set-Cookie;
proxy_ssl_protocols TLSv1.3;
proxy_ssl_session_reuse on;
proxy_cache upstream;
proxy_cache_key $scheme$host$uri$is_args$args;
proxy_cache_methods GET HEAD;
proxy_cache_min_uses 0;
proxy_cache_valid 200 301 302 1h;
proxy_cache_use_stale updating;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_pass https://tar.backend.com;
}
This will be a HIT after the 1st request:
https://example.com/get/preview?fileId=17389&x=256&y=256&a=true&v=5fe320ede1bb5
This is always a MISS:
https://example.com/get/preview.png?file=/zedje/118812514_3358890630894241_5001264763560347393_n.jpg&c=5fe3256d45a8c&x=150&y=150
You should check "Expires" header from your upstream. Documentation said "parameters of caching may be set in the header fields “Expires” or “Cache-Control”."
Another option - maybe you have another location for .(png|jpg|css|js)$ files with different options.

nginx - enabling cache for .css file with gzip compression

I have following nginx config. if I remove the cache config for css everything works and all css files load perfectly via reverse proxy. but when I put in cache config for .css that results in 404 for all my css resources:
location ~* \.css {
add_header Cache-Control public;
add_header Pragma public;
add_header Vary Accept-Encoding;
expires 1M;
}
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
}
Nginx chooses a single location to process a request. That location needs to be complete. See how Nginx processes a request.
Your location ~* \.css block is missing the proxy_pass statement.
The proxy_set_header statements can be moved to the outer block and inherited by both location blocks.
For example:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
location / {
proxy_pass http://localhost:8080;
}
location ~* \.css {
add_header Cache-Control public;
add_header Pragma public;
add_header Vary Accept-Encoding;
expires 1M;
proxy_pass http://localhost:8080;
}

nginx reverse proxy disable cache

i use nginx as a reverse proxy to connect a api. The problem is when i send a query after add or remove something. Nginx send me the old json value. I tried to disabled cache but it's not working.
my nginx config:
location / {
sendfile off;
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
proxy_no_cache 1;
proxy_cache_bypass 1;
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header HTTPS $https;
}
i tried query without nginx and all work well in console
thank you!
According to the documentation proxy_cache you have to replace
proxy_no_cache 1;
proxy_cache_bypass 1;
proxy_no_cache and proxy_cache_bypass defines conditions under which the response will not be saved to a cache.
Then to disable the cache, you can replace these two condition with
proxy_cache off;
Here a full exemple that you can use to configure a proxy for a stateless api server
location /myapi {
# Proxy
proxy_set_header X-Localhost true;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080/myapi;
proxy_redirect off;
proxy_buffers 32 16k;
proxy_busy_buffers_size 64k;
proxy_cache off;
# Headers for client browser NOCACHE + CORS origin filter
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
expires off;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept' always;
allow all;
}

How to configure NGINX not to cache specific URL?

I have a NGINX server as front-end cache server and I'd like to disable cache on specific urls.
Here is the configuration on NGINX:
proxy_cache_path /tmp/nginx levels=1:2 keys_zone=my_zone:10m inactive=120m max_size=1000m;
proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";
server {
listen 10.0.0.45:80 default_server;
server_name proxy2.jjd;
include /etc/nginx/default.d/*.conf;
location / {
client_max_body_size 20m;
proxy_cache my_zone;
proxy_cache_bypass $http_cache_control;
proxy_no_cache $http_pragma $http_authorization $cookie_nocache $arg_nocache;
add_header X-Proxy-Cache-NGINX $upstream_cache_status;
add_header X-Real-IP $remote_addr;
add_header Cache-Control "public";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_redirect off;
}
}
Add the following location to avoid an url:
location ^~ /your-url/ {
add_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_redirect off;
}
It just assigns this location to the proxy and doesn't enable caching for it.
As I get it, you just need a nested location with a single string proxy_cache off; inside to disable caching for nested URLs. Like this:
location / {
proxy_cache my_zone;
proxy_cache_bypass $http_cache_control;
// other stuff related to proxying or other processing
location /do/not/cache/this/url/ {
proxy_cache off;
}
}
you can just specify location do proxy_pass only for disable cache
location /will/not/cache {
proxy_pass http://127.0.0.1:8080;
..set_header ..
}

Limit HTTP verbs without redundant config

I've got an Elasticsearch cluster plus Logstash and Kibana, and I only want to expose a read-only window into the indexes, with the exception of the index kibana-int so that dashboards can be saved.
I've found a suitable ES proxy config, and I've modified it to use limit_except to disallow write/modify to other indexes, but much of the config is needlessly duplicated. Is there a cleaner way to define this?
upstream elasticsearch {
server es-01.iad.company.com:9200;
server es-02.iad.company.com:9200;
}
server {
listen 9200;
server_name elasticsearch.proxy;
client_max_body_size 50m;
location / {
limit_except GET POST HEAD OPTIONS {
deny all;
}
proxy_pass http://elasticsearch;
proxy_redirect off;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass_header Access-Control-Allow-Origin;
proxy_pass_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
add_header Access-Control-Allow-Credentials true;
}
location /kibana-int/ {
proxy_pass http://elasticsearch;
proxy_redirect off;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass_header Access-Control-Allow-Origin;
proxy_pass_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
add_header Access-Control-Allow-Credentials true;
}
}
There are several ways:
Solution 1
You could put repeating config into file and include it.
Your config:
upstream elasticsearch {
server es-01.iad.company.com:9200;
server es-02.iad.company.com:9200;
}
server {
listen 9200;
server_name elasticsearch.proxy;
client_max_body_size 50m;
location / {
limit_except GET POST HEAD OPTIONS {
deny all;
}
include proxy.inc;
}
location /kibana-int/ {
include proxy.inc;
}
}
proxy.inc:
proxy_pass http://elasticsearch;
proxy_redirect off;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_hide_header Access-Control-Allow-Headers;
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
add_header Access-Control-Allow-Credentials true;
Solution 2
Other way is use nginx's directive inheritance.
upstream elasticsearch {
server es-01.iad.company.com:9200;
server es-02.iad.company.com:9200;
}
server {
listen 9200;
server_name elasticsearch.proxy;
client_max_body_size 50m;
proxy_redirect off;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_hide_header Access-Control-Allow-Headers;
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
add_header Access-Control-Allow-Credentials true;
location / {
limit_except GET POST HEAD OPTIONS {
deny all;
}
proxy_pass http://elasticsearch;
}
location /kibana-int/ {
proxy_pass http://elasticsearch;
}
}
BTW, your proxy_pass_header directives are needless. Nginx proxies almost all headers by default.

Resources