[APM] Fix problems with tilde in transaction name (#33309) (#33364)

This commit is contained in:
Søren Louv-Jansen 2019-03-18 11:57:01 +01:00 committed by GitHub
parent bfdd11681f
commit 3ccc989cf3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 4 deletions

View file

@ -8,7 +8,13 @@ import { Location } from 'history';
import url from 'url';
// @ts-ignore
import { toJson } from '../testHelpers';
import { fromQuery, getKibanaHref, toQuery } from './url_helpers';
import {
fromQuery,
getKibanaHref,
legacyDecodeURIComponent,
legacyEncodeURIComponent,
toQuery
} from './url_helpers';
describe('toQuery', () => {
it('should parse string to object', () => {
@ -74,3 +80,64 @@ function getUrlQuery(href?: string) {
const hash = url.parse(href!).hash!.slice(1);
return url.parse(hash, true).query;
}
describe('legacyEncodeURIComponent', () => {
it('should encode a string with forward slashes', () => {
expect(legacyEncodeURIComponent('a/b/c')).toBe('a~2Fb~2Fc');
});
it('should encode a string with tilde', () => {
expect(legacyEncodeURIComponent('a~b~c')).toBe('a~7Eb~7Ec');
});
it('should encode a string with spaces', () => {
expect(legacyEncodeURIComponent('a b c')).toBe('a~20b~20c');
});
});
describe('legacyDecodeURIComponent', () => {
['a/b/c', 'a~b~c', 'GET /', 'foo ~ bar /'].map(input => {
it(`should encode and decode ${input}`, () => {
const converted = legacyDecodeURIComponent(
legacyEncodeURIComponent(input)
);
expect(converted).toBe(input);
});
});
describe('when Angular decodes forward slashes in a url', () => {
it('should decode value correctly', () => {
const transactionName = 'GET a/b/c/';
const encodedTransactionName = legacyEncodeURIComponent(transactionName);
const parsedUrl = emulateAngular(
`/transaction/${encodedTransactionName}`
);
const decodedTransactionName = legacyDecodeURIComponent(
parsedUrl.split('/')[2]
);
expect(decodedTransactionName).toBe(transactionName);
});
it('should decode value incorrectly when using vanilla encodeURIComponent', () => {
const transactionName = 'GET a/b/c/';
const encodedTransactionName = encodeURIComponent(transactionName);
const parsedUrl = emulateAngular(
`/transaction/${encodedTransactionName}`
);
const decodedTransactionName = decodeURIComponent(
parsedUrl.split('/')[2]
);
expect(decodedTransactionName).not.toBe(transactionName);
});
});
});
// Angular decodes forward slashes in path params
function emulateAngular(input: string) {
return input
.split('/')
.map(pathParam => pathParam.replace(/%2F/g, '/'))
.join('/');
}

View file

@ -124,10 +124,15 @@ export type QueryParams = APMQueryParams & RisonEncoded;
export type QueryParamsDecoded = APMQueryParams & RisonDecoded;
// This is downright horrible 😭 💔
// Angular decodes encoded url tokens like "%2F" to "/" which causes the route to change.
// It was supposedly fixed in https://github.com/angular/angular.js/commit/1b779028fdd339febaa1fff5f3bd4cfcda46cc09 but still seeing the issue
// Angular decodes encoded url tokens like "%2F" to "/" which causes problems when path params contains forward slashes
// This was originally fixed in Angular, but roled back to avoid breaking backwards compatability: https://github.com/angular/angular.js/commit/2bdf7126878c87474bb7588ce093d0a3c57b0026
export function legacyEncodeURIComponent(rawUrl?: string) {
return rawUrl && encodeURIComponent(rawUrl).replace(/%/g, '~');
return (
rawUrl &&
encodeURIComponent(rawUrl)
.replace(/~/g, '%7E')
.replace(/%/g, '~')
);
}
export function legacyDecodeURIComponent(encodedUrl?: string) {