mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* Use content-encoding header from ES for mvt
We can't always assume the content-encoding will be gzip. When SSL is enabled in Elasticsearch, the http.compression is disabled by default. We can use the headers from the Elasticsearch response to form the Kibana response.
You should have HTTPS enabled to test this PR. Use `yarn es snapshot --ssl` and `yarn start --ssl`.
(cherry picked from commit ac5aca44e8
)
This commit is contained in:
parent
2a32e1ce88
commit
1d76973116
3 changed files with 23 additions and 13 deletions
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { CoreStart, Logger } from 'src/core/server';
|
||||
import type { DataRequestHandlerContext } from 'src/plugins/data/server';
|
||||
import { IncomingHttpHeaders } from 'http';
|
||||
import { Stream } from 'stream';
|
||||
import { RENDER_AS } from '../../common/constants';
|
||||
import { isAbortError } from './util';
|
||||
|
@ -40,7 +41,7 @@ export async function getEsGridTile({
|
|||
requestType: RENDER_AS.GRID | RENDER_AS.POINT;
|
||||
gridPrecision: number;
|
||||
abortController: AbortController;
|
||||
}): Promise<Stream | null> {
|
||||
}): Promise<{ stream: Stream | null; headers?: IncomingHttpHeaders }> {
|
||||
try {
|
||||
const path = `/${encodeURIComponent(index)}/_mvt/${geometryFieldName}/${z}/${x}/${y}`;
|
||||
const body = {
|
||||
|
@ -78,13 +79,13 @@ export async function getEsGridTile({
|
|||
}
|
||||
);
|
||||
|
||||
return tile.body as Stream;
|
||||
return { stream: tile.body as Stream, headers: tile.headers };
|
||||
} catch (e) {
|
||||
if (!isAbortError(e)) {
|
||||
// These are often circuit breaking exceptions
|
||||
// Should return a tile with some error message
|
||||
logger.warn(`Cannot generate ES-grid-tile for ${z}/${x}/${y}: ${e.message}`);
|
||||
}
|
||||
return null;
|
||||
return { stream: null };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { CoreStart, Logger } from 'src/core/server';
|
||||
import type { DataRequestHandlerContext } from 'src/plugins/data/server';
|
||||
import { IncomingHttpHeaders } from 'http';
|
||||
import { Stream } from 'stream';
|
||||
import { isAbortError } from './util';
|
||||
import { makeExecutionContext } from '../../common/execution_context';
|
||||
|
@ -36,7 +37,7 @@ export async function getEsTile({
|
|||
logger: Logger;
|
||||
requestBody: any;
|
||||
abortController: AbortController;
|
||||
}): Promise<Stream | null> {
|
||||
}): Promise<{ stream: Stream | null; headers?: IncomingHttpHeaders }> {
|
||||
try {
|
||||
const path = `/${encodeURIComponent(index)}/_mvt/${geometryFieldName}/${z}/${x}/${y}`;
|
||||
|
||||
|
@ -79,13 +80,13 @@ export async function getEsTile({
|
|||
}
|
||||
);
|
||||
|
||||
return tile.body as Stream;
|
||||
return { stream: tile.body as Stream, headers: tile.headers };
|
||||
} catch (e) {
|
||||
if (!isAbortError(e)) {
|
||||
// These are often circuit breaking exceptions
|
||||
// Should return a tile with some error message
|
||||
logger.warn(`Cannot generate ES-grid-tile for ${z}/${x}/${y}: ${e.message}`);
|
||||
}
|
||||
return null;
|
||||
return { stream: null };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { Stream } from 'stream';
|
||||
import { IncomingHttpHeaders } from 'http';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { CoreStart, KibanaRequest, KibanaResponseFactory, Logger } from 'src/core/server';
|
||||
import { IRouter } from 'src/core/server';
|
||||
|
@ -57,7 +58,7 @@ export function initMVTRoutes({
|
|||
|
||||
const abortController = makeAbortController(request);
|
||||
|
||||
const gzippedTile = await getEsTile({
|
||||
const { stream, headers } = await getEsTile({
|
||||
url: `${API_ROOT_PATH}/${MVT_GETTILE_API_PATH}/{z}/{x}/{y}.pbf`,
|
||||
core,
|
||||
logger,
|
||||
|
@ -71,7 +72,7 @@ export function initMVTRoutes({
|
|||
abortController,
|
||||
});
|
||||
|
||||
return sendResponse(response, gzippedTile);
|
||||
return sendResponse(response, stream, headers);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -103,7 +104,7 @@ export function initMVTRoutes({
|
|||
|
||||
const abortController = makeAbortController(request);
|
||||
|
||||
const gzipTileStream = await getEsGridTile({
|
||||
const { stream, headers } = await getEsGridTile({
|
||||
url: `${API_ROOT_PATH}/${MVT_GETGRIDTILE_API_PATH}/{z}/{x}/{y}.pbf`,
|
||||
core,
|
||||
logger,
|
||||
|
@ -119,20 +120,27 @@ export function initMVTRoutes({
|
|||
abortController,
|
||||
});
|
||||
|
||||
return sendResponse(response, gzipTileStream);
|
||||
return sendResponse(response, stream, headers);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function sendResponse(response: KibanaResponseFactory, gzipTileStream: Stream | null) {
|
||||
function sendResponse(
|
||||
response: KibanaResponseFactory,
|
||||
gzipTileStream: Stream | null,
|
||||
headers?: IncomingHttpHeaders
|
||||
) {
|
||||
const cacheControl = `public, max-age=${CACHE_TIMEOUT_SECONDS}`;
|
||||
const lastModified = `${new Date().toUTCString()}`;
|
||||
if (gzipTileStream) {
|
||||
if (gzipTileStream && headers) {
|
||||
// use the content-encoding and content-length headers from elasticsearch if they exist
|
||||
const { 'content-length': contentLength, 'content-encoding': contentEncoding } = headers;
|
||||
return response.ok({
|
||||
body: gzipTileStream,
|
||||
headers: {
|
||||
'content-disposition': 'inline',
|
||||
'content-encoding': 'gzip',
|
||||
...(contentLength && { 'content-length': contentLength }),
|
||||
...(contentEncoding && { 'content-encoding': contentEncoding }),
|
||||
'Content-Type': 'application/x-protobuf',
|
||||
'Cache-Control': cacheControl,
|
||||
'Last-Modified': lastModified,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue