Add cache-control for assets served via registerStaticDir (#102756)

* Add cache-control for assets served via `registerStaticDir`

* fix case

* add test for 'dynamic' file content
This commit is contained in:
Pierre Gayvallet 2021-06-22 12:53:32 +02:00 committed by GitHub
parent df8637ae47
commit fc55c30e8b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 136 additions and 5 deletions

View file

@ -7,9 +7,10 @@
*/
import { Server } from 'http';
import { readFileSync } from 'fs';
import { rmdir, mkdtemp, readFile, writeFile } from 'fs/promises';
import supertest from 'supertest';
import { omit } from 'lodash';
import { join } from 'path';
import { ByteSizeValue, schema } from '@kbn/config-schema';
import { HttpConfig } from './http_config';
@ -47,9 +48,9 @@ const enhanceWithContext = (fn: (...args: any[]) => any) => fn.bind(null, {});
let certificate: string;
let key: string;
beforeAll(() => {
certificate = readFileSync(KBN_CERT_PATH, 'utf8');
key = readFileSync(KBN_KEY_PATH, 'utf8');
beforeAll(async () => {
certificate = await readFile(KBN_CERT_PATH, 'utf8');
key = await readFile(KBN_KEY_PATH, 'utf8');
});
beforeEach(() => {
@ -1409,6 +1410,19 @@ describe('setup contract', () => {
});
describe('#registerStaticDir', () => {
const assetFolder = join(__dirname, 'integration_tests', 'fixtures', 'static');
let tempDir: string;
beforeAll(async () => {
tempDir = await mkdtemp('cache-test');
});
afterAll(async () => {
if (tempDir) {
await rmdir(tempDir, { recursive: true });
}
});
test('does not throw if called after stop', async () => {
const { registerStaticDir } = await server.setup(config);
await server.stop();
@ -1416,6 +1430,111 @@ describe('setup contract', () => {
registerStaticDir('/path1/{path*}', '/path/to/resource');
}).not.toThrow();
});
test('returns correct headers for static assets', async () => {
const { registerStaticDir, server: innerServer } = await server.setup(config);
registerStaticDir('/static/{path*}', assetFolder);
await server.start();
const response = await supertest(innerServer.listener)
.get('/static/some_json.json')
.expect(200);
expect(response.get('cache-control')).toEqual('must-revalidate');
expect(response.get('etag')).not.toBeUndefined();
});
test('returns compressed version if present', async () => {
const { registerStaticDir, server: innerServer } = await server.setup(config);
registerStaticDir('/static/{path*}', assetFolder);
await server.start();
const response = await supertest(innerServer.listener)
.get('/static/compression_available.json')
.set('accept-encoding', 'gzip')
.expect(200);
expect(response.get('cache-control')).toEqual('must-revalidate');
expect(response.get('etag')).not.toBeUndefined();
expect(response.get('content-encoding')).toEqual('gzip');
});
test('returns uncompressed version if compressed asset is not available', async () => {
const { registerStaticDir, server: innerServer } = await server.setup(config);
registerStaticDir('/static/{path*}', assetFolder);
await server.start();
const response = await supertest(innerServer.listener)
.get('/static/some_json.json')
.set('accept-encoding', 'gzip')
.expect(200);
expect(response.get('cache-control')).toEqual('must-revalidate');
expect(response.get('etag')).not.toBeUndefined();
expect(response.get('content-encoding')).toBeUndefined();
});
test('returns a 304 if etag value matches', async () => {
const { registerStaticDir, server: innerServer } = await server.setup(config);
registerStaticDir('/static/{path*}', assetFolder);
await server.start();
const response = await supertest(innerServer.listener)
.get('/static/some_json.json')
.expect(200);
const etag = response.get('etag');
expect(etag).not.toBeUndefined();
await supertest(innerServer.listener)
.get('/static/some_json.json')
.set('If-None-Match', etag)
.expect(304);
});
test('serves content if etag values does not match', async () => {
const { registerStaticDir, server: innerServer } = await server.setup(config);
registerStaticDir('/static/{path*}', assetFolder);
await server.start();
await supertest(innerServer.listener)
.get('/static/some_json.json')
.set('If-None-Match', `"definitely not a valid etag"`)
.expect(200);
});
test('dynamically updates depending on the content of the file', async () => {
const tempFile = join(tempDir, 'some_file.json');
const { registerStaticDir, server: innerServer } = await server.setup(config);
registerStaticDir('/static/{path*}', tempDir);
await server.start();
await supertest(innerServer.listener).get('/static/some_file.json').expect(404);
await writeFile(tempFile, `{ "over": 9000 }`);
let response = await supertest(innerServer.listener)
.get('/static/some_file.json')
.expect(200);
const etag1 = response.get('etag');
await writeFile(tempFile, `{ "over": 42 }`);
response = await supertest(innerServer.listener).get('/static/some_file.json').expect(200);
const etag2 = response.get('etag');
expect(etag1).not.toEqual(etag2);
});
});
describe('#registerOnPreRouting', () => {

View file

@ -465,7 +465,13 @@ export class HttpServer {
lookupCompressed: true,
},
},
options: { auth: false },
options: {
auth: false,
cache: {
privacy: 'public',
otherwise: 'must-revalidate',
},
},
});
}

View file

@ -0,0 +1,3 @@
{
"hello": "dolly"
}

View file

@ -0,0 +1,3 @@
{
"foo": "bar"
}