I have a question about serving gzipped static files from nginx. I did gzip -k style.min.css to produce style.min.css.gz and I uploaded it to the server in the static-root directory. My location block is an exact match and looks like this:
location =/style.min.css {
root /home/ubuntu/.../static-root/;
gzip_static on;
expires 100d;
add_header Cache-Control "public";
access_log off;
}
Will nginx just serve up the style.min.css.gz in place of the style.min.css automagically, or do I have to tweak that location block so that the gzipped version is served?
Given the exact match at that location block this test does 404
$ curl -I https://example.com/style.css.gz -H "Accept-Encoding: gzip"
HTTP/1.1 404 Not Found
Is the compressed version still getting served up or do I need to tweak the location block to something like this so that the .gz file gets served?
location ~ /(style.min.css.*) {...
Update ... I can confirm that a gzipped version of a static css file is returned. So it seems to happen automatically. I don't know if the gzip on; in the server section or the gzip_static on; takes care of it but it is working.
$ curl -H "Accept-Encoding: gzip" -I https://example.com/bsmin.css
HTTP/1.1 200 OK
Cache-Control: max-age=7673705, public
Cache-control: no-cache="set-cookie"
Content-Encoding: gzip
From the official documentation https://docs.nginx.com/nginx/admin-guide/web-server/compression/ under Sending Compressed Files
to service a request for /path/to/file, NGINX tries to find and send the file /path/to/file.gz. If the file doesn’t exist, or the client does not support gzip, NGINX sends the uncompressed version of the file.
Note that the gzip_static directive does not enable on-the-fly compression. It merely uses a file compressed beforehand by any compression tool. To compress content (and not only static content) at runtime, use the gzip directive.
Related
Consider there are 3 files named a.html, a.html.gz, b.html and they are served by nginx with the configuration gzip on and gzip_static on, and we also have sendfile on.
What make me feel confused are:
When I access localhost/a.html in browser, I know it will read content from a.html.gz, but will sendfile still work in this case?
What happen when I access localhost/b.html? Will it just send the uncompressed file, or will nginx will gzip this file dynamically?
By the way, is there any configuration in nginx can show the detail log about how a request are handled by different modules?
I've got a single page application running on a server correctly, serving pages across different urls:
example.com
example.com/jsonendpoint
But when I try to access an endpoint meant to return JSON, I get an HTML response. The nginx config looks like:
server {
root /home/myapplication/server/public;
location / {
proxy_pass http://myapplication/;
proxy_redirect off;
try_files $uri $uri/ /index.html;
}
location /jsonendpoint {
proxy_pass http://myapplication/;
default_type application/json;
proxy_redirect off;
}
}
If I comment out the try_files line, then the JSON response works fine and I can still access the root URL at example.com but when I try to access example.com/jsonendpoint then nginx returns a 404.
How do I fix the config to get both things to work?
EDIT:
When I curl the server from within the VPS it's hosted on:
curl -i -H "Accept: application/json" http://localhost:3000/jsonendpoint
I get a JSON response:
Content-Type: application/json; charset=utf-8
When I make the same curl request from my local machine (which means going through nginx then the response type is wrong:
Content-Type: text/html; charset=UTF-8
This rules out the possibility that the problem lies with the backend server.
The mime.types file does have the json mime type added and it is being included by nginx. I've also tried forcing a response type per location block (see above snippet).
Check that in your in your mime types you have something like:
application/json json;
Then try to query your site using something like this:
curl -i -H "Accept: application/json" http://your-site
Check for the header content-type if your application is returning json it should be:
content-type: application/json
If you get something like:
content-type: text/html; charset=utf-8
Check your backend to add the proper content type.
In case you would like to force the type, try this:
location / {
default_type application/json;
# ...
}
Old question but wanted to share what fixed the issue for me:
nginx-user did not have access to my json files. Apparently root-user loads you the html when you browse to website. But other requests like json calls will be served in nginx worker threads as nginx-user.
I added read and execute permissions to all users in html-folder to solve this problem (there are maybe better solutions also):
chmod -R 755 /usr/share/nginx/html
Inside /var/www/storage/ folder located only mp3 files. What I want to do is, to make every request to those files to end up with download rather than playing in browser.
My current config looks like this, I can't figure out what is wrong.
server {
charset utf-8;
client_max_body_size 128M;
listen 80; ## listen for ipv4
server_name dl.domain.com;
root /var/www/storage/;
location / {
add_header Content-Disposition: "$request_filename";
}
}
Your initial configuration is almost correct, all you are forgetting is the "attachment":
add_header Content-Disposition "attachment; filename=$request_filename";
It's also recommended that you do the application/octet-stream as suggested by raven428. However I believe you will get the "save as" in most UAs without adjusting the Content-Type.
Per RFC 2616 sec19.5.1 :
If this header is used in a response with the application/octet- stream content-type, the implied suggestion is that the user agent should not display the response, but directly enter a `save response as...' dialog.
browser decision to play or download depends on content-type header. if you want to force browser download file instead of play, your webserver should return Content-Type: application/octet-stream for mp3 files:
location ~ /mp3folder/.+\.mp3$ {
types {
application/octet-stream;
}
}
I have found an interesting problem.
I am trying to serve some gzipped files without the sources using NGINX's gzip_static module (I know the downsides to this). This means you can have gzipped files on the server that will be served with transfer-encoding: gzip. For example, if there's a file /foo.html.gz, a request for /foo.html will be served the compressed file with content-encoding: text/html.
While this usually works it turns out that when looking for index files in a directory the gzipped versions are not considered.
GET /index.html
200
GET /
403
I was wondering if anyone knows how to fix this. I tried setting index.html.gz as in index file but it is served as a gzip file rather then a gzip encoded html file.
This clearly won't work this way.
This is a part of the module source:
if (r->uri.data[r->uri.len - 1] == '/') {
return NGX_DECLINED;
}
So if the uri ends in slash, it does not even look for the gzipped version.
But, you probably could hack around using rewrite.
(This is a guess, I have not tested it)
rewrite ^(.*)/$ $1/index.html;
Edit: To make it work with autoindex (guess) you can try using this instead of rewrite:
location ~ /$ {
try_files ${uri}/index.html $uri;
}
It probably is better overall than using rewrite. But you need to try ...
You can prepare your precompressed files then serve it.
Below it's prepared by PHP and served without checking if the client supports gzip.
// PHP prepare the precompressed gzip file
file_put_contents('/var/www/static/gzip/script-name.js.gz', gzencode($s, 9));
// where $s is the string containing your file to pre-compress
// NginX serve the precompressed gzip file
location ~ "^/precompressed/(.+)\.js$" {
root /var/www;
expires 262144;
add_header Content-Encoding gzip;
default_type application/javascript;
try_files /static/gzip/$1.js.gz =404;
}
# Browser request a file - transfert 113,90 Kb (uncompressed size 358,68 Kb)
GET http://inc.ovh/precompressed/script-name.js
# Response from the server
Accept-Ranges bytes
Cache-Control max-age=262144
Connection keep-alive
Content-Encoding gzip
Content-Length 113540
Content-Type application/javascript; charset=utf-8
ETag "63f00fd5-1bb84"
Server NginX
I have a stylesheet gzip compressed on disk and would like to serve it via nginx. It's named file.css.xgz and it should have
Content-Type: text/css
Content-Compression: gzip
So I added this to mime.types:
text/css css css.xgz;
And this to my server configuration:
location ~* \.xgz$ {
add_header Content-Encoding gzip;
}
Server is restarted for sure, but the content-type is still application/octet-stream (Content-Encoding is set as expected).
Try just "xgz" in the mime type in place of "css.xgz"