mirror of
https://github.com/elastic/kibana.git
synced 2025-04-19 15:35:00 -04:00
[Synthtrace] Fix wrong url build in the Kibana client (#217678)
Relates to #217529 #216653 #216844 ## Summary The issue was introduced in the [PR here](https://github.com/elastic/kibana/pull/212120/files#diff-34f8e7299930135fd708d98018fc6f4141d6e7c25df7e5fdb90f3472ad0e2948R36): basically, the URL will look like: ` http:/user:pass@localhost:5620/api/fleet/epm/packages/apm?prerelease=false` because `Path.join` will strip the `/` which is needed in this case - this URL is also passed to `getFetchAgent`. This PR will fix this issue.
This commit is contained in:
parent
23cbaa6d55
commit
7f0a625d66
3 changed files with 91 additions and 5 deletions
|
@ -11,9 +11,9 @@
|
|||
|
||||
import fetch from 'node-fetch';
|
||||
import { RequestInit } from 'node-fetch';
|
||||
import Path from 'path';
|
||||
import { kibanaHeaders } from './client_headers';
|
||||
import { getFetchAgent } from '../../cli/utils/ssl';
|
||||
import { normalizeUrl } from '../utils/normalize_url';
|
||||
|
||||
type KibanaClientFetchOptions = RequestInit;
|
||||
|
||||
|
@ -33,18 +33,20 @@ export class KibanaClient {
|
|||
}
|
||||
|
||||
fetch<T>(pathname: string, options: KibanaClientFetchOptions): Promise<T> {
|
||||
const url = Path.join(this.target, pathname);
|
||||
return fetch(url, {
|
||||
const pathnameWithLeadingSlash = pathname.startsWith('/') ? pathname : `/${pathname}`;
|
||||
const url = new URL(`${this.target}${pathnameWithLeadingSlash}`);
|
||||
const normalizedUrl = normalizeUrl(url.toString());
|
||||
return fetch(normalizedUrl, {
|
||||
...options,
|
||||
headers: {
|
||||
...this.headers,
|
||||
...options.headers,
|
||||
},
|
||||
agent: getFetchAgent(url),
|
||||
agent: getFetchAgent(normalizedUrl),
|
||||
}).then(async (response) => {
|
||||
if (response.status >= 400) {
|
||||
throw new KibanaClientHttpError(
|
||||
`Response error for ${options.method?.toUpperCase() ?? 'GET'} ${url}`,
|
||||
`Response error for ${options.method?.toUpperCase() ?? 'GET'} ${normalizedUrl}`,
|
||||
response.status,
|
||||
await response.json().catch((error) => {
|
||||
return undefined;
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the "Elastic License
|
||||
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||
* Public License v 1"; you may not use this file except in compliance with, at
|
||||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
export function normalizeUrl(url: string): string {
|
||||
return url.replace(/([^:]\/)\/+/g, '$1');
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the "Elastic License
|
||||
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||
* Public License v 1"; you may not use this file except in compliance with, at
|
||||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { normalizeUrl } from './normalize_url';
|
||||
|
||||
describe('normalizeUrl', () => {
|
||||
it('should remove unnecessary double slashes from the URL', () => {
|
||||
const url = 'http://example.com//some//path///to/resource';
|
||||
const result = normalizeUrl(url);
|
||||
expect(result).toBe('http://example.com/some/path/to/resource');
|
||||
});
|
||||
|
||||
it('should preserve the protocol slashes', () => {
|
||||
const url = 'http:///example.com';
|
||||
const result = normalizeUrl(url);
|
||||
expect(result).toBe('http://example.com');
|
||||
});
|
||||
|
||||
it('should handle URLs with query parameters', () => {
|
||||
const url = 'http://example.com//some/path?key=value&key2=value2';
|
||||
const result = normalizeUrl(url);
|
||||
expect(result).toBe('http://example.com/some/path?key=value&key2=value2');
|
||||
});
|
||||
|
||||
it('should handle URLs with port', () => {
|
||||
const url = 'http://example:3000//some/path?key=value&key2=value2';
|
||||
const result = normalizeUrl(url);
|
||||
expect(result).toBe('http://example:3000/some/path?key=value&key2=value2');
|
||||
});
|
||||
|
||||
it('should handle URLs with localhost port and extra path', () => {
|
||||
const url = 'http://localhost:3000//some/path//more/path';
|
||||
const result = normalizeUrl(url);
|
||||
expect(result).toBe('http://localhost:3000/some/path/more/path');
|
||||
});
|
||||
|
||||
it('should handle URLs with trailing slashes', () => {
|
||||
const url = 'http://example.com/some/path///';
|
||||
const result = normalizeUrl(url);
|
||||
expect(result).toBe('http://example.com/some/path/');
|
||||
});
|
||||
|
||||
it('should handle URLs without double slashes', () => {
|
||||
const url = 'http://example.com/some/path';
|
||||
const result = normalizeUrl(url);
|
||||
expect(result).toBe('http://example.com/some/path');
|
||||
});
|
||||
|
||||
it('should handle URLs with no path', () => {
|
||||
const url = 'http://example.com';
|
||||
const result = normalizeUrl(url);
|
||||
expect(result).toBe('http://example.com');
|
||||
});
|
||||
|
||||
it('should handle empty strings', () => {
|
||||
const url = '';
|
||||
const result = normalizeUrl(url);
|
||||
expect(result).toBe('');
|
||||
});
|
||||
|
||||
it('should handle URLs with differnt protocol', () => {
|
||||
const url = 'ftp://example.com//some/path';
|
||||
const result = normalizeUrl(url);
|
||||
expect(result).toBe('ftp://example.com/some/path');
|
||||
});
|
||||
});
|
Loading…
Add table
Reference in a new issue