Reputation: 236
I'm having a hard time configuring nginx to act as a proxy of a public S3 endpoint. My use case necessitates altering the status code of the S3 response, while preserving the response payload.
The possible status codes returned by S3 include 200 and 403. For my use case, I need to map those status codes to 503.
I have tried the following which does not work:
location ~* ^/.* {
[...]
proxy_intercept_errors on;
error_page 200 =503 $upstream_http_location
}
Nginx outputs the following error:
nginx: [emerg] value "200" must be between 300 and 599 in /etc/nginx/nginx.conf:xx
Here's a more complete snippet:
server {
listen 80;
location ~* ^/.* {
proxy_http_version 1.1;
proxy_method GET;
proxy_pass http://my-s3-bucket-endpoint;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Connection "";
proxy_set_header Host my-s3-bucket-endpoint;
proxy_set_header Authorization '';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header Set-Cookie;
proxy_ignore_headers "Set-Cookie";
proxy_cache S3_CACHE;
proxy_cache_valid 200 403 503 1h;
proxy_cache_bypass $http_cache_purge;
add_header X-Cached $upstream_cache_status;
proxy_intercept_errors on;
error_page 200 =503 $upstream_http_location;
}
}
Is it possible to achieve what I need with nginx?
Upvotes: 6
Views: 12161
Reputation: 1
Example with gcs storage
location ~/ {
return 503;
}
error_page 500 502 503 504 /custom_50x.html;
location = /custom_50x.html {
rewrite (.*) /your-bucket/custom_error.html break;
proxy_pass https://storage.googleapis.com;
}
Upvotes: 0
Reputation: 236
I found a more or less suitable solution. It's a bit hackish but it works.
The key was to set the index document of my S3 bucket to a non-existing filename. This causes requests to / on the S3 bucket endpoint to result in 403.
Since the nginx proxy maps all incoming requests to / on the S3 bucket endpoint, the result is always 403 which the nginx proxy can intercept. From there, the error_page directive tells it to respond by requesting a specific document (in this case error.json) in the S3 bucket endpoint and use 503 as the response status code.
location ~* ^/. {
proxy_intercept_errors on;
error_page 403 =503 /error.json;
}
This solution involves two requests being sent to the S3 bucket endpoint (/, /error.json) but at least caching seems to be enabled for both requests using the configuration in the more complete snippet above.
Upvotes: 7