server { listen 443 ssl; listen [::]:443 ssl; server_name s3.*; include /config/nginx/ssl.conf; client_max_body_size 0; location / { include /config/nginx/proxy.conf; include /config/nginx/resolver.conf; set $upstream_app garage; set $upstream_port 3900; set $upstream_proto http; # --- Handle CORS preflight --- if ($request_method = OPTIONS) { add_header 'Access-Control-Allow-Origin' "*" always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, HEAD' always; add_header 'Access-Control-Allow-Headers' '*' always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header 'Access-Control-Max-Age' 3000; add_header 'Content-Length' 0; add_header 'Content-Type' 'text/plain charset=UTF-8'; return 204; } # --- Proxy normal requests --- proxy_pass $upstream_proto://$upstream_app:$upstream_port; # Prevent backend from sending conflicting CORS headers (optional) proxy_hide_header Access-Control-Allow-Origin; proxy_hide_header Access-Control-Allow-Credentials; proxy_hide_header Access-Control-Allow-Headers; proxy_hide_header Access-Control-Allow-Methods; proxy_hide_header Access-Control-Expose-Headers; # --- Add CORS headers for actual responses --- add_header 'Access-Control-Allow-Origin' "*" always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, HEAD' always; add_header 'Access-Control-Allow-Headers' '*' always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header 'Access-Control-Expose-Headers' 'Etag' always;# } }