Decode req.path before loading object from S3 bucket.

Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Eric Peterson
2021-05-07 14:57:19 +02:00
parent 4916a6e23d
commit 3ebfa8f189
2 changed files with 45 additions and 2 deletions
@@ -21,6 +21,8 @@ import {
ENTITY_DEFAULT_NAMESPACE,
} from '@backstage/catalog-model';
import { ConfigReader } from '@backstage/config';
import express from 'express';
import request from 'supertest';
import mockFs from 'mock-fs';
import os from 'os';
import path from 'path';
@@ -272,4 +274,45 @@ describe('AwsS3Publish', () => {
});
});
});
describe('docsRouter', () => {
let app: express.Express;
const entity = createMockEntity();
const entityRootDir = getEntityRootDir(entity);
beforeEach(() => {
app = express().use(publisher.docsRouter());
mockFs.restore();
mockFs({
[entityRootDir]: {
img: {
'with spaces.png': 'found it',
},
'some folder': {
'also with spaces.js': 'found it too',
},
},
});
});
it('should pass expected object path to bucket', async () => {
const {
kind,
metadata: { namespace, name },
} = entity;
// Ensures leading slash is trimmed and encoded path is decoded.
const pngResponse = await request(app).get(
`/${namespace}/${kind}/${name}/img/with%20spaces.png`,
);
expect(Buffer.from(pngResponse.body).toString('utf8')).toEqual(
'found it',
);
const jsResponse = await request(app).get(
`/${namespace}/${kind}/${name}/some%20folder/also%20with%20spaces.js`,
);
expect(jsResponse.text).toEqual('found it too');
});
});
});
@@ -263,9 +263,9 @@ export class AwsS3Publish implements PublisherBase {
*/
docsRouter(): express.Handler {
return async (req, res) => {
// Trim the leading forward slash
// Decode and trim the leading forward slash
// filePath example - /default/Component/documented-component/index.html
const filePath = req.path.replace(/^\//, '');
const filePath = decodeURI(req.path.replace(/^\//, ''));
// Files with different extensions (CSS, HTML) need to be served with different headers
const fileExtension = path.extname(filePath);