nginx won't serve json file unless specifying .json in url
I have the following nginx.conf file:
server {
listen 8080;
server_name dummy_server;
root /usr/share/nginx/html;
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
default_type 'application/json';
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Content-Type' 'application/json';
if ($request_uri ~* "([^/]*$)" ) {
set $last_path_component $1;
}
try_files $last_path_component.json $last_path_component.json =404;
}
}
I would like to serve healthcheck.json
when localhost:8080/v1/healthcheck
is requested.
However, nginx refuses to serve any json file if I'm not explicitly hitting localhost:8080/v1/healthcheck.json
, otherwise it logs file not found, and the response is nginx's 404 page.
If I add .json at the end of the url, the file is magically found and great magic happens.
I tried forcing application/json
type, as well as changing the try files
row to explicitly return the file I would like to return (so I've set try_files healthcheck.json =404;
) all returns the same issue.
I'm quite lost.. anyone have any ideas?
This is actually an expected behavior with this config.
So, what you are doing, is stripping the URL and then passing it to try_files
.
But there is nothing in try_files
to handle files without an extension. To do that, modify it like this
try_files $last_path_component $last_path_component.json $last_path_component.json =404;
This will allow you to serve .json
files without extension. However, this will not serve the same .json
file with or without extension. The try_files
directive checks the existence of the files and serves them in this order. So if you have healthcheck.json
and try to access it via localhost:8080/v1/healthcheck
it will still fail. So you need to have healthcheck
end-point to be actually without an extension on the server for it to be accessible.
If you want to handle both variations, with or without extension, you might want to strip the .json
part first like this
if ($request_uri ~ ^/([^?]*)\.json(\?.*)?$) {
return 302 /$1$2;
}
try_files $uri $uri.json =404;
}