How to add headers to only specific files with nginx - nginx

I have pictures, and I want to add their headers to max, I have profile pictures which can be changed and post pictures, I want to add headers only for post pictures, but not to profile pictures, I have no idea how can I manage this. thank you, this is my configuration,
this is the path of posts, /post/name-of-the-picture.jpg
this is the path of users, /user/name-of-the-picture.jpg
I only want to add headers to post path
location ~* \.(css|js|png|gif)$ {
expires max;
add_header Pragma public;
add_header Cache-Control "public";
}

Currently we have two options to solve this:
Option 1:
Duplicated locations: NGINX looks for the best match. (a little better performance)
location /post/ {
post config stuff;
.
.
.
}
location ~* ^/post/.*\.(css|js|png|gif)$ {
post/files.(css|js|png|gif) config stuff;
expires max;
add_header Pragma public;
add_header Cache-Control "public";
}
location /user/ {
user folder config stuff;
.
.
.
}
location ~* ^/user/.*\.(css|js|png|gif)$ {
user/files.(css|js|png|gif) config stuff;
.
.
.
}
Option 2:
Nested locations: Filtered by extension in the inner location blocks
location /post/{
...
location ~* \.(css|js|png|gif)$ {
expires max;
add_header Pragma public;
add_header Cache-Control "public";
}
}
location /user/{
...
location ~* \.(css|js|png|gif)$ {
...
}
}

Related

How can I set Cache-Control globally in NGINX

I want to setup a general cache-control for all NGINX-Sites.
Here is an example of it:
location ~* \.(?:ico|gif|jpe?g|png|svg?z)$ {
expires 1y;
add_header Pragma public;
add_header Cache-Control public;
}
If I try to add this "location" setting to /etc/nginx/nginx.conf I got an error, that I can't set it here.
So is there a way to set this cache handling for all sites in nginx by default, without the need to edit each single host in /sites_available/ ?
No, you can't use location directive in contexts other than server or another location. However you can use the following workaround (this one can be added to the http context):
map $cache $public {
1 public;
}
map $cache $expires {
1 1y;
default off; # or some other default value
}
map $uri $cache {
~*\.(?:ico|gif|jpe?g|png|svg?z)$ 1;
}
expires $expires;
add_header Pragma $public;
add_header Cache-Control $public;
nginx won't add the header at all (or modify an existing header) if the value calculated via the map expression will be an empty string. But be aware of this documentation excerpt:
There could be several add_header directives. These directives are inherited from the previous configuration level if and only if there are no add_header directives defined on the current level.

NGINX cache only images, css, fonts in a specific directory

location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico)$ {
expires 15d;
add_header Cache-Control "public, no-transform";
}
I have the code above which is supposed to cache these files for 15 days. how do I fix it so that only the files coming from /js, /css, /img will get cached instead of all?
Change the location rule to:
location ~ ^/(js|css|img)/*\.(js|css|png|jpg|jpeg|gif|svg|ico)$ {
expires 15d;
add_header Cache-Control "public, no-transform";
}
That should work

Exclude folders from caching

In Plesk under Additional nginx directives I've added the following cache settings.
location ~* .(jpg|js|css)$ { #shortened
etag on;
if_modified_since exact;
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}
But in the wp-admin I have rewrites on the url's of these type of files.
How Do I exclude wp-admin/* and wp-includes/* from the block above?
Bit of background, I run a WordPress multisite in a subfolder. so
maildomain.com/wp-admin/stylesheet.css is actually located in
maildomain.com/wp/wp-admin/stylesheet.css
You can try to experiment with location parameter before caching directives, e.g.:
location ^~ /wp-admin/ {
}
location ~* .(jpg|js|css)$ { #shortened
etag on;
if_modified_since exact;
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}
UPD. Yes, checked it on my test lab and got the 403 error. I guess empty section is not enough and some directives should be added explicitly.
Managed to add exclusion like the one below:
location ~* "^/(?!wp-admin/|wp-includes/).*\.(jpg|js|css)$" { #shortened
etag on;
if_modified_since exact;
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}

Setting cache-control on all folders' assets except one

I need to apply the following location rule for every single folder of my app with the exception of /forum and its children:
location ~* \.(?:jpg|jpeg|gif)$ {
expires 1M;
access_log off;
add_header Cache-Control "public";
}
I tried out setting it to location ~* ^/forum/.*\.(?:jpg|jpeg)$ but it doesn't look like it's working the way I want it to.
This is the solver I came up with:
location /forum {
...
}
location / {
location ~* \.(?:jpg|jpeg|gif)$ {
...
}
...
}
Simply separate the location directives and adjust commands accordingly.

NGINX and Lua scripting: conditional use in content_by_lua

I'm trying to create a conditional content_by_lua script, where the content should be set by lua only under a turthy condition.
example:
nginx.conf
location / {
content_by_lua_file /nginx/lua/nginx.lua;
root /nginx/www;
index index.html;
location ~* \.(?:ico|css|js|gif|jpe?g|png|woff|ttf)$ {
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
}
nginx.lua
if condition then
ngx.header["Content-type"] = "text/html"
ngx.say('<H1>Hello World.</H1>');
ngx.exit(0)
else
-- serve the original content (index.html)
end
the problem is - lua scripting under nginx doesnt support 2 content directive within the same route, is there a workaround I can do?
with the current usage when the condition false I expect the index.html to be shown but receive a blank page instead
You can do a ngx.exec call which does an internal call.
nginx.conf
location / {
content_by_lua_file /nginx/lua/nginx.lua;
root /nginx/www;
index index.html;
location ~* \.(?:ico|css|js|gif|jpe?g|png|woff|ttf)$ {
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
}
location /default_index {
root /nginx/www;
index index.html;
}
nginx.lua
if condition then
ngx.header["Content-type"] = "text/html"
ngx.say('<H1>Hello World.</H1>');
ngx.exit(0)
else
-- serve the original content (index.html)
ngx.exec("/default_index", ngx.var.args)
end

Resources