nginx expires doesn't work - nginx

Here's the relevant nginx configuration fragment:
location ^~ /static/ {
expires max;
rewrite ^/static/[^/]+/(.*)$ /$1 last;
}
After reloading nginx there's no sign of the Expires header for some reason:
$ curl -i http://monda.hu/static/1/blog/wp-content/icomoon/style.css
HTTP/1.1 200 OK
Server: nginx/1.4.1 (Ubuntu)
Date: Sat, 21 Dec 2013 22:55:46 GMT
Content-Type: text/css
Content-Length: 1783
Last-Modified: Tue, 16 Jul 2013 21:03:00 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: "51e5b504-6f7"
Accept-Ranges: bytes
(The idea here is to increment the numeric version value in the URL whenever the related resource changes. Please do not tell me that expires max is a bad practice. I think it's a matter of taste and priorities.)
Other than the above there are the following location blocks present in the relevant server section:
location ~ \.php$ { ... }
location / { ... }
location ~ /\. { ... }
location ^~ /mydbadmin/ { ... }
location #php { ... } # this one is not even referenced

Related

Nginx don`t use cache after url rewrite

I want to use nginx as internet out proxy.
So, I try to connect to http://mirror01.org/google.com, but cache files were not created.
If I delete rewrite rule and replace proxy_pass to http://google.come cache files will be created.
Where did I go wrong?
Trace using curl
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.20.2
Date: Tue, 08 Mar 2022 15:44:42 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: http://google.com
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Tue, 08 Mar 2022 15:44:42 GMT
Expires: Thu, 07 Apr 2022 15:44:42 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
HTTP/1.1 200 OK
Content-Type: text/html; charset=ISO-8859-1
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Date: Tue, 08 Mar 2022 15:44:43 GMT
Server: gws
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Transfer-Encoding: chunked
Expires: Tue, 08 Mar 2022 15:44:43 GMT
Cache-Control: private
Set-Cookie: 1P_JAR=2022-03-08-15; expires=Thu, 07-Apr-2022 15:44:43 GMT; path=/; domain=.google.com; Secure
Set-Cookie: NID=511=21PQ3ziwDTFTppHDMUoAVReBsFB6oGkVHqT38eqJO25UQkP3SJSEleOsHhefVDR_TgKSK6DpcTmBewjKC-kazv8mWRrfW10NUJevh16H5MZtKrKCJxllfI4r; expires=Wed, 07-Sep-2022 15:44:43 GMT; path=/; domain=.google.com; HttpOnly
Nginx conf:
access_log /opt/nginx/log/access.log main;
error_log /opt/nginx/log/error.log crit;
proxy_cache_path /opt/nginx/cache levels=1:2 keys_zone=default_cache:10m max_size=2g
inactive=120m use_temp_path=off;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid any 60m;
server {
listen 80;
server_name mirror01.org;
location / {
proxy_cache default_cache;
proxy_buffering on;
proxy_ignore_headers Expires;
proxy_ignore_headers X-Accel-Expires;
proxy_ignore_headers Cache-Control;
proxy_ignore_headers Set-Cookie;
proxy_hide_header X-Accel-Expires;
proxy_hide_header Expires;
proxy_hide_header Cache-Control;
proxy_hide_header Pragma;
add_header X-Proxy-Cache $upstream_cache_status;
rewrite ^/(.*)$ http://$request_uri? break;
proxy_pass $request_uri;
}
}

Nginx Font Cashing

I'm desperately trying to figure out a way to set an expiry date on fonts in nginx to optimize on mobile.
I'm interested for ttf fonts.
I have mime.types as fallows:
application/font-woff woff;
application/vnd.ms-fontobject eot;
application/x-font-ttf ttc ttf;
font/opentype otf;
image/svg+xml svg svgz;
And on Nginx I have tried every solution I found on the web to no avail:
Try #1:
location ~* \.(?:eot|woff|woff2|ttf|svg|otf) {
access_log off;
log_not_found off;
expires 365d;
add_header Cache-Control "public";
add_header Access-Control-Allow-Origin *;
types {font/truetype ttf;}
}
Fail NO Expiry:
Request URL: http://localhost:3001/static/media/Poppins-Regular.8081832f.ttf
Request Method: GET
Status Code: 200 OK
Remote Address: [::1]:3001
Referrer Policy: strict-origin-when-cross-origin
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/x-font-ttf
Date: Thu, 01 Apr 2021 18:33:55 GMT
ETag: W/"60660e52-269f0"
Last-Modified: Thu, 01 Apr 2021 18:17:54 GMT
Server: nginx/1.15.2
Transfer-Encoding: chunked
Vary: Accept-Encoding
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: localhost:3001
Origin: http://localhost:3001
Referer: http://localhost:3001/static/css/main.06159cd9.chunk.css
Sec-Fetch-Dest: font
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Sec-GPC: 1
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36
Try #2:
location ~* \.(woff|ttf|otf|woff2|eot)$ {
expires 365d;
access_log off;
add_header Pragma public;
add_header Cache-Control "public, max-age=86400";
add_header X-Asset "yes";
}
Failed: Same result
Try: 3
https://io.24hoursmedia.com/tech-notes/nginx-send-browser-cache-headers-for-static-files
Failed: Same result
Try: 4
location ~* \.(?:jpg|jpeg|gif|png|ico|woff2)$ {
expires 1M;
add_header Cache-Control "public";
}
Failed: Same result
What I am missing? Please help.
Keep it simple. My NGINX looks like:
location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf)$ {
....
expires max;
add_header Cache-Control "public, no-transform";
}
And the response:
cache-control: max-age=315360000
cache-control: public, no-transform
content-length: 84508
content-type: font/woff2
date: Mon, 05 Apr 2021 19:08:55 GMT
etag: "603562a6-14a1c"
expires: Thu, 31 Dec 2037 23:55:55 GMT
last-modified: Tue, 23 Feb 2021 20:16:38 GMT
server: nginx
I have two different configurations for my fonts ...
types { application/x-font-ttf ttf}
AND
types {font/ttf ttf}
The second one is based on the new font standard released back in 2017.
https://www.iana.org/assignments/media-types/media-types.xhtml#font
... but I haven't seen font/truetype.
More Information: http://nginx.org/en/docs/http/ngx_http_core_module.html#types
If you want to fine-tune your expires value take a look here:
https://nginx.org/en/docs/http/ngx_http_headers_module.html#expires
{
map $sent_http_content_type $expires {
default off;
application/pdf 42d;
~image/ max;
}
server {
...
location ~*\.(woff|woff2...)$ {
...
expires $expires;
}
}
}

Why nginx works with error 301 HTTP1.1/Moved permanently?

I'm trying to configure Location directive on my nginx web-server (Ubuntu).
I can have access to:
http://127.0.0.1/app1/
BUT when I'm trying to get access whitout slash in the end like:
http://127.0.0.1/app1
I get an error 301 HTTP1.1/Moved permanently
I have following nginx config:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Looks like everything is OK.
And following default.conf:
server {
listen 80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location /app1/ {
root /var/www/html/;
index index.html;
try_files $uri $uri/ /app1/index.html;
}
}
Curl output
http://127.0.0.1/app1/
root#ubuntu-test:/etc/nginx/sites-available# curl 127.0.0.1/app1/ -Iv
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> HEAD /app1/ HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: nginx/1.14.0 (Ubuntu)
Server: nginx/1.14.0 (Ubuntu)
< Date: Thu, 20 Feb 2020 09:14:12 GMT
Date: Thu, 20 Feb 2020 09:14:12 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 5
Content-Length: 5
< Last-Modified: Tue, 18 Feb 2020 10:49:53 GMT
Last-Modified: Tue, 18 Feb 2020 10:49:53 GMT
< Connection: keep-alive
Connection: keep-alive
< ETag: "5e4bc151-5"
ETag: "5e4bc151-5"
< Accept-Ranges: bytes
Accept-Ranges: bytes
<
* Connection #0 to host 127.0.0.1 left intact
http://127.0.0.1/app1
root#ubuntu-test:/etc/nginx/sites-available# curl 127.0.0.1/app1 -Iv
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> HEAD /app1 HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
HTTP/1.1 301 Moved Permanently
< Server: nginx/1.14.0 (Ubuntu)
Server: nginx/1.14.0 (Ubuntu)
< Date: Thu, 20 Feb 2020 09:19:31 GMT
Date: Thu, 20 Feb 2020 09:19:31 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 194
Content-Length: 194
< Location: http://127.0.0.1/app1/
Location: http://127.0.0.1/app1/
< Connection: keep-alive
Connection: keep-alive
Why does it happen?
Nginx selects the location / block to process the URI /app1 as no other locations are a better match. See how Nginx processes a request.
The $uri/ term of the try_files statement informs Nginx to append a / to any URI that matches a directory. The directory /var/www/html/app1 matches this requirement, so a 301 redirection is generated to append a / to the URI. See this document for details.
In addition, the default behaviour for a URI which ends with a / and points to a directory is to search that directory for a file that matches the index directive. See this document for details.
It is possible to deviate from this default behaviour, but you will need to make a number of changes to your configuration. The location /app1/ needs to lose the trailing / if you want it to match /app1. Your try_files directives need to lose the $uri/ term, if you want to avoid the 301 redirect. You will also lose default index processing, so the index directive will be useless.

How to add cache control on a static file which have a http code 404

I would like to add http header Cache-Control: max-age=4 on non existing static file.
I try to include the following block into my nginx vhost
server {
listen *:80;
server_name local.test.com;
root /vat/www/test;
location ~* \.(js)$ {
expires 4s;
}
}
On an existing asset it work fine
curl -s -I http://local.test.com/index.js | grep Cache-Control
Cache-Control: max-age=4
On a none existing asset it does't work
curl -s -I http://local.test.com/fake.js
HTTP/1.1 404 Not Found
Server: nginx/1.15.8
Date: Thu, 19 Sep 2019 09:10:39 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
Any idea ?

Make Nginx ignore the content-length header from PHP-FPM

I have PHP FPM + Nginx setup. One of my PHP applications sets an invalid content length header, so I'm trying to ignore it using fastcgi_hide_header, but it doesn't work. It works for headers other than Content-Length, so I assume there is a problem with that in particular.
What is the correct way of doing this? I cannot modify the PHP application to fix the source of the problem.
server {
listen 8000 default_server;
root /var/www;
index index.php index.html index.htm;
rewrite_log on;
# Make site accessible from http://localhost/
server_name localhost;
location / {
try_files $uri $uri/ /index.php;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
# With php5-cgi alone:
fastcgi_hide_header X-Fake-Header;
fastcgi_hide_header Content-Length;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
Output if I remove the code in PHP that sets the headers (this is the desired output):
< HTTP/1.1 200 OK
* Server nginx/1.4.1 (Ubuntu) is not blacklisted
< Server: nginx/1.4.1 (Ubuntu)
< Date: Thu, 13 Feb 2014 01:58:07 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Powered-By: PHP/5.5.3-1ubuntu2.1
If I leave the code in, but use the above nginx config, I get this:
< HTTP/1.1 200 OK
* Server nginx/1.4.1 (Ubuntu) is not blacklisted
< Server: nginx/1.4.1 (Ubuntu)
< Date: Thu, 13 Feb 2014 01:59:09 GMT
< Content-Type: text/html
< Content-Length: 6
< Connection: keep-alive
< X-Powered-By: PHP/5.5.3-1ubuntu2.1
I ended up having to user the HttpHeadersMore module in Nginx (if you're on Ubuntu, this is included with nginx-extras but not nginx-full).
With the module installed, I just added the following to my Nginx configuration:
more_clear_headers Content-Length;
This worked as expected.

Resources