Cache some API requests in Nginx

I’m seeking advise from experts here.

We have the following scenario. We have a java application. Java app is
running on tomcat7. tomcat7 acting as API server. User interface files (
Static html and css ) are served by nginx. Nginx is acting as reverse
proxy
here. All API request are passed to API server and rest are being server
by
nginx directly.

What we want is to implement cache mechanism here. That is means we want
to
enable cache for all but with few exception. We want to exclude some API
requests from being cached.

Our configuration is like as shown below

server {

listen 443 ssl;
server_name ~^(?.+).ourdomain.com$;
add_header X-Frame-Options “SAMEORIGIN”;
add_header X-XSS-Protection “1; mode=block”;

if ($request_method !~ ^(GET|HEAD|POST)$ )
{
return 405;
}

open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

location / {

root /var/www/html/userUI;

location ~* .(?:css|js)$ {
expires 1M;
access_log off;
add_header Pragma public;
add_header Cache-Control “public, must-revalidate, proxy-revalidate”;

}

location ~*
.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$
{
expires 1M;
access_log off;
add_header Pragma public;
add_header Cache-Control “public, must-revalidate, proxy-revalidate”;

}

}

location /server {

proxy_pass http://upstream/server;
proxy_set_header Host $subdomain.ourdomain.com;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_temp_path /var/nginx/proxy_temp;
proxy_next_upstream error timeout invalid_header http_500 http_502
http_503
http_504;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
proxy_set_header Host $host;
proxy_redirect off;
proxy_cache sd6;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_cache_bypass $http_cache_control;

}

ssl on;
ssl_certificate /etc/nginx/ssl/ourdomain.com.bundle.crt;
ssl_certificate_key /etc/nginx/ssl/ourdomain.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_ciphers “EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384
EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4
EECDH
EDH+aRSA HIGH !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS”;
ssl_dhparam /etc/nginx/ssl/dhparams.pem;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_prefer_server_ciphers on;
ssl_session_timeout 24h;
keepalive_timeout 300;

As above, we use cache only for static files located in
/var/www/html/userUI

We want to implement as such in location /server. This our api server.
Means
nginx passes api request to tomcat7 ( upstream ) server. We want to
enable
cache for specific API requests only but need to disable cache for rest
of
all requests.

We want to do the following

Exclude all json requests from cache and but need to enable cache for
few.

Request url will be something like as shown below

Request
URL:https://ourdomain.com/server/user/api/v7/userProfileImage/get?loginName=user1&_=1453442399073

What this url does is to get the Profile image. We want to enable cache
for
this specific url. So condition we would like to use is , if request url
contains “/userProfileImage/get” we want to set cache and all other
requests
shouldn’t cache.

All our api request goes through
https://ourdomain.com/server/user/api/v7/

To achieve this we changed the settings to following

location /server {

set $no_cache 0;

if ($request_uri ~* “/server/user/api/v7/userProfileImage/get*”)

{
set $no_cache 1;
}

proxy_pass http://upstream/server;
proxy_set_header Host $subdomain.ourdomain.com;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_temp_path /var/nginx/proxy_temp;
proxy_next_upstream error timeout invalid_header http_500 http_502
http_503
http_504;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
proxy_set_header Host $host;
proxy_redirect off;
proxy_cache sd6;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_no_cache $no_cache;
proxy_cache_bypass $no_cache;

}

Below are the results of http responses

General :

Request URL:https://ourdomain.com/server/common/...oginName=user1
Request Method:GET
Status Code:200 OK
Remote Address:131.212.98.12:443

Response Headers :

Cache-Control:no-cache, no-store, must-revalidate
Connection:keep-alive
Content-Type:image/png;charset=UTF-8
Date:Fri, 22 Jan 2016 07:36:56 GMT
Expires:Thu, 01 Jan 1970 00:00:00 GMT
Pragma:no-cache
Server:nginx
Transfer-Encoding:chunked
X-Proxy-Cache:MISS

It would be great if someone could provide a solution.

Posted at Nginx Forum: