[Console] Handle encoded characters in API requests (#132191) (#133601)

* Handle encoded characters in API requests

Co-authored-by: Muhammad Ibragimov <muhammad.ibragimov@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
(cherry picked from commit 52dca01b23)

Co-authored-by: Muhammad Ibragimov <53621505+mibragimov@users.noreply.github.com>
This commit is contained in:
Kibana Machine 2022-06-06 05:40:24 -05:00 committed by GitHub
parent cb9e081618
commit 8a29d64a5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 8 deletions

View file

@ -149,5 +149,21 @@ describe(`Console's send request`, () => {
const [httpRequestOptions] = stub.firstCall.args;
expect((httpRequestOptions as any).path).toEqual('/%3Cmy-index-%7Bnow%2Fd%7D%3E');
});
it('should not encode path if it does not require encoding', async () => {
const result = await proxyRequest({
agent: null as any,
headers: {},
method: 'get',
payload: null as any,
timeout: 30000,
uri: new URL(`http://noone.nowhere.none/my-index/_doc/this%2Fis%2Fa%2Fdoc`),
originalPath: 'my-index/_doc/this%2Fis%2Fa%2Fdoc',
});
expect(result).toEqual('done');
const [httpRequestOptions] = stub.firstCall.args;
expect((httpRequestOptions as any).path).toEqual('/my-index/_doc/this%2Fis%2Fa%2Fdoc');
});
});
});

View file

@ -22,6 +22,7 @@ interface Args {
timeout: number;
headers: http.OutgoingHttpHeaders;
rejectUnauthorized?: boolean;
originalPath?: string;
}
/**
@ -39,11 +40,6 @@ const sanitizeHostname = (hostName: string): string =>
const encodePathname = (pathname: string) => {
const decodedPath = new URLSearchParams(`path=${pathname}`).get('path') ?? '';
// Skip if it is valid
if (pathname === decodedPath) {
return pathname;
}
return `/${encodeURIComponent(trimStart(decodedPath, '/'))}`;
};
@ -58,11 +54,17 @@ export const proxyRequest = ({
timeout,
payload,
rejectUnauthorized,
originalPath,
}: Args) => {
const { hostname, port, protocol, pathname, search } = uri;
const { hostname, port, protocol, search, pathname: percentEncodedPath } = uri;
const client = uri.protocol === 'https:' ? https : http;
const encodedPath = encodePathname(pathname);
let pathname = uri.pathname;
let resolved = false;
const requiresEncoding = trimStart(originalPath, '/') !== trimStart(percentEncodedPath, '/');
if (requiresEncoding) {
pathname = encodePathname(pathname);
}
let resolve: (res: http.IncomingMessage) => void;
let reject: (res: unknown) => void;
@ -84,7 +86,7 @@ export const proxyRequest = ({
host: sanitizeHostname(hostname),
port: port === '' ? undefined : parseInt(port, 10),
protocol,
path: `${encodedPath}${search || ''}`,
path: `${pathname}${search || ''}`,
headers: {
...finalUserHeaders,
'content-type': 'application/json',

View file

@ -175,6 +175,7 @@ export const createHandler =
payload: body,
rejectUnauthorized,
agent,
originalPath: path,
});
break;