Skip to content

Commit 28824ad

Browse files
committed
Fixes nginx#62
This commit adds support for CORS response headers. Signed-off-by: Elijah Zupancic <e.zupancic@f5.com>
1 parent 41645a0 commit 28824ad

File tree

8 files changed

+96
-4
lines changed

8 files changed

+96
-4
lines changed

Dockerfile.buildkit.plus

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ ENV PROXY_CACHE_VALID_OK "1h"
99
ENV PROXY_CACHE_VALID_NOTFOUND "1m"
1010
ENV PROXY_CACHE_VALID_FORBIDDEN "30s"
1111

12+
ENV PROXY_CACHE_VALID_OK "1h"
13+
ENV PROXY_CACHE_VALID_NOTFOUND "1m"
14+
ENV PROXY_CACHE_VALID_FORBIDDEN "30s"
15+
ENV CORS_ENABLED 0
16+
1217
COPY plus/usr /usr
1318

1419
# Copy files from the OSS NGINX Docker container such that the container

Dockerfile.oss

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ ENV NJS_VERSION 0.7.9
66
ENV PROXY_CACHE_VALID_OK "1h"
77
ENV PROXY_CACHE_VALID_NOTFOUND "1m"
88
ENV PROXY_CACHE_VALID_FORBIDDEN "30s"
9+
ENV CORS_ENABLED 0
910

1011
# We modify the nginx base image by:
1112
# 1. Adding configuration files needed for proxying private S3 buckets

Dockerfile.plus

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ ENV XSLT_VERSION 28-1
88
ENV PROXY_CACHE_VALID_OK "1h"
99
ENV PROXY_CACHE_VALID_NOTFOUND "1m"
1010
ENV PROXY_CACHE_VALID_FORBIDDEN "30s"
11+
ENV CORS_ENABLED 0
1112

1213
COPY plus/etc/ssl /etc/ssl
1314
COPY plus/usr /usr

common/docker-entrypoint.d/00-check-for-required-env.sh

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ set -e
2323
failed=0
2424

2525
required=("S3_BUCKET_NAME" "S3_SERVER" "S3_SERVER_PORT" "S3_SERVER_PROTO"
26-
"S3_REGION" "S3_STYLE" "ALLOW_DIRECTORY_LIST" "AWS_SIGS_VERSION")
26+
"S3_REGION" "S3_STYLE" "ALLOW_DIRECTORY_LIST" "AWS_SIGS_VERSION"
27+
"CORS_ENABLED")
2728

2829
# Require some form of authentication to be configured.
2930

@@ -107,3 +108,4 @@ echo "Directory Listing Enabled: ${ALLOW_DIRECTORY_LIST}"
107108
echo "Provide Index Pages Enabled: ${PROVIDE_INDEX_PAGE}"
108109
echo "Append slash for directory enabled: ${APPEND_SLASH_FOR_POSSIBLE_DIRECTORY}"
109110
echo "Stripping the following headers from responses: x-amz-;${HEADER_PREFIXES_TO_STRIP}"
111+
echo "CORS Enabled: ${CORS_ENABLED}"

common/docker-entrypoint.sh

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/sh
1+
#!/usr/bin/env bash
22
#
33
# Copyright 2020 F5 Networks
44
#
@@ -19,11 +19,37 @@
1919

2020
set -e
2121

22+
parseBoolean() {
23+
case "$1" in
24+
TRUE | true | True | YES | Yes | 1)
25+
echo 1
26+
;;
27+
*)
28+
echo 0
29+
;;
30+
esac
31+
}
32+
2233
# This line is an addition to the NGINX Docker image's entrypoint script.
2334
if [ -z ${DNS_RESOLVERS+x} ]; then
2435
export DNS_RESOLVERS="$(cat /etc/resolv.conf | grep nameserver | cut -d' ' -f2 | xargs)"
2536
fi
2637

38+
# Normalize the CORS_ENABLED environment variable to a numeric value
39+
# so that it can be easily parsed in the nginx configuration.
40+
export CORS_ENABLED="$(parseBoolean "${CORS_ENABLED}")"
41+
42+
# By enabling CORS, we also need to enable the OPTIONS method which
43+
# is not normally used as part of the gateway. The following variable
44+
# defines the set of acceptable headers.
45+
if [ "${CORS_ENABLED}" == "1" ]; then
46+
export LIMIT_METHODS_TO="GET HEAD OPTIONS"
47+
export LIMIT_METHODS_TO_CSV="GET, HEAD, OPTIONS"
48+
else
49+
export LIMIT_METHODS_TO="GET HEAD"
50+
export LIMIT_METHODS_TO_CSV="GET, HEAD"
51+
fi
52+
2753
# Nothing is modified under this line
2854

2955
if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then

common/etc/nginx/templates/default.conf.template

+20-1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ server {
6666
}
6767

6868
location / {
69+
# This value is templated in based on the value of $CORS_ENABLED. When
70+
# CORS is enabled, acceptable methods are GET, HEAD, and OPTIONS.
71+
# Otherwise, they are GET and HEAD.
72+
limit_except ${LIMIT_METHODS_TO} {}
73+
74+
# CORS is implemented by returning the appropriate headers as part of
75+
# the response to an OPTIONS request. If you want to customize the
76+
# CORS response, the cors.conf.template file can be overwritten and
77+
# extended to meet one's needs.
78+
include /etc/nginx/conf.d/gateway/cors.conf;
79+
6980
auth_request /aws/credentials/retrieve;
7081

7182
# Redirect to the proper location based on the client request - either
@@ -86,6 +97,10 @@ server {
8697
# we plan to use.
8798
include /etc/nginx/conf.d/gateway/v${AWS_SIGS_VERSION}_headers.conf;
8899

100+
# The CORS configuration needs to be imported in several places in order for
101+
# it to be applied within different contexts.
102+
include /etc/nginx/conf.d/gateway/cors.conf;
103+
89104
# Don't allow any headers from the client - we don't want them messing
90105
# with S3 at all.
91106
proxy_pass_request_headers off;
@@ -128,6 +143,10 @@ server {
128143
# we plan to use.
129144
include /etc/nginx/conf.d/gateway/v${AWS_SIGS_VERSION}_headers.conf;
130145

146+
# The CORS configuration needs to be imported in several places in order for
147+
# it to be applied within different contexts.
148+
include /etc/nginx/conf.d/gateway/cors.conf;
149+
131150
# Don't allow any headers from the client - we don't want them messing
132151
# with S3 at all.
133152
proxy_pass_request_headers off;
@@ -193,7 +212,7 @@ server {
193212
# Provide a hint to the client on 405 errors of the acceptable request methods
194213
error_page 405 @error405;
195214
location @error405 {
196-
add_header Allow "GET, HEAD" always;
215+
add_header Allow "${LIMIT_METHODS_TO_CSV}" always;
197216
return 405;
198217
}
199218

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
set $request_cors "${request_method}_${CORS_ENABLED}";
2+
3+
if ($request_cors = "OPTIONS_1") {
4+
add_header 'Access-Control-Allow-Origin' '*';
5+
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
6+
#
7+
# Custom headers and headers various browsers *should* be OK with but aren't
8+
#
9+
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
10+
#
11+
# Tell client that this pre-flight info is valid for 20 days
12+
#
13+
add_header 'Access-Control-Max-Age' 1728000;
14+
add_header 'Content-Type' 'text/plain; charset=utf-8';
15+
add_header 'Content-Length' 0;
16+
return 204;
17+
}
18+
19+
if ($request_cors = "GET_1") {
20+
add_header 'Access-Control-Allow-Origin' '*' always;
21+
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
22+
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
23+
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
24+
}
25+
26+
if ($request_cors = "HEAD_1") {
27+
add_header 'Access-Control-Allow-Origin' '*' always;
28+
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
29+
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
30+
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
31+
}

docs/getting_started.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,14 @@ running as a Container or as a Systemd service.
3737
* `PROXY_CACHE_VALID_NOTFOUND` - Sets caching time for response code 404
3838
* `PROXY_CACHE_VALID_FORBIDDEN` - Sets caching time for response code 403
3939
* `JS_TRUSTED_CERT_PATH` - (optional) Enables the `js_fetch_trusted_certificate` directive when retrieving AWS credentials and sets the path (on the container) to the specified path
40-
* `HEADER_PREFIXES_TO_STRIP` - (optional) a list of HTTP header prefixes that exclude headers client responses. List should be specified in lower-case and a semicolon (;) should be used to as a deliminator between values. For example: `x-goog-;x-something-`
40+
* `HEADER_PREFIXES_TO_STRIP` - (optional) a list of HTTP header prefixes that exclude headers client responses. List should be specified in lower-case and a semicolon (;) should be used to as a deliminator between values. For example: `x-goog-;x-something-`
41+
* `CORS_ENABLED` - Flag (true/false) that enables CORS headers on GET
42+
requests and enables pre-flight OPTIONS requests. If enabled, this will
43+
add CORS headers for "fully open" cross domain requests by default,
44+
meaning all domains are allowed, similar to the settings show in
45+
[this example](https://enable-cors.org/server_nginx.html).
46+
CORS settings can be fine-tuned by overwriting the
47+
[`cors.conf.template`](/common/etc/nginx/templates/gateway/cors.conf.template) file. (default: false)
4148

4249
If you are using [AWS instance profile credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html),
4350
you will need to omit the `S3_ACCESS_KEY_ID` and `S3_SECRET_KEY` variables from

0 commit comments

Comments
 (0)