diff --git a/packages/template-mrt-reference-app/app/ssr.js b/packages/template-mrt-reference-app/app/ssr.js index 899cc03217..fcfa0a1a8a 100644 --- a/packages/template-mrt-reference-app/app/ssr.js +++ b/packages/template-mrt-reference-app/app/ssr.js @@ -65,6 +65,7 @@ const ENVS_TO_EXPOSE = [ 'aws_lambda_log_stream_name', 'aws_region', 'bundle_id', + 'mrt_env_base_path', // These "customer" defined environment variables are set by the Manager // and expected by the MRT smoke test suite 'customer_*', @@ -353,6 +354,19 @@ const loggingMiddleware = (req, res, next) => { return next() } +const envBasePathMiddleware = (req, res, next) => { + const basePath = process.env.MRT_ENV_BASE_PATH + console.log(`Base path: ${basePath}`) + console.log(`Request path: ${req.url}`) + if (basePath && req.url.startsWith(basePath)) { + req.url = req.path.slice(basePath.length) || '/' + console.log( + `Base path: Rewrote ${basePath} -> Request path: ${req.originalUrl} -> New path: ${req.url}` + ) + } + return next() +} + const options = { // The build directory (an absolute path) buildDir: path.resolve(process.cwd(), 'build'), @@ -387,7 +401,8 @@ const {handler, app, server} = runtime.createHandler(options, (app) => { // Add middleware to log request and response headers app.use(loggingMiddleware) - + // Add a middleware to consume the base path from the request path if one is set + app.use(envBasePathMiddleware) // Configure routes app.all('/exception', exception) app.get('/tls', tlsVersionTest) diff --git a/packages/template-mrt-reference-app/app/ssr.test.js b/packages/template-mrt-reference-app/app/ssr.test.js index 302ef3d65c..3f48754b00 100644 --- a/packages/template-mrt-reference-app/app/ssr.test.js +++ b/packages/template-mrt-reference-app/app/ssr.test.js @@ -16,7 +16,6 @@ const { } = require('@aws-sdk/client-cloudwatch-logs') const {mockClient} = require('aws-sdk-client-mock') const {ServiceException} = require('@smithy/smithy-client') - class AccessDenied extends ServiceException { constructor(options) { super({...options, name: 'AccessDenied'}) @@ -28,6 +27,25 @@ describe('server', () => { const lambdaMock = mockClient(LambdaClient) const s3Mock = mockClient(S3Client) const logsMock = mockClient(CloudWatchLogsClient) + const pathsToCheck = [ + ['/', 200, 'application/json; charset=utf-8'], + ['/tls', 200, 'application/json; charset=utf-8'], + ['/exception', 500, 'text/html; charset=utf-8'], + ['/cache', 200, 'application/json; charset=utf-8'], + ['/cookie', 200, 'application/json; charset=utf-8'], + ['/set-response-headers', 200, 'application/json; charset=utf-8'], + ['/isolation', 200, 'application/json; charset=utf-8'], + ['/memtest', 200, 'application/json; charset=utf-8'], + ['/streaming-large', 200, 'application/json; charset=utf-8'] + ] + const pathsToCheckWithBasePath = (basePath) => { + return pathsToCheck.map((pathStatusContentType) => [ + basePath + pathStatusContentType[0], + pathStatusContentType[1], + pathStatusContentType[2] + ]) + } + beforeEach(() => { originalEnv = process.env process.env = Object.assign({}, process.env, { @@ -53,22 +71,26 @@ describe('server', () => { server.close() jest.restoreAllMocks() }) - test.each([ - ['/', 200, 'application/json; charset=utf-8'], - ['/tls', 200, 'application/json; charset=utf-8'], - ['/exception', 500, 'text/html; charset=utf-8'], - ['/cache', 200, 'application/json; charset=utf-8'], - ['/cookie', 200, 'application/json; charset=utf-8'], - ['/set-response-headers', 200, 'application/json; charset=utf-8'], - ['/isolation', 200, 'application/json; charset=utf-8'], - ['/memtest', 200, 'application/json; charset=utf-8'], - ['/streaming-large', 200, 'application/json; charset=utf-8'] - ])('Path %p should render correctly', (path, expectedStatus, expectedContentType) => { - return request(app) - .get(path) - .expect(expectedStatus) - .expect('Content-Type', expectedContentType) - }) + test.each(pathsToCheck)( + 'Path %p should render correctly', + (path, expectedStatus, expectedContentType) => { + return request(app) + .get(path) + .expect(expectedStatus) + .expect('Content-Type', expectedContentType) + } + ) + + test.each(pathsToCheckWithBasePath('/test-base-path'))( + 'Path %p should render correctly', + (path, expectedStatus, expectedContentType) => { + process.env.MRT_ENV_BASE_PATH = '/test-base-path' + return request(app) + .get(path) + .expect(expectedStatus) + .expect('Content-Type', expectedContentType) + } + ) test('Path "/cache" has Cache-Control set', () => { return request(app).get('/cache').expect('Cache-Control', 's-maxage=60')