I have the following scenario: a nginx serving static files to clients. For a request, the file is searched for in a local directory and, if not found, the request is forwarded to Amazon S3 via a proxy_pass
directive.
The problem is that Amazon S3 returns HTTP 403 if a file is not found and I would like to change that code to 404 for the client.
(As a side note, this machine running nginx is authorized to retrieve the files from S3 without any credentials and that works properly)
My config looks like this:
user nobody;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 2048;
multi_accept on;
use epoll;
}
http {
reset_timedout_connection on;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
gzip off;
open_file_cache off;
server {
listen 8000 backlog=1000;
server_name blablabla;
#
# Requests made to this server are in the form of GET /file/<sha256> and
# for aabbc1111111111...11 the file will be located in:
# * /files/aa/bb/c/aabbc111111...11.bin on the disk
# * s3://my-bucket-name/aa/bb/c/aabbc1111111...11.bin in S3
#
location ~ "^/file/(?<a>[0-9a-fA-F]{2})(?<b>[0-9a-fA-F]{2})(?<c>[0-9a-fA-F])(?<d>[0-9a-fA-F]{59})$" {
root /files;
rewrite ^ /$a/$b/$c/$a$b$c$d.bin break;
# If 404 results from trying to serve the file from the local directory,
# move to S3
error_page 404 = @try_s3;
}
location @try_s3 {
rewrite ^(.*)\.bin$ /my-bucket-name$1 break;
return 404;
proxy_http_version 1.1;
proxy_pass https://s3-eu-west-1.amazonaws.com;
proxy_set_header Connection ""; break;
proxy_intercept_errors on;
# This is not working, I still get 403, but the difference is that
# with it, I get 403 from nginx (with its 403 HTML template), without
# it I get the 403 sent from S3 (with their HTML in it)
error_page 403 =404;
}
# This is used for the load balancer
location /ping {
return 200;
}
location / {
return 404;
}
}
}