mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
* expose IncomingMessage from KibanaRequest It's applied to identify incoming requests across New and Legacy platforms. We can rely on the value if want to attach additional information to incoming requests without mutating them. * support attaching basePath information to incoming requests * Support Url changing for incoming requests * add tests * use NP API in the legacy platform * relax KibanaRequest typings * check basePath cannot be set twice * address @eli comments * generate docs
This commit is contained in:
parent
b30723ab96
commit
8ca20f554b
17 changed files with 292 additions and 43 deletions
|
@ -8,7 +8,7 @@
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export declare class KibanaRequest<Params, Query, Body>
|
||||
export declare class KibanaRequest<Params = unknown, Query = unknown, Body = unknown>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
@ -27,4 +27,5 @@ export declare class KibanaRequest<Params, Query, Body>
|
|||
| --- | --- | --- |
|
||||
| [from(req, routeSchemas)](./kibana-plugin-server.kibanarequest.from.md) | <code>static</code> | Factory for creating requests. Validates the request before creating an instance of a KibanaRequest. |
|
||||
| [getFilteredHeaders(headersToKeep)](./kibana-plugin-server.kibanarequest.getfilteredheaders.md) | | |
|
||||
| [unstable\_getIncomingMessage()](./kibana-plugin-server.kibanarequest.unstable_getincomingmessage.md) | | |
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [KibanaRequest](./kibana-plugin-server.kibanarequest.md) > [unstable\_getIncomingMessage](./kibana-plugin-server.kibanarequest.unstable_getincomingmessage.md)
|
||||
|
||||
## KibanaRequest.unstable\_getIncomingMessage() method
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
unstable_getIncomingMessage(): import("http").IncomingMessage;
|
||||
```
|
||||
<b>Returns:</b>
|
||||
|
||||
`import("http").IncomingMessage`
|
||||
|
|
@ -19,4 +19,5 @@ export interface OnRequestToolkit
|
|||
| [next](./kibana-plugin-server.onrequesttoolkit.next.md) | <code>() => OnRequestResult</code> | To pass request to the next handler |
|
||||
| [redirected](./kibana-plugin-server.onrequesttoolkit.redirected.md) | <code>(url: string) => OnRequestResult</code> | To interrupt request handling and redirect to a configured url |
|
||||
| [rejected](./kibana-plugin-server.onrequesttoolkit.rejected.md) | <code>(error: Error, options?: {`<p/>` statusCode?: number;`<p/>` }) => OnRequestResult</code> | Fail the request with specified error. |
|
||||
| [setUrl](./kibana-plugin-server.onrequesttoolkit.seturl.md) | <code>(newUrl: string | Url) => void</code> | Change url for an incoming request. |
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index) > [kibana-plugin-server](./kibana-plugin-server.md) > [OnRequestToolkit](./kibana-plugin-server.onrequesttoolkit.md) > [setUrl](./kibana-plugin-server.onrequesttoolkit.seturl.md)
|
||||
|
||||
## OnRequestToolkit.setUrl property
|
||||
|
||||
Change url for an incoming request.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
setUrl: (newUrl: string | Url) => void;
|
||||
```
|
|
@ -10,5 +10,7 @@
|
|||
http: {
|
||||
registerAuth: HttpServiceSetup['registerAuth'];
|
||||
registerOnRequest: HttpServiceSetup['registerOnRequest'];
|
||||
getBasePathFor: HttpServiceSetup['getBasePathFor'];
|
||||
setBasePathFor: HttpServiceSetup['setBasePathFor'];
|
||||
};
|
||||
```
|
||||
|
|
|
@ -17,5 +17,5 @@ export interface PluginSetupContext
|
|||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [elasticsearch](./kibana-plugin-server.pluginsetupcontext.elasticsearch.md) | <code>{`<p/>` adminClient$: Observable<ClusterClient>;`<p/>` dataClient$: Observable<ClusterClient>;`<p/>` }</code> | |
|
||||
| [http](./kibana-plugin-server.pluginsetupcontext.http.md) | <code>{`<p/>` registerAuth: HttpServiceSetup['registerAuth'];`<p/>` registerOnRequest: HttpServiceSetup['registerOnRequest'];`<p/>` }</code> | |
|
||||
| [http](./kibana-plugin-server.pluginsetupcontext.http.md) | <code>{`<p/>` registerAuth: HttpServiceSetup['registerAuth'];`<p/>` registerOnRequest: HttpServiceSetup['registerOnRequest'];`<p/>` getBasePathFor: HttpServiceSetup['getBasePathFor'];`<p/>` setBasePathFor: HttpServiceSetup['setBasePathFor'];`<p/>` }</code> | |
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import { ByteSizeValue } from '@kbn/config-schema';
|
|||
import { HttpConfig, Router } from '.';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { HttpServer } from './http_server';
|
||||
import { KibanaRequest } from './router';
|
||||
|
||||
const chance = new Chance();
|
||||
|
||||
|
@ -613,3 +614,97 @@ test('throws an error if starts without set up', async () => {
|
|||
`"Http server is not setup up yet"`
|
||||
);
|
||||
});
|
||||
|
||||
test('#getBasePathFor() returns base path associated with an incoming request', async () => {
|
||||
const {
|
||||
getBasePathFor,
|
||||
setBasePathFor,
|
||||
registerRouter,
|
||||
server: innerServer,
|
||||
registerOnRequest,
|
||||
} = await server.setup(config);
|
||||
|
||||
const path = '/base-path';
|
||||
registerOnRequest((req, t) => {
|
||||
setBasePathFor(req, path);
|
||||
return t.next();
|
||||
});
|
||||
|
||||
const router = new Router('/');
|
||||
router.get({ path: '/', validate: false }, (req, res) => res.ok({ key: getBasePathFor(req) }));
|
||||
registerRouter(router);
|
||||
|
||||
await server.start(config);
|
||||
await supertest(innerServer.listener)
|
||||
.get('/')
|
||||
.expect(200)
|
||||
.then(res => {
|
||||
expect(res.body).toEqual({ key: path });
|
||||
});
|
||||
});
|
||||
|
||||
test('#getBasePathFor() is based on server base path', async () => {
|
||||
const configWithBasePath = {
|
||||
...config,
|
||||
basePath: '/bar',
|
||||
};
|
||||
const {
|
||||
getBasePathFor,
|
||||
setBasePathFor,
|
||||
registerRouter,
|
||||
server: innerServer,
|
||||
registerOnRequest,
|
||||
} = await server.setup(configWithBasePath);
|
||||
|
||||
const path = '/base-path';
|
||||
registerOnRequest((req, t) => {
|
||||
setBasePathFor(req, path);
|
||||
return t.next();
|
||||
});
|
||||
|
||||
const router = new Router('/');
|
||||
router.get({ path: '/', validate: false }, async (req, res) =>
|
||||
res.ok({ key: getBasePathFor(req) })
|
||||
);
|
||||
registerRouter(router);
|
||||
|
||||
await server.start(configWithBasePath);
|
||||
await supertest(innerServer.listener)
|
||||
.get('/')
|
||||
.expect(200)
|
||||
.then(res => {
|
||||
expect(res.body).toEqual({ key: `${configWithBasePath.basePath}${path}` });
|
||||
});
|
||||
});
|
||||
|
||||
test('#setBasePathFor() cannot be set twice for one request', async () => {
|
||||
const incomingMessage = {
|
||||
url: '/',
|
||||
};
|
||||
const kibanaRequestFactory = {
|
||||
from() {
|
||||
return KibanaRequest.from(
|
||||
{
|
||||
headers: {},
|
||||
path: '/',
|
||||
raw: {
|
||||
req: incomingMessage,
|
||||
},
|
||||
} as any,
|
||||
undefined
|
||||
);
|
||||
},
|
||||
};
|
||||
jest.doMock('./router/request', () => ({
|
||||
KibanaRequest: jest.fn(() => kibanaRequestFactory),
|
||||
}));
|
||||
|
||||
const { setBasePathFor } = await server.setup(config);
|
||||
|
||||
const setPath = () => setBasePathFor(kibanaRequestFactory.from(), '/path');
|
||||
|
||||
setPath();
|
||||
expect(setPath).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Request basePath was previously set. Setting multiple times is not supported."`
|
||||
);
|
||||
});
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { Server, ServerOptions } from 'hapi';
|
||||
import { Request, Server, ServerOptions } from 'hapi';
|
||||
|
||||
import { modifyUrl } from '../../utils';
|
||||
import { Logger } from '../logging';
|
||||
|
@ -25,8 +25,7 @@ import { HttpConfig } from './http_config';
|
|||
import { createServer, getServerOptions } from './http_tools';
|
||||
import { adoptToHapiAuthFormat, AuthenticationHandler } from './lifecycle/auth';
|
||||
import { adoptToHapiOnRequestFormat, OnRequestHandler } from './lifecycle/on_request';
|
||||
import { Router } from './router';
|
||||
|
||||
import { Router, KibanaRequest } from './router';
|
||||
import {
|
||||
SessionStorageCookieOptions,
|
||||
createCookieSessionStorageFactory,
|
||||
|
@ -50,12 +49,18 @@ export interface HttpServerSetup {
|
|||
* Can register any number of OnRequestHandlers, which are called in sequence (from the first registered to the last)
|
||||
*/
|
||||
registerOnRequest: (requestHandler: OnRequestHandler) => void;
|
||||
getBasePathFor: (request: KibanaRequest | Request) => string;
|
||||
setBasePathFor: (request: KibanaRequest | Request, basePath: string) => void;
|
||||
}
|
||||
|
||||
export class HttpServer {
|
||||
private server?: Server;
|
||||
private registeredRouters = new Set<Router>();
|
||||
private authRegistered = false;
|
||||
private basePathCache = new WeakMap<
|
||||
ReturnType<KibanaRequest['unstable_getIncomingMessage']>,
|
||||
string
|
||||
>();
|
||||
|
||||
constructor(private readonly log: Logger) {}
|
||||
|
||||
|
@ -72,6 +77,28 @@ export class HttpServer {
|
|||
this.registeredRouters.add(router);
|
||||
}
|
||||
|
||||
// passing hapi Request works for BWC. can be deleted once we remove legacy server.
|
||||
private getBasePathFor(config: HttpConfig, request: KibanaRequest | Request) {
|
||||
const incomingMessage =
|
||||
request instanceof KibanaRequest ? request.unstable_getIncomingMessage() : request.raw.req;
|
||||
|
||||
const requestScopePath = this.basePathCache.get(incomingMessage) || '';
|
||||
const serverBasePath = config.basePath || '';
|
||||
return `${serverBasePath}${requestScopePath}`;
|
||||
}
|
||||
|
||||
// should work only for KibanaRequest as soon as spaces migrate to NP
|
||||
private setBasePathFor(request: KibanaRequest | Request, basePath: string) {
|
||||
const incomingMessage =
|
||||
request instanceof KibanaRequest ? request.unstable_getIncomingMessage() : request.raw.req;
|
||||
if (this.basePathCache.has(incomingMessage)) {
|
||||
throw new Error(
|
||||
'Request basePath was previously set. Setting multiple times is not supported.'
|
||||
);
|
||||
}
|
||||
this.basePathCache.set(incomingMessage, basePath);
|
||||
}
|
||||
|
||||
public setup(config: HttpConfig): HttpServerSetup {
|
||||
const serverOptions = getServerOptions(config);
|
||||
this.server = createServer(serverOptions);
|
||||
|
@ -84,6 +111,8 @@ export class HttpServer {
|
|||
fn: AuthenticationHandler<T>,
|
||||
cookieOptions: SessionStorageCookieOptions<T>
|
||||
) => this.registerAuth(fn, cookieOptions, config.basePath),
|
||||
getBasePathFor: this.getBasePathFor.bind(this, config),
|
||||
setBasePathFor: this.setBasePathFor.bind(this),
|
||||
// Return server instance with the connection options so that we can properly
|
||||
// bridge core and the "legacy" Kibana internally. Once this bridge isn't
|
||||
// needed anymore we shouldn't return the instance from this method.
|
||||
|
|
|
@ -26,6 +26,8 @@ const createSetupContractMock = () => {
|
|||
registerAuth: jest.fn(),
|
||||
registerOnRequest: jest.fn(),
|
||||
registerRouter: jest.fn(),
|
||||
getBasePathFor: jest.fn(),
|
||||
setBasePathFor: jest.fn(),
|
||||
// we can mock some hapi server method when we need it
|
||||
server: {} as Server,
|
||||
};
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
|
||||
import path from 'path';
|
||||
import { parse } from 'url';
|
||||
|
||||
import request from 'request';
|
||||
import * as kbnTestServer from '../../../../test_utils/kbn_server';
|
||||
import { Router } from '../router';
|
||||
|
@ -27,12 +29,12 @@ import { url as onReqUrl } from './__fixtures__/plugins/dummy_on_request/server/
|
|||
describe('http service', () => {
|
||||
describe('setup contract', () => {
|
||||
describe('#registerAuth()', () => {
|
||||
const dummySecurityPlugin = path.resolve(__dirname, './__fixtures__/plugins/dummy_security');
|
||||
const plugin = path.resolve(__dirname, './__fixtures__/plugins/dummy_security');
|
||||
let root: ReturnType<typeof kbnTestServer.createRoot>;
|
||||
beforeAll(async () => {
|
||||
root = kbnTestServer.createRoot(
|
||||
{
|
||||
plugins: { paths: [dummySecurityPlugin] },
|
||||
plugins: { paths: [plugin] },
|
||||
},
|
||||
{
|
||||
dev: true,
|
||||
|
@ -109,15 +111,12 @@ describe('http service', () => {
|
|||
});
|
||||
|
||||
describe('#registerOnRequest()', () => {
|
||||
const dummyOnRequestPlugin = path.resolve(
|
||||
__dirname,
|
||||
'./__fixtures__/plugins/dummy_on_request'
|
||||
);
|
||||
const plugin = path.resolve(__dirname, './__fixtures__/plugins/dummy_on_request');
|
||||
let root: ReturnType<typeof kbnTestServer.createRoot>;
|
||||
beforeAll(async () => {
|
||||
beforeEach(async () => {
|
||||
root = kbnTestServer.createRoot(
|
||||
{
|
||||
plugins: { paths: [dummyOnRequestPlugin] },
|
||||
plugins: { paths: [plugin] },
|
||||
},
|
||||
{
|
||||
dev: true,
|
||||
|
@ -136,7 +135,7 @@ describe('http service', () => {
|
|||
await root.start();
|
||||
}, 30000);
|
||||
|
||||
afterAll(async () => await root.shutdown());
|
||||
afterEach(async () => await root.shutdown());
|
||||
it('Should support passing request through to the route handler', async () => {
|
||||
await kbnTestServer.request.get(root, onReqUrl.root).expect(200, { content: 'ok' });
|
||||
});
|
||||
|
@ -160,5 +159,79 @@ describe('http service', () => {
|
|||
await kbnTestServer.request.get(root, onReqUrl.independentReq).expect(200);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#registerOnRequest() toolkit', () => {
|
||||
let root: ReturnType<typeof kbnTestServer.createRoot>;
|
||||
beforeEach(async () => {
|
||||
root = kbnTestServer.createRoot();
|
||||
}, 30000);
|
||||
|
||||
afterEach(async () => await root.shutdown());
|
||||
it('supports Url change on the flight', async () => {
|
||||
const { http } = await root.setup();
|
||||
http.registerOnRequest((req, t) => {
|
||||
t.setUrl(parse('/new-url'));
|
||||
return t.next();
|
||||
});
|
||||
|
||||
const router = new Router('/');
|
||||
router.get({ path: '/new-url', validate: false }, async (req, res) =>
|
||||
res.ok({ key: 'new-url-reached' })
|
||||
);
|
||||
http.registerRouter(router);
|
||||
|
||||
await root.start();
|
||||
|
||||
await kbnTestServer.request.get(root, '/').expect(200, { key: 'new-url-reached' });
|
||||
});
|
||||
|
||||
it('url re-write works for legacy server as well', async () => {
|
||||
const { http } = await root.setup();
|
||||
const newUrl = '/new-url';
|
||||
http.registerOnRequest((req, t) => {
|
||||
t.setUrl(newUrl);
|
||||
return t.next();
|
||||
});
|
||||
|
||||
await root.start();
|
||||
const kbnServer = kbnTestServer.getKbnServer(root);
|
||||
kbnServer.server.route({
|
||||
method: 'GET',
|
||||
path: newUrl,
|
||||
handler: () => 'ok-from-legacy',
|
||||
});
|
||||
|
||||
await kbnTestServer.request.get(root, '/').expect(200, 'ok-from-legacy');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getBasePathFor()/#setBasePathFor()', () => {
|
||||
let root: ReturnType<typeof kbnTestServer.createRoot>;
|
||||
beforeEach(async () => {
|
||||
root = kbnTestServer.createRoot();
|
||||
}, 30000);
|
||||
|
||||
afterEach(async () => await root.shutdown());
|
||||
it('basePath information for an incoming request is available in legacy server', async () => {
|
||||
const reqBasePath = '/requests-specific-base-path';
|
||||
const { http } = await root.setup();
|
||||
http.registerOnRequest((req, t) => {
|
||||
http.setBasePathFor(req, reqBasePath);
|
||||
return t.next();
|
||||
});
|
||||
|
||||
await root.start();
|
||||
|
||||
const legacyUrl = '/legacy';
|
||||
const kbnServer = kbnTestServer.getKbnServer(root);
|
||||
kbnServer.server.route({
|
||||
method: 'GET',
|
||||
path: legacyUrl,
|
||||
handler: kbnServer.newPlatform.setup.core.http.getBasePathFor,
|
||||
});
|
||||
|
||||
await kbnTestServer.request.get(root, legacyUrl).expect(200, reqBasePath);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { Url } from 'url';
|
||||
import Boom from 'boom';
|
||||
import { Lifecycle, Request, ResponseToolkit } from 'hapi';
|
||||
import { KibanaRequest } from '../router';
|
||||
|
@ -64,14 +65,10 @@ export interface OnRequestToolkit {
|
|||
redirected: (url: string) => OnRequestResult;
|
||||
/** Fail the request with specified error. */
|
||||
rejected: (error: Error, options?: { statusCode?: number }) => OnRequestResult;
|
||||
/** Change url for an incoming request. */
|
||||
setUrl: (newUrl: string | Url) => void;
|
||||
}
|
||||
|
||||
const toolkit: OnRequestToolkit = {
|
||||
next: OnRequestResult.next,
|
||||
redirected: OnRequestResult.redirected,
|
||||
rejected: OnRequestResult.rejected,
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export type OnRequestHandler<Params = any, Query = any, Body = any> = (
|
||||
req: KibanaRequest<Params, Query, Body>,
|
||||
|
@ -86,11 +83,20 @@ export type OnRequestHandler<Params = any, Query = any, Body = any> = (
|
|||
*/
|
||||
export function adoptToHapiOnRequestFormat(fn: OnRequestHandler) {
|
||||
return async function interceptRequest(
|
||||
req: Request,
|
||||
request: Request,
|
||||
h: ResponseToolkit
|
||||
): Promise<Lifecycle.ReturnValue> {
|
||||
try {
|
||||
const result = await fn(KibanaRequest.from(req, undefined), toolkit);
|
||||
const result = await fn(KibanaRequest.from(request, undefined), {
|
||||
next: OnRequestResult.next,
|
||||
redirected: OnRequestResult.redirected,
|
||||
rejected: OnRequestResult.rejected,
|
||||
setUrl: (newUrl: string | Url) => {
|
||||
request.setUrl(newUrl);
|
||||
// We should update raw request as well since it can be proxied to the old platform
|
||||
request.raw.req.url = typeof newUrl === 'string' ? newUrl : newUrl.href;
|
||||
},
|
||||
});
|
||||
if (OnRequestResult.isValidResult(result)) {
|
||||
if (result.isNext()) {
|
||||
return h.continue;
|
||||
|
|
|
@ -24,7 +24,7 @@ import { filterHeaders, Headers } from './headers';
|
|||
import { RouteSchemas } from './route';
|
||||
|
||||
/** @public */
|
||||
export class KibanaRequest<Params, Query, Body> {
|
||||
export class KibanaRequest<Params = unknown, Query = unknown, Body = unknown> {
|
||||
/**
|
||||
* Factory for creating requests. Validates the request before creating an
|
||||
* instance of a KibanaRequest.
|
||||
|
@ -71,12 +71,22 @@ export class KibanaRequest<Params, Query, Body> {
|
|||
public readonly headers: Headers;
|
||||
public readonly path: string;
|
||||
|
||||
constructor(req: Request, readonly params: Params, readonly query: Query, readonly body: Body) {
|
||||
this.headers = req.headers;
|
||||
this.path = req.path;
|
||||
constructor(
|
||||
private readonly request: Request,
|
||||
readonly params: Params,
|
||||
readonly query: Query,
|
||||
readonly body: Body
|
||||
) {
|
||||
this.headers = request.headers;
|
||||
this.path = request.path;
|
||||
}
|
||||
|
||||
public getFilteredHeaders(headersToKeep: string[]) {
|
||||
return filterHeaders(this.headers, headersToKeep);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||
public unstable_getIncomingMessage() {
|
||||
return this.request.raw.req;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -171,4 +171,4 @@ export class Router {
|
|||
export type RequestHandler<P extends ObjectType, Q extends ObjectType, B extends ObjectType> = (
|
||||
req: KibanaRequest<TypeOf<P>, TypeOf<Q>, TypeOf<B>>,
|
||||
createResponse: ResponseFactory
|
||||
) => Promise<KibanaResponse<any>>;
|
||||
) => KibanaResponse<any> | Promise<KibanaResponse<any>>;
|
||||
|
|
|
@ -58,6 +58,8 @@ export interface PluginSetupContext {
|
|||
http: {
|
||||
registerAuth: HttpServiceSetup['registerAuth'];
|
||||
registerOnRequest: HttpServiceSetup['registerOnRequest'];
|
||||
getBasePathFor: HttpServiceSetup['getBasePathFor'];
|
||||
setBasePathFor: HttpServiceSetup['setBasePathFor'];
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -148,6 +150,8 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>(
|
|||
http: {
|
||||
registerAuth: deps.http.registerAuth,
|
||||
registerOnRequest: deps.http.registerOnRequest,
|
||||
getBasePathFor: deps.http.getBasePathFor,
|
||||
setBasePathFor: deps.http.setBasePathFor,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import { Server } from 'hapi';
|
|||
import { ServerOptions } from 'hapi';
|
||||
import { Type } from '@kbn/config-schema';
|
||||
import { TypeOf } from '@kbn/config-schema';
|
||||
import { Url } from 'url';
|
||||
|
||||
// @public (undocumented)
|
||||
export type APICaller = (endpoint: string, clientParams: Record<string, unknown>, options?: CallAPIOptions) => Promise<unknown>;
|
||||
|
@ -143,8 +144,8 @@ export interface HttpServiceStart {
|
|||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export class KibanaRequest<Params, Query, Body> {
|
||||
constructor(req: Request, params: Params, query: Query, body: Body);
|
||||
export class KibanaRequest<Params = unknown, Query = unknown, Body = unknown> {
|
||||
constructor(request: Request, params: Params, query: Query, body: Body);
|
||||
// (undocumented)
|
||||
readonly body: Body;
|
||||
// Warning: (ae-forgotten-export) The symbol "RouteSchemas" needs to be exported by the entry point index.d.ts
|
||||
|
@ -159,6 +160,8 @@ export class KibanaRequest<Params, Query, Body> {
|
|||
readonly path: string;
|
||||
// (undocumented)
|
||||
readonly query: Query;
|
||||
// (undocumented)
|
||||
unstable_getIncomingMessage(): import("http").IncomingMessage;
|
||||
}
|
||||
|
||||
// @public
|
||||
|
@ -242,6 +245,7 @@ export interface OnRequestToolkit {
|
|||
rejected: (error: Error, options?: {
|
||||
statusCode?: number;
|
||||
}) => OnRequestResult;
|
||||
setUrl: (newUrl: string | Url) => void;
|
||||
}
|
||||
|
||||
// @public
|
||||
|
@ -286,6 +290,8 @@ export interface PluginSetupContext {
|
|||
http: {
|
||||
registerAuth: HttpServiceSetup['registerAuth'];
|
||||
registerOnRequest: HttpServiceSetup['registerOnRequest'];
|
||||
getBasePathFor: HttpServiceSetup['getBasePathFor'];
|
||||
setBasePathFor: HttpServiceSetup['setBasePathFor'];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ export default async function (kbnServer, server, config) {
|
|||
kbnServer.server = new Hapi.Server(kbnServer.newPlatform.params.serverOptions);
|
||||
server = kbnServer.server;
|
||||
|
||||
setupBasePathProvider(server, config);
|
||||
setupBasePathProvider(kbnServer);
|
||||
|
||||
await registerHapiPlugins(server);
|
||||
|
||||
|
|
|
@ -17,22 +17,14 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export function setupBasePathProvider(server, config) {
|
||||
|
||||
server.decorate('request', 'setBasePath', function (basePath) {
|
||||
export function setupBasePathProvider(kbnServer) {
|
||||
kbnServer.server.decorate('request', 'setBasePath', function (basePath) {
|
||||
const request = this;
|
||||
if (request.app._basePath) {
|
||||
throw new Error(`Request basePath was previously set. Setting multiple times is not supported.`);
|
||||
}
|
||||
request.app._basePath = basePath;
|
||||
kbnServer.newPlatform.setup.core.http.setBasePathFor(request, basePath);
|
||||
});
|
||||
|
||||
server.decorate('request', 'getBasePath', function () {
|
||||
kbnServer.server.decorate('request', 'getBasePath', function () {
|
||||
const request = this;
|
||||
|
||||
const serverBasePath = config.get('server.basePath');
|
||||
const requestBasePath = request.app._basePath || '';
|
||||
|
||||
return `${serverBasePath}${requestBasePath}`;
|
||||
return kbnServer.newPlatform.setup.core.http.getBasePathFor(request);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue