diff --git a/common/etc/nginx/include/s3gateway.js b/common/etc/nginx/include/s3gateway.js index dda556cc..2ca140ec 100644 --- a/common/etc/nginx/include/s3gateway.js +++ b/common/etc/nginx/include/s3gateway.js @@ -322,9 +322,9 @@ function redirectToS3(r) { if (isDirectoryListing && (r.method === 'GET' || r.method === 'HEAD')) { r.internalRedirect("@s3PreListing"); - } else if ( PROVIDE_INDEX_PAGE == true ) { + } else if (PROVIDE_INDEX_PAGE === true) { r.internalRedirect("@s3"); - } else if ( !ALLOW_LISTING && !PROVIDE_INDEX_PAGE && uriPath == "/" ) { + } else if (!ALLOW_LISTING && !PROVIDE_INDEX_PAGE && uriPath === "/") { r.internalRedirect("@error404"); } else { r.internalRedirect("@s3"); @@ -333,8 +333,12 @@ function redirectToS3(r) { function trailslashControl(r) { if (APPEND_SLASH) { + // For the purposes of understanding whether this is a directory, + // consider the uri without query params or anchors + const path = r.variables.uri_path.split(/[?#]/)[0]; + const hasExtension = /\/[^.\/]+\.[^.]+$/; - if (!hasExtension.test(r.variables.uri_path) && !_isDirectory(r.variables.uri_path)){ + if (!hasExtension.test(path) && !_isDirectory(path)){ return r.internalRedirect("@trailslash"); } } @@ -353,22 +357,20 @@ async function loadContent(r) { r.internalRedirect("@s3Directory"); return; } - const url = s3uri(r); + const uri = s3uri(r); let reply = await ngx.fetch( - `http://127.0.0.1:80${url}` + `http://127.0.0.1:80${uri}` ); - if (reply.status == 200) { - // found index.html, so redirect to it - r.internalRedirect(r.variables.request_uri + INDEX_PAGE); - } else if (reply.status == 404) { - // else just list the contents of the directory + if (reply.status === 200) { + utils.debug_log(r, `Found index file, redirecting to: ${uri}`); + r.internalRedirect(uri); + } else if (reply.status === 404) { + // As there was no index file found, just list the contents of the directory r.internalRedirect("@s3Directory"); } else { r.internalRedirect("@error500"); } - - return; } /** @@ -449,16 +451,9 @@ function _escapeURIPath(uri) { * @private */ function _isDirectory(path) { - if (path === undefined) { - return false; - } - const len = path.length; - - if (len < 1) { - return false; - } + if (!path) return false; - return path.charAt(len - 1) === '/'; + return path.slice(-1) === '/'; } /** diff --git a/common/etc/nginx/templates/default.conf.template b/common/etc/nginx/templates/default.conf.template index c78ffc46..7873a190 100644 --- a/common/etc/nginx/templates/default.conf.template +++ b/common/etc/nginx/templates/default.conf.template @@ -326,7 +326,7 @@ server { location @trailslash { # 302 to request without slashes - rewrite ^ $scheme://$http_host$request_uri/ redirect; + rewrite ^ $scheme://$http_host$uri/$is_args$query_string redirect; } # Provide a hint to the client on 405 errors of the acceptable request methods diff --git a/test.sh b/test.sh index d90f9ce7..20920005 100755 --- a/test.sh +++ b/test.sh @@ -411,6 +411,11 @@ integration_test 2 1 0 0 compose stop nginx-s3-gateway # Restart with new config +p "Testing API with AWS Signature V2 and allow directory listing on and append slash and allow index" +integration_test 2 1 1 1 + +compose stop nginx-s3-gateway # Restart with new config + p "Testing API with AWS Signature V2 and static site on" integration_test 2 0 1 0 diff --git a/test/data/bucket-1/test/index.html b/test/data/bucket-1/test/index.html new file mode 100644 index 00000000..da85dd89 --- /dev/null +++ b/test/data/bucket-1/test/index.html @@ -0,0 +1 @@ +

This is an index page of the d directory

\ No newline at end of file diff --git a/test/integration/test_api.sh b/test/integration/test_api.sh index ec49f99f..cb17a61c 100644 --- a/test/integration/test_api.sh +++ b/test/integration/test_api.sh @@ -288,6 +288,15 @@ assertHttpRequestEquals "GET" "/statichost/noindexdir/multipledir/" "data/bucket assertHttpRequestEquals "GET" "/statichost" "data/bucket-1/statichost/index.html" assertHttpRequestEquals "GET" "/statichost/noindexdir/multipledir" "data/bucket-1/statichost/noindexdir/multipledir/index.html" fi + + if [ "${allow_directory_list}" == "1" ]; then + if [ "$append_slash" == "1" ]; then + assertHttpRequestEquals "GET" "test" "200" + assertHttpRequestEquals "GET" "test/" "200" + assertHttpRequestEquals "GET" "test?foo=bar" "200" + assertHttpRequestEquals "GET" "test/?foo=bar" "200" + fi + fi fi if [ "${allow_directory_list}" == "1" ]; then @@ -299,7 +308,9 @@ if [ "${allow_directory_list}" == "1" ]; then assertHttpRequestEquals "GET" "%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B/" "200" assertHttpRequestEquals "GET" "системы/" "200" if [ "$append_slash" == "1" ]; then - assertHttpRequestEquals "GET" "b" "302" + if [ "${index_page}" == "0" ]; then + assertHttpRequestEquals "GET" "b" "302" + fi else assertHttpRequestEquals "GET" "b" "404" fi