Skip to content

Commit bb03e88

Browse files
feat: Add option to specify a prefix to be prepended to object paths (#190)
Adds an optional configuration environment variable `PREFIX_LEADING_DIRECTORY_PATH`. If defined, this prefix is prepended to all S3 object paths. This is intended as a simple way to allow only some subset of a bucket to be served by the gateway. When used in combination with the existing STRIP_LEADING_DIRECTORY_PATH option, this effectively allows the leading prefix to be replaced, rather than just removed. Special thanks to @hoffmanr-cshs for this thoughtful contribution. --------- Co-authored-by: Javier Evans <[email protected]>
1 parent a95a6f3 commit bb03e88

File tree

10 files changed

+54
-16
lines changed

10 files changed

+54
-16
lines changed

Dockerfile.buildkit.plus

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ ENV PROXY_CACHE_VALID_NOTFOUND "1m"
1212
ENV PROXY_CACHE_VALID_FORBIDDEN "30s"
1313
ENV CORS_ENABLED 0
1414
ENV DIRECTORY_LISTING_PATH_PREFIX ""
15+
ENV STRIP_LEADING_DIRECTORY_PATH ""
16+
ENV PREFIX_LEADING_DIRECTORY_PATH ""
1517

1618
COPY plus/usr /usr
1719

Dockerfile.oss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ ENV PROXY_CACHE_VALID_FORBIDDEN "30s"
1111
ENV CORS_ENABLED 0
1212
ENV DIRECTORY_LISTING_PATH_PREFIX ""
1313
ENV STRIP_LEADING_DIRECTORY_PATH ""
14+
ENV PREFIX_LEADING_DIRECTORY_PATH ""
1415

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

Dockerfile.plus

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ ENV PROXY_CACHE_VALID_FORBIDDEN "30s"
1313
ENV CORS_ENABLED 0
1414
ENV DIRECTORY_LISTING_PATH_PREFIX ""
1515
ENV STRIP_LEADING_DIRECTORY_PATH ""
16+
ENV PREFIX_LEADING_DIRECTORY_PATH ""
1617

1718
COPY plus/etc/ssl /etc/ssl
1819
COPY plus/usr /usr

common/etc/nginx/nginx.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ env PROXY_CACHE_VALID_FORBIDDEN;
3232
env HEADER_PREFIXES_TO_STRIP;
3333
env FOUR_O_FOUR_ON_EMPTY_BUCKET;
3434
env STRIP_LEADING_DIRECTORY_PATH;
35+
env PREFIX_LEADING_DIRECTORY_PATH;
3536

3637
events {
3738
worker_connections 1024;

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ map $request_uri $uri_full_path {
1313
"~^(?P<path>.*?)(\?.*)*$" $path;
1414
}
1515

16-
# Remove a portion of request URL (if configured)
16+
# Remove/replace a portion of request URL (if configured)
1717
map $uri_full_path $uri_path {
18-
"~^$STRIP_LEADING_DIRECTORY_PATH(.*)" $1;
19-
default $uri_full_path;
18+
"~^$STRIP_LEADING_DIRECTORY_PATH(.*)" $PREFIX_LEADING_DIRECTORY_PATH$1;
19+
default $PREFIX_LEADING_DIRECTORY_PATH$uri_full_path;
2020
}
2121

2222
map $S3_STYLE $s3_host_hdr {

docs/getting_started.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ running as a Container or as a Systemd service.
3939
| `JS_TRUSTED_CERT_PATH` | No | | | Enables the `js_fetch_trusted_certificate` directive when retrieving AWS credentials and sets the path (on the container) to the specified path |
4040
| `HEADER_PREFIXES_TO_STRIP` | No | | | 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-` |
4141
| `CORS_ENABLED` | No | `true`, `false` | `false` | Flag that enables CORS headers on GET requests and enables pre-flight OPTIONS requests. If enabled, this will add CORS headers for "fully open" cross domain requests by default, meaning all domains are allowed, similar to the settings show in [this example](https://enable-cors.org/server_nginx.html). CORS settings can be fine-tuned by overwriting the [`cors.conf.template`](/common/etc/nginx/templates/gateway/cors.conf.template) file. |
42-
| `CORS_ALLOWED_ORIGIN` | No | | | value to set to be returned from the CORS `Access-Control-Allow-Origin` header. This value is only used if CORS is enabled. (default: \*)
43-
| `STRIP_LEADING_DIRECTORY_PATH` | No | | | Removes a portion of the path in the requested URL (if configured). Useful when deploying to an ALB under a folder (eg. www.mysite.com/somepath).
42+
| `CORS_ALLOWED_ORIGIN` | No | | | value to set to be returned from the CORS `Access-Control-Allow-Origin` header. This value is only used if CORS is enabled. (default: \*) |
43+
| `STRIP_LEADING_DIRECTORY_PATH` | No | | | Removes a portion of the path in the requested URL (if configured). Useful when deploying to an ALB under a folder (eg. www.mysite.com/somepath). |
44+
| `PREFIX_LEADING_DIRECTORY_PATH` | No | | | Prefix to prepend to all S3 object paths. Useful to serve only a subset of an S3 bucket. When used in combination with `STRIP_LEADING_DIRECTORY_PATH`, this allows the leading path to be replaced, rather than just removed. |
4445

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

standalone_ubuntu_oss_install.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ PROXY_CACHE_VALID_FORBIDDEN=${PROXY_CACHE_VALID_FORBIDDEN:-'30s'}
173173
CORS_ENABLED=${CORS_ENABLED:-'false'}
174174
# Configure portion of URL to be removed (optional)
175175
STRIP_LEADING_DIRECTORY_PATH=${STRIP_LEADING_DIRECTORY_PATH:-''}
176+
# Configure portion of URL to be added to the beginning of the requested path (optional)
177+
PREFIX_LEADING_DIRECTORY_PATH=${PREFIX_LEADING_DIRECTORY_PATH:-''}
176178
EOF
177179

178180
# By enabling CORS, we also need to enable the OPTIONS method which

test.sh

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,13 @@ integration_test() {
249249
printf "\e[1m Integration test suite with APPEND_SLASH_FOR_POSSIBLE_DIRECTORY=%s\e[22m\n" "$4"
250250
printf "\033[34;1m▶\033[0m"
251251
printf "\e[1m Integration test suite with STRIP_LEADING_DIRECTORY_PATH=%s\e[22m\n" "$5"
252+
printf "\033[34;1m▶\033[0m"
253+
printf "\e[1m Integration test suite with PREFIX_LEADING_DIRECTORY_PATH=%s\e[22m\n" "$6"
254+
252255

253256
p "Starting Docker Compose Environment"
254257
# COMPOSE_COMPATIBILITY=true Supports older style compose filenames with _ vs -
255-
COMPOSE_COMPATIBILITY=true AWS_SIGS_VERSION=$1 ALLOW_DIRECTORY_LIST=$2 PROVIDE_INDEX_PAGE=$3 APPEND_SLASH_FOR_POSSIBLE_DIRECTORY=$4 STRIP_LEADING_DIRECTORY_PATH=$5 compose up -d
258+
COMPOSE_COMPATIBILITY=true AWS_SIGS_VERSION=$1 ALLOW_DIRECTORY_LIST=$2 PROVIDE_INDEX_PAGE=$3 APPEND_SLASH_FOR_POSSIBLE_DIRECTORY=$4 STRIP_LEADING_DIRECTORY_PATH=$5 PREFIX_LEADING_DIRECTORY_PATH=$6 compose up -d
256259

257260
if [ "${wait_for_it_installed}" ]; then
258261
if [ -x "${wait_for_it_cmd}" ]; then
@@ -261,8 +264,8 @@ integration_test() {
261264
fi
262265

263266
p "Starting HTTP API tests (v$1 signatures)"
264-
echo " test/integration/test_api.sh \"$test_server\" \"$test_dir\" $1 $2 $3 $4 $5"
265-
bash "${test_dir}/integration/test_api.sh" "${test_server}" "${test_dir}" "$1" "$2" "$3" "$4" "$5";
267+
echo " test/integration/test_api.sh \"$test_server\" \"$test_dir\" $1 $2 $3 $4 $5 $6"
268+
bash "${test_dir}/integration/test_api.sh" "${test_server}" "${test_dir}" "$1" "$2" "$3" "$4" "$5" "$6";
266269

267270
# We check to see if NGINX is in fact using the correct version of AWS
268271
# signatures as it was configured to do.
@@ -404,41 +407,52 @@ runUnitTestWithSessionToken "s3gateway_test.js"
404407
integration_test_data
405408

406409
p "Testing API with AWS Signature V2 and allow directory listing off"
407-
integration_test 2 0 0 0 ""
410+
integration_test 2 0 0 0 "" ""
408411

409412
compose stop nginx-s3-gateway # Restart with new config
410413

411414
p "Testing API with AWS Signature V2 and allow directory listing on"
412-
integration_test 2 1 0 0 ""
415+
integration_test 2 1 0 0 "" ""
413416

414417
compose stop nginx-s3-gateway # Restart with new config
415418

416419
p "Testing API with AWS Signature V2 and static site on"
417-
integration_test 2 0 1 0 ""
420+
integration_test 2 0 1 0 "" ""
418421

419422
compose stop nginx-s3-gateway # Restart with new config
420423

421424
p "Testing API with AWS Signature V2 and allow directory listing on and append slash and allow index"
422-
integration_test 2 1 1 1 ""
425+
integration_test 2 1 1 1 "" ""
423426

424427
compose stop nginx-s3-gateway # Restart with new config
425428

426429
p "Test API with AWS Signature V4 and allow directory listing off"
427-
integration_test 4 0 0 0 ""
430+
integration_test 4 0 0 0 "" ""
428431

429432
compose stop nginx-s3-gateway # Restart with new config
430433

431434
p "Test API with AWS Signature V4 and allow directory listing on and appending /"
432-
integration_test 4 1 0 1 ""
435+
integration_test 4 1 0 1 "" ""
433436

434437
compose stop nginx-s3-gateway # Restart with new config
435438

436439
p "Test API with AWS Signature V4 and static site on appending /"
437-
integration_test 4 0 1 1 ""
440+
integration_test 4 0 1 1 "" ""
438441

439442
compose stop nginx-s3-gateway # Restart with new config
440443

441444
p "Testing API with AWS Signature V2 and allow directory listing off and prefix stripping on"
442-
integration_test 2 0 0 0 /my-bucket
445+
integration_test 2 0 0 0 /my-bucket ""
446+
447+
compose stop nginx-s3-gateway # Restart with new config
448+
449+
p "Test API with AWS Signature V4 and prefix leading directory path on"
450+
integration_test 4 0 0 0 "" "/b"
451+
452+
p "Test API with AWS Signature V4 and prefix leading directory path on and prefix stripping on"
453+
integration_test 4 0 0 0 "/tostrip" "/b"
454+
455+
p "Testing API with AWS Signature V2 and prefix leading directory path"
456+
integration_test 2 0 0 0 "" "/b"
443457

444458
p "All integration tests complete"

test/docker-compose.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ services:
2727
PROVIDE_INDEX_PAGE:
2828
APPEND_SLASH_FOR_POSSIBLE_DIRECTORY:
2929
STRIP_LEADING_DIRECTORY_PATH:
30+
PREFIX_LEADING_DIRECTORY_PATH:
3031
AWS_SIGS_VERSION:
3132
STATIC_SITE_HOSTING:
3233
PROXY_CACHE_MAX_SIZE: "10g"

test/integration/test_api.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ allow_directory_list=$4
2626
index_page=$5
2727
append_slash=$6
2828
strip_leading_directory=$7
29+
prefix_leading_directory_path=$8
30+
2931
test_fail_exit_code=2
3032
no_dep_exit_code=3
3133
checksum_length=32
@@ -159,6 +161,19 @@ for (( i=1; i<=3; i++ )); do
159161
done
160162
set -o errexit
161163

164+
if [ -n "${prefix_leading_directory_path}" ]; then
165+
assertHttpRequestEquals "GET" "/c/d.txt" "data/bucket-1/b/c/d.txt"
166+
167+
if [ -n "${strip_leading_directory}" ]; then
168+
# When these two flags are used together, stripped value is basically
169+
# replaced with the specified prefix
170+
assertHttpRequestEquals "GET" "/tostrip/c/d.txt" "data/bucket-1/b/c/d.txt"
171+
fi
172+
173+
# Exit early for this case since all tests following will fail because of the added prefix
174+
exit 0
175+
fi
176+
162177
# Ordinary filenames
163178

164179
assertHttpRequestEquals "HEAD" "a.txt" "200"

0 commit comments

Comments
 (0)