mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
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:
parent
df8637ae47
commit
fc55c30e8b
5 changed files with 136 additions and 5 deletions
|
@ -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', () => {
|
||||
|
|
|
@ -465,7 +465,13 @@ export class HttpServer {
|
|||
lookupCompressed: true,
|
||||
},
|
||||
},
|
||||
options: { auth: false },
|
||||
options: {
|
||||
auth: false,
|
||||
cache: {
|
||||
privacy: 'public',
|
||||
otherwise: 'must-revalidate',
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"hello": "dolly"
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"foo": "bar"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue