From cbde75e77b4404e3af08e7716a7c6b021911bd69 Mon Sep 17 00:00:00 2001 From: Georgios Kalpakas Date: Wed, 8 Mar 2017 16:29:37 +0200 Subject: [PATCH] feat(aio): redirect HTTP to HTTPS --- .../dockerbuild/nginx/aio-builds.conf | 16 +- .../scripts-js/lib/verify-setup/nginx.e2e.ts | 463 +++++++++--------- 2 files changed, 257 insertions(+), 222 deletions(-) diff --git a/aio/aio-builds-setup/dockerbuild/nginx/aio-builds.conf b/aio/aio-builds-setup/dockerbuild/nginx/aio-builds.conf index b67e2abb1f..e8e8f0f161 100644 --- a/aio/aio-builds-setup/dockerbuild/nginx/aio-builds.conf +++ b/aio/aio-builds-setup/dockerbuild/nginx/aio-builds.conf @@ -1,9 +1,19 @@ +# Redirect all HTTP traffic to HTTPS +server { + server_name _; + + listen {{$AIO_NGINX_PORT_HTTP}} default_server; + listen [::]:{{$AIO_NGINX_PORT_HTTP}}; + + # Ideally we want 308 (permanent + keep original method), + # but it is relatively new and not supported by some clients (e.g. cURL). + return 307 https://$host:{{$AIO_NGINX_PORT_HTTPS}}$request_uri; +} + # Serve PR-preview requests server { server_name "~^pr(?[1-9][0-9]*)-(?[0-9a-f]{40})\."; - listen {{$AIO_NGINX_PORT_HTTP}}; - listen [::]:{{$AIO_NGINX_PORT_HTTP}}; listen {{$AIO_NGINX_PORT_HTTPS}} ssl; listen [::]:{{$AIO_NGINX_PORT_HTTPS}} ssl; @@ -27,8 +37,6 @@ server { server { server_name _; - listen {{$AIO_NGINX_PORT_HTTP}} default_server; - listen [::]:{{$AIO_NGINX_PORT_HTTP}}; listen {{$AIO_NGINX_PORT_HTTPS}} ssl default_server; listen [::]:{{$AIO_NGINX_PORT_HTTPS}} ssl; diff --git a/aio/aio-builds-setup/dockerbuild/scripts-js/lib/verify-setup/nginx.e2e.ts b/aio/aio-builds-setup/dockerbuild/scripts-js/lib/verify-setup/nginx.e2e.ts index beef51a54a..7c28b9e09b 100644 --- a/aio/aio-builds-setup/dockerbuild/scripts-js/lib/verify-setup/nginx.e2e.ts +++ b/aio/aio-builds-setup/dockerbuild/scripts-js/lib/verify-setup/nginx.e2e.ts @@ -3,240 +3,267 @@ import * as path from 'path'; import {helper as h} from './helper'; // Tests -h.runForAllSupportedSchemes((scheme, port) => describe(`nginx (on ${scheme.toUpperCase()})`, () => { - const hostname = h.nginxHostname; - const host = `${hostname}:${port}`; - const pr = '9'; - const sha9 = '9'.repeat(40); - const sha0 = '0'.repeat(40); +describe(`nginx`, () => { beforeEach(() => jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000); afterEach(() => h.cleanUp()); - describe(`pr-.${host}/*`, () => { + it('should redirect HTTP to HTTPS', done => { + const httpHost = `${h.nginxHostname}:${h.nginxPortHttp}`; + const httpsHost = `${h.nginxHostname}:${h.nginxPortHttps}`; + const urlMap = { + [`http://${httpHost}/`]: `https://${httpsHost}/`, + [`http://${httpHost}/foo`]: `https://${httpsHost}/foo`, + [`http://foo.${httpHost}/`]: `https://foo.${httpsHost}/`, + }; - beforeEach(() => { - h.createDummyBuild(pr, sha9); - h.createDummyBuild(pr, sha0); - }); - - - it('should return /index.html', done => { - const origin = `${scheme}://pr${pr}-${sha9}.${host}`; - const bodyRegex = new RegExp(`^PR: ${pr} | SHA: ${sha9} | File: /index\\.html$`); - - Promise.all([ - h.runCmd(`curl -iL ${origin}/index.html`).then(h.verifyResponse(200, bodyRegex)), - h.runCmd(`curl -iL ${origin}/`).then(h.verifyResponse(200, bodyRegex)), - h.runCmd(`curl -iL ${origin}`).then(h.verifyResponse(200, bodyRegex)), - ]).then(done); - }); - - - it('should return /foo/bar.js', done => { - const bodyRegex = new RegExp(`^PR: ${pr} | SHA: ${sha9} | File: /foo/bar\\.js$`); - - h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}.${host}/foo/bar.js`). - then(h.verifyResponse(200, bodyRegex)). - then(done); - }); - - - it('should respond with 403 for directories', done => { - Promise.all([ - h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}.${host}/foo/`).then(h.verifyResponse(403)), - h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}.${host}/foo`).then(h.verifyResponse(403)), - ]).then(done); - }); - - - it('should respond with 404 for unknown paths to files', done => { - h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}.${host}/foo/baz.css`). - then(h.verifyResponse(404)). - then(done); - }); - - - it('should rewrite to \'index.html\' for unknown paths that don\'t look like files', done => { - const bodyRegex = new RegExp(`^PR: ${pr} | SHA: ${sha9} | File: /index\\.html$`); - - Promise.all([ - h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}.${host}/foo/baz`).then(h.verifyResponse(200, bodyRegex)), - h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}.${host}/foo/baz/`).then(h.verifyResponse(200, bodyRegex)), - ]).then(done); - }); - - - it('should respond with 404 for unknown PRs/SHAs', done => { - const otherPr = 54321; - const otherSha = '8'.repeat(40); - - Promise.all([ - h.runCmd(`curl -iL ${scheme}://pr${pr}9-${sha9}.${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://pr${otherPr}-${sha9}.${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}9.${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://pr${pr}-${otherSha}.${host}`).then(h.verifyResponse(404)), - ]).then(done); - }); - - - it('should respond with 404 if the subdomain format is wrong', done => { - Promise.all([ - h.runCmd(`curl -iL ${scheme}://xpr${pr}-${sha9}.${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://prx${pr}-${sha9}.${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://xx${pr}-${sha9}.${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://p${pr}-${sha9}.${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://r${pr}-${sha9}.${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://${pr}-${sha9}.${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://pr${pr}${sha9}.${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://pr${pr}_${sha9}.${host}`).then(h.verifyResponse(404)), - ]).then(done); - }); - - - it('should reject PRs with leading zeros', done => { - h.runCmd(`curl -iL ${scheme}://pr0${pr}-${sha9}.${host}`). - then(h.verifyResponse(404)). - then(done); - }); - - - it('should accept SHAs with leading zeros (but not ignore them)', done => { - const bodyRegex = new RegExp(`^PR: ${pr} | SHA: ${sha0} | File: /index\\.html$`); - - Promise.all([ - h.runCmd(`curl -iL ${scheme}://pr${pr}-0${sha9}.${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha0}.${host}`).then(h.verifyResponse(200, bodyRegex)), - ]).then(done); + const verifyRedirection = (httpUrl: string) => h.runCmd(`curl -i ${httpUrl}`).then(result => { + h.verifyResponse(307)(result); + + const headers = result.stdout.split(/(?:\r?\n){2,}/)[0]; + expect(headers).toContain(`Location: ${urlMap[httpUrl]}`); }); + Promise. + all(Object.keys(urlMap).map(verifyRedirection)). + then(done); }); - describe(`${host}/health-check`, () => { - - it('should respond with 200', done => { - Promise.all([ - h.runCmd(`curl -iL ${scheme}://${host}/health-check`).then(h.verifyResponse(200)), - h.runCmd(`curl -iL ${scheme}://${host}/health-check/`).then(h.verifyResponse(200)), - ]).then(done); - }); + h.runForAllSupportedSchemes((scheme, port) => describe(`nginx (on ${scheme.toUpperCase()})`, () => { + const hostname = h.nginxHostname; + const host = `${hostname}:${port}`; + const pr = '9'; + const sha9 = '9'.repeat(40); + const sha0 = '0'.repeat(40); - it('should respond with 404 if the path does not match exactly', done => { - Promise.all([ - h.runCmd(`curl -iL ${scheme}://${host}/health-check/foo`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://${host}/health-check-foo`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://${host}/health-checknfoo`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://${host}/foo/health-check`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://${host}/foo-health-check`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://${host}/foonhealth-check`).then(h.verifyResponse(404)), - ]).then(done); - }); + describe(`pr-.${host}/*`, () => { - }); - - - describe(`${host}/create-build//`, () => { - - it('should disallow non-POST requests', done => { - const url = `${scheme}://${host}/create-build/${pr}/${sha9}`; - - Promise.all([ - h.runCmd(`curl -iLX GET ${url}`).then(h.verifyResponse([405, 'Not Allowed'])), - h.runCmd(`curl -iLX PUT ${url}`).then(h.verifyResponse([405, 'Not Allowed'])), - h.runCmd(`curl -iLX PATCH ${url}`).then(h.verifyResponse([405, 'Not Allowed'])), - h.runCmd(`curl -iLX DELETE ${url}`).then(h.verifyResponse([405, 'Not Allowed'])), - ]).then(done); - }); - - - it(`should reject files larger than ${h.uploadMaxSize}B (according to header)`, done => { - const headers = `--header "Content-Length: ${1.5 * h.uploadMaxSize}"`; - const url = `${scheme}://${host}/create-build/${pr}/${sha9}`; - - h.runCmd(`curl -iLX POST ${headers} ${url}`). - then(h.verifyResponse([413, 'Request Entity Too Large'])). - then(done); - }); - - - it(`should reject files larger than ${h.uploadMaxSize}B (without header)`, done => { - const filePath = path.join(h.buildsDir, 'snapshot.tar.gz'); - const url = `${scheme}://${host}/create-build/${pr}/${sha9}`; - - h.writeFile(filePath, {size: 1.5 * h.uploadMaxSize}); - - h.runCmd(`curl -iLX POST --data-binary "@${filePath}" ${url}`). - then(h.verifyResponse([413, 'Request Entity Too Large'])). - then(done); - }); - - - it('should pass requests through to the upload server', done => { - h.runCmd(`curl -iLX POST ${scheme}://${host}/create-build/${pr}/${sha9}`). - then(h.verifyResponse(401, /Missing or empty 'AUTHORIZATION' header/)). - then(done); - }); - - - it('should respond with 404 for unknown paths', done => { - const cmdPrefix = `curl -iLX POST ${scheme}://${host}`; - - Promise.all([ - h.runCmd(`${cmdPrefix}/foo/create-build/${pr}/${sha9}`).then(h.verifyResponse(404)), - h.runCmd(`${cmdPrefix}/foo-create-build/${pr}/${sha9}`).then(h.verifyResponse(404)), - h.runCmd(`${cmdPrefix}/fooncreate-build/${pr}/${sha9}`).then(h.verifyResponse(404)), - h.runCmd(`${cmdPrefix}/create-build/foo/${pr}/${sha9}`).then(h.verifyResponse(404)), - h.runCmd(`${cmdPrefix}/create-build-foo/${pr}/${sha9}`).then(h.verifyResponse(404)), - h.runCmd(`${cmdPrefix}/create-buildnfoo/${pr}/${sha9}`).then(h.verifyResponse(404)), - h.runCmd(`${cmdPrefix}/create-build/pr${pr}/${sha9}`).then(h.verifyResponse(404)), - h.runCmd(`${cmdPrefix}/create-build/${pr}/${sha9}42`).then(h.verifyResponse(404)), - ]).then(done); - }); - - - it('should reject PRs with leading zeros', done => { - h.runCmd(`curl -iLX POST ${scheme}://${host}/create-build/0${pr}/${sha9}`). - then(h.verifyResponse(404)). - then(done); - }); - - - it('should accept SHAs with leading zeros (but not ignore them)', done => { - const cmdPrefix = `curl -iLX POST ${scheme}://${host}/create-build/${pr}`; - const bodyRegex = /Missing or empty 'AUTHORIZATION' header/; - - Promise.all([ - h.runCmd(`${cmdPrefix}/0${sha9}`).then(h.verifyResponse(404)), - h.runCmd(`${cmdPrefix}/${sha0}`).then(h.verifyResponse(401, bodyRegex)), - ]).then(done); - }); - - }); - - - describe(`${host}/*`, () => { - - it('should respond with 404 for unkown URLs (even if the resource exists)', done => { - ['index.html', 'foo.js', 'foo/index.html'].forEach(relFilePath => { - const absFilePath = path.join(h.buildsDir, relFilePath); - h.writeFile(absFilePath, {content: `File: /${relFilePath}`}); + beforeEach(() => { + h.createDummyBuild(pr, sha9); + h.createDummyBuild(pr, sha0); + }); + + + it('should return /index.html', done => { + const origin = `${scheme}://pr${pr}-${sha9}.${host}`; + const bodyRegex = new RegExp(`^PR: ${pr} | SHA: ${sha9} | File: /index\\.html$`); + + Promise.all([ + h.runCmd(`curl -iL ${origin}/index.html`).then(h.verifyResponse(200, bodyRegex)), + h.runCmd(`curl -iL ${origin}/`).then(h.verifyResponse(200, bodyRegex)), + h.runCmd(`curl -iL ${origin}`).then(h.verifyResponse(200, bodyRegex)), + ]).then(done); + }); + + + it('should return /foo/bar.js', done => { + const bodyRegex = new RegExp(`^PR: ${pr} | SHA: ${sha9} | File: /foo/bar\\.js$`); + + h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}.${host}/foo/bar.js`). + then(h.verifyResponse(200, bodyRegex)). + then(done); + }); + + + it('should respond with 403 for directories', done => { + Promise.all([ + h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}.${host}/foo/`).then(h.verifyResponse(403)), + h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}.${host}/foo`).then(h.verifyResponse(403)), + ]).then(done); + }); + + + it('should respond with 404 for unknown paths to files', done => { + h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}.${host}/foo/baz.css`). + then(h.verifyResponse(404)). + then(done); + }); + + + it('should rewrite to \'index.html\' for unknown paths that don\'t look like files', done => { + const bodyRegex = new RegExp(`^PR: ${pr} | SHA: ${sha9} | File: /index\\.html$`); + + Promise.all([ + h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}.${host}/foo/baz`).then(h.verifyResponse(200, bodyRegex)), + h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}.${host}/foo/baz/`).then(h.verifyResponse(200, bodyRegex)), + ]).then(done); + }); + + + it('should respond with 404 for unknown PRs/SHAs', done => { + const otherPr = 54321; + const otherSha = '8'.repeat(40); + + Promise.all([ + h.runCmd(`curl -iL ${scheme}://pr${pr}9-${sha9}.${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://pr${otherPr}-${sha9}.${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha9}9.${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://pr${pr}-${otherSha}.${host}`).then(h.verifyResponse(404)), + ]).then(done); + }); + + + it('should respond with 404 if the subdomain format is wrong', done => { + Promise.all([ + h.runCmd(`curl -iL ${scheme}://xpr${pr}-${sha9}.${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://prx${pr}-${sha9}.${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://xx${pr}-${sha9}.${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://p${pr}-${sha9}.${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://r${pr}-${sha9}.${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://${pr}-${sha9}.${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://pr${pr}${sha9}.${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://pr${pr}_${sha9}.${host}`).then(h.verifyResponse(404)), + ]).then(done); + }); + + + it('should reject PRs with leading zeros', done => { + h.runCmd(`curl -iL ${scheme}://pr0${pr}-${sha9}.${host}`). + then(h.verifyResponse(404)). + then(done); + }); + + + it('should accept SHAs with leading zeros (but not ignore them)', done => { + const bodyRegex = new RegExp(`^PR: ${pr} | SHA: ${sha0} | File: /index\\.html$`); + + Promise.all([ + h.runCmd(`curl -iL ${scheme}://pr${pr}-0${sha9}.${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://pr${pr}-${sha0}.${host}`).then(h.verifyResponse(200, bodyRegex)), + ]).then(done); }); - Promise.all([ - h.runCmd(`curl -iL ${scheme}://${host}/index.html`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://${host}/`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://foo.${host}/index.html`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://foo.${host}/`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://foo.${host}`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://${host}/foo.js`).then(h.verifyResponse(404)), - h.runCmd(`curl -iL ${scheme}://${host}/foo/index.html`).then(h.verifyResponse(404)), - ]).then(done); }); - }); -})); + describe(`${host}/health-check`, () => { + + it('should respond with 200', done => { + Promise.all([ + h.runCmd(`curl -iL ${scheme}://${host}/health-check`).then(h.verifyResponse(200)), + h.runCmd(`curl -iL ${scheme}://${host}/health-check/`).then(h.verifyResponse(200)), + ]).then(done); + }); + + + it('should respond with 404 if the path does not match exactly', done => { + Promise.all([ + h.runCmd(`curl -iL ${scheme}://${host}/health-check/foo`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://${host}/health-check-foo`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://${host}/health-checknfoo`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://${host}/foo/health-check`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://${host}/foo-health-check`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://${host}/foonhealth-check`).then(h.verifyResponse(404)), + ]).then(done); + }); + + }); + + + describe(`${host}/create-build//`, () => { + + it('should disallow non-POST requests', done => { + const url = `${scheme}://${host}/create-build/${pr}/${sha9}`; + + Promise.all([ + h.runCmd(`curl -iLX GET ${url}`).then(h.verifyResponse([405, 'Not Allowed'])), + h.runCmd(`curl -iLX PUT ${url}`).then(h.verifyResponse([405, 'Not Allowed'])), + h.runCmd(`curl -iLX PATCH ${url}`).then(h.verifyResponse([405, 'Not Allowed'])), + h.runCmd(`curl -iLX DELETE ${url}`).then(h.verifyResponse([405, 'Not Allowed'])), + ]).then(done); + }); + + + it(`should reject files larger than ${h.uploadMaxSize}B (according to header)`, done => { + const headers = `--header "Content-Length: ${1.5 * h.uploadMaxSize}"`; + const url = `${scheme}://${host}/create-build/${pr}/${sha9}`; + + h.runCmd(`curl -iLX POST ${headers} ${url}`). + then(h.verifyResponse([413, 'Request Entity Too Large'])). + then(done); + }); + + + it(`should reject files larger than ${h.uploadMaxSize}B (without header)`, done => { + const filePath = path.join(h.buildsDir, 'snapshot.tar.gz'); + const url = `${scheme}://${host}/create-build/${pr}/${sha9}`; + + h.writeFile(filePath, {size: 1.5 * h.uploadMaxSize}); + + h.runCmd(`curl -iLX POST --data-binary "@${filePath}" ${url}`). + then(h.verifyResponse([413, 'Request Entity Too Large'])). + then(done); + }); + + + it('should pass requests through to the upload server', done => { + h.runCmd(`curl -iLX POST ${scheme}://${host}/create-build/${pr}/${sha9}`). + then(h.verifyResponse(401, /Missing or empty 'AUTHORIZATION' header/)). + then(done); + }); + + + it('should respond with 404 for unknown paths', done => { + const cmdPrefix = `curl -iLX POST ${scheme}://${host}`; + + Promise.all([ + h.runCmd(`${cmdPrefix}/foo/create-build/${pr}/${sha9}`).then(h.verifyResponse(404)), + h.runCmd(`${cmdPrefix}/foo-create-build/${pr}/${sha9}`).then(h.verifyResponse(404)), + h.runCmd(`${cmdPrefix}/fooncreate-build/${pr}/${sha9}`).then(h.verifyResponse(404)), + h.runCmd(`${cmdPrefix}/create-build/foo/${pr}/${sha9}`).then(h.verifyResponse(404)), + h.runCmd(`${cmdPrefix}/create-build-foo/${pr}/${sha9}`).then(h.verifyResponse(404)), + h.runCmd(`${cmdPrefix}/create-buildnfoo/${pr}/${sha9}`).then(h.verifyResponse(404)), + h.runCmd(`${cmdPrefix}/create-build/pr${pr}/${sha9}`).then(h.verifyResponse(404)), + h.runCmd(`${cmdPrefix}/create-build/${pr}/${sha9}42`).then(h.verifyResponse(404)), + ]).then(done); + }); + + + it('should reject PRs with leading zeros', done => { + h.runCmd(`curl -iLX POST ${scheme}://${host}/create-build/0${pr}/${sha9}`). + then(h.verifyResponse(404)). + then(done); + }); + + + it('should accept SHAs with leading zeros (but not ignore them)', done => { + const cmdPrefix = `curl -iLX POST ${scheme}://${host}/create-build/${pr}`; + const bodyRegex = /Missing or empty 'AUTHORIZATION' header/; + + Promise.all([ + h.runCmd(`${cmdPrefix}/0${sha9}`).then(h.verifyResponse(404)), + h.runCmd(`${cmdPrefix}/${sha0}`).then(h.verifyResponse(401, bodyRegex)), + ]).then(done); + }); + + }); + + + describe(`${host}/*`, () => { + + it('should respond with 404 for unkown URLs (even if the resource exists)', done => { + ['index.html', 'foo.js', 'foo/index.html'].forEach(relFilePath => { + const absFilePath = path.join(h.buildsDir, relFilePath); + h.writeFile(absFilePath, {content: `File: /${relFilePath}`}); + }); + + Promise.all([ + h.runCmd(`curl -iL ${scheme}://${host}/index.html`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://${host}/`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://foo.${host}/index.html`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://foo.${host}/`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://foo.${host}`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://${host}/foo.js`).then(h.verifyResponse(404)), + h.runCmd(`curl -iL ${scheme}://${host}/foo/index.html`).then(h.verifyResponse(404)), + ]).then(done); + }); + + }); + + })); + +});