Summary:
Quick notes:
- This looks worse than it is. It adds mandatory parentheses to single argument lambdas. Lots of outrage on Twitter about it, personally I'm {emoji:1f937_200d_2642} about it.
- Space before function, e.g. `a = function ()` is now enforced. I like this because both were fine before.
- I added `eslint-config-prettier` to the config because otherwise a ton of rules conflict with eslint itself.
Close https://github.com/facebook/flipper/pull/915
Reviewed By: jknoxville
Differential Revision: D20594929
fbshipit-source-id: ca1c65376b90e009550dd6d1f4e0831d32cbff03
104 lines
2.8 KiB
TypeScript
104 lines
2.8 KiB
TypeScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @format
|
|
*/
|
|
|
|
import pako from 'pako';
|
|
import {Request, Response, Header} from './types';
|
|
|
|
export function getHeaderValue(headers: Array<Header>, key: string): string {
|
|
for (const header of headers) {
|
|
if (header.key.toLowerCase() === key.toLowerCase()) {
|
|
return header.value;
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
export function decodeBody(container: Request | Response): string {
|
|
if (!container.data) {
|
|
return '';
|
|
}
|
|
|
|
const b64Decoded = atob(container.data);
|
|
try {
|
|
if (getHeaderValue(container.headers, 'Content-Encoding') === 'gzip') {
|
|
// for gzip, use pako to decompress directly to unicode string
|
|
return decompress(b64Decoded);
|
|
}
|
|
|
|
// Data is transferred as base64 encoded bytes to support unicode characters,
|
|
// we need to decode the bytes here to display the correct unicode characters.
|
|
return decodeURIComponent(escape(b64Decoded));
|
|
} catch (e) {
|
|
console.warn('Discarding malformed body, size: ' + b64Decoded.length);
|
|
return '';
|
|
}
|
|
}
|
|
|
|
function decompress(body: string): string {
|
|
const charArray = body.split('').map((x) => x.charCodeAt(0));
|
|
|
|
const byteArray = new Uint8Array(charArray);
|
|
|
|
try {
|
|
if (body) {
|
|
return pako.inflate(byteArray, {to: 'string'});
|
|
} else {
|
|
return body;
|
|
}
|
|
} catch (e) {
|
|
// Sometimes Content-Encoding is 'gzip' but the body is already decompressed.
|
|
// Assume this is the case when decompression fails.
|
|
}
|
|
|
|
return body;
|
|
}
|
|
|
|
export function convertRequestToCurlCommand(request: Request): string {
|
|
let command: string = `curl -v -X ${request.method}`;
|
|
command += ` ${escapedString(request.url)}`;
|
|
// Add headers
|
|
request.headers.forEach((header: Header) => {
|
|
const headerStr = `${header.key}: ${header.value}`;
|
|
command += ` -H ${escapedString(headerStr)}`;
|
|
});
|
|
// Add body
|
|
const body = decodeBody(request);
|
|
if (body) {
|
|
command += ` -d ${escapedString(body)}`;
|
|
}
|
|
return command;
|
|
}
|
|
|
|
function escapeCharacter(x: string) {
|
|
const code = x.charCodeAt(0);
|
|
return code < 16 ? '\\u0' + code.toString(16) : '\\u' + code.toString(16);
|
|
}
|
|
|
|
const needsEscapingRegex = /[\u0000-\u001f\u007f-\u009f!]/g;
|
|
|
|
// Escape util function, inspired by Google DevTools. Works only for POSIX
|
|
// based systems.
|
|
function escapedString(str: string) {
|
|
if (needsEscapingRegex.test(str) || str.includes("'")) {
|
|
return (
|
|
"$'" +
|
|
str
|
|
.replace(/\\/g, '\\\\')
|
|
.replace(/\'/g, "\\'")
|
|
.replace(/\n/g, '\\n')
|
|
.replace(/\r/g, '\\r')
|
|
.replace(needsEscapingRegex, escapeCharacter) +
|
|
"'"
|
|
);
|
|
}
|
|
|
|
// Simply use singly quoted string.
|
|
return "'" + str + "'";
|
|
}
|