Skip to content

Commit

Permalink
[Maps] Use content-encoding header from ES for mvt response (elastic#…
Browse files Browse the repository at this point in the history
…130417)

* 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`.
  • Loading branch information
nickpeihl authored and kertal committed May 24, 2022
1 parent 7f2d1d7 commit 1e925fc
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 13 deletions.
7 changes: 4 additions & 3 deletions x-pack/plugins/maps/server/mvt/get_grid_tile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import { CoreStart, Logger } from '@kbn/core/server';
import type { DataRequestHandlerContext } from '@kbn/data-plugin/server';
import { IncomingHttpHeaders } from 'http';
import { Stream } from 'stream';
import { RENDER_AS } from '../../common/constants';
import { isAbortError } from './util';
Expand Down Expand Up @@ -40,7 +41,7 @@ export async function getEsGridTile({
renderAs: RENDER_AS;
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 = {
Expand Down Expand Up @@ -80,13 +81,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 changes: 4 additions & 3 deletions x-pack/plugins/maps/server/mvt/get_tile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import { CoreStart, Logger } from '@kbn/core/server';
import type { DataRequestHandlerContext } from '@kbn/data-plugin/server';
import { IncomingHttpHeaders } from 'http';
import { Stream } from 'stream';
import { isAbortError } from './util';
import { makeExecutionContext } from '../../common/execution_context';
Expand Down Expand Up @@ -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}`;

Expand Down Expand Up @@ -80,13 +81,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 };
}
}
22 changes: 15 additions & 7 deletions x-pack/plugins/maps/server/mvt/mvt_routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import { Stream } from 'stream';
import { IncomingHttpHeaders } from 'http';
import { schema } from '@kbn/config-schema';
import { CoreStart, KibanaRequest, KibanaResponseFactory, Logger } from '@kbn/core/server';
import { IRouter } from '@kbn/core/server';
Expand Down Expand Up @@ -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,
Expand All @@ -71,7 +72,7 @@ export function initMVTRoutes({
abortController,
});

return sendResponse(response, gzippedTile);
return sendResponse(response, stream, headers);
}
);

Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down

0 comments on commit 1e925fc

Please sign in to comment.