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.
Related
I used the Negated Regular Expressions in location but it does add the header but removes everything else that existed before. Even if I add it doesn’t consider the rest only hsts. I am not sure what is the best way to do this. add a header for anything else but "don't add this HSTS header if we're on API::P".
location ~ (?!^/p/) {
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
or
location ~ ^(/p/) {
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
Here is the logic that I have in mind.
if location == "/p/":
pass
else:
add_header ...HSTS...
Because of performance considerations, avoid using regex whenever possible. Either use two locations duplicating everything else that cannot be moved one level up:
location / {
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
... common configuration
}
location /p/ {
... common configuration
}
or use the map block (however this actually will make at least one PRCE library call):
map $uri $hsts {
~^/p/ "";
default "max-age=31536000; includeSubDomains";
}
server {
...
add_header Strict-Transport-Security $hsts always;
...
}
If evaluated variable used in the add_header directive will be empty, nginx won't add a header with an empty value - instead it won't add such a header at all.
For the two-locations configuration, every request started with /p/ will be handled with the location /p/ { ... }, and every other request will be handled with the location / { ... }. There is absolutely no need to use any regex locations for this particular case.
Please note that add_header directives are inherited from the previous configuration level if and only if there are no add_header directives defined on the current level.
Static files on my server served with browser caching via Cache-Control headers:
location ~* \.(css|js|gif|jpe?g|png)$ {
expires 1h;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
Is it possible to disable this header for certain IPs so they would not cache any files?
P.S. I need it for users who log in as administrators to see the last changes.
The expires directive can be controlled by a variable, usually generated by a map directive. See this document for details.
For example:
map $remote_addr $expires {
default 1h;
10.1.2.3 -1;
}
server {
...
location ~* \.(css|js|gif|jpe?g|png)$ {
expires $expires;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
}
It is assumed that the add_header statements can remain, even if expires is set to -1 to disable the caching.
I added the Access-Control-Allow-Origin under the server section. That works as expected for any 'images'. When I call the 'canonical link' (1.pdf) the Access-Control-Allow-Origin is missing in the response. Why? And how can that be solved?
I don't want do add this line to all of my canonical links.
server {
server_name myserver.de;
listen 10.11.12.13:443 ssl http2;
access_log /var/log/nginx/ssl_access.log;
error_log /var/log/nginx/ssl_error.log error;
add_header 'Access-Control-Allow-Origin' 'https://foo.bar';
location / {
root /data/images/;
location ~ (.*)/1.pdf$ {
#add_header 'Access-Control-Allow-Origin' 'https://foo.bar';
add_header Link "<http://foo.bar/a-pdf>; rel=\"canonical\"";
}
}
There could be several add_header directives. These directives are
inherited from the previous level if and only if there are no
add_header directives defined on the current level.
You can use ngx_headers_more module to solve this problem
If you don't want to use above module, try something like this
server {
set $headerA 'https://foo.bar';
set $headerB "";
if (something) {
set $headerB "something";
}
add_header 'Access-Control-Allow-Origin' $headerA;
add_header Link $headerB;
}
Only use add_header in the server block and remove all add_header from location block. Note that Link would not be returned if headerB is empty
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
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)$ {
...
}
}