Refactor types and util functions
Summary: Separating out the types and utils for work I'm doing on https://github.com/facebook/flipper/pull/415 / D14973754. This will make the request to curl utility function much cleaner Reviewed By: jknoxville Differential Revision: D14976747 fbshipit-source-id: cc15c10103ea75945d0a2ebaaa6d32a376192961
This commit is contained in:
committed by
Facebook Github Bot
parent
20bd937d43
commit
01e4d694b5
@@ -5,9 +5,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// $FlowFixMe
|
import type {Request, Response, Header} from './types.js';
|
||||||
import pako from 'pako';
|
|
||||||
import type {Request, Response, Header} from './index.js';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
@@ -20,7 +18,7 @@ import {
|
|||||||
styled,
|
styled,
|
||||||
colors,
|
colors,
|
||||||
} from 'flipper';
|
} from 'flipper';
|
||||||
import {getHeaderValue} from './index.js';
|
import {decodeBody, getHeaderValue} from './utils.js';
|
||||||
|
|
||||||
import querystring from 'querystring';
|
import querystring from 'querystring';
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
@@ -58,48 +56,6 @@ type RequestDetailsState = {
|
|||||||
bodyFormat: string,
|
bodyFormat: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
function decodeBody(container: Request | Response): string {
|
|
||||||
if (!container.data) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const b64Decoded = atob(container.data);
|
|
||||||
const body =
|
|
||||||
getHeaderValue(container.headers, 'Content-Encoding') === 'gzip'
|
|
||||||
? decompress(b64Decoded)
|
|
||||||
: 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.
|
|
||||||
try {
|
|
||||||
return decodeURIComponent(escape(body));
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('Discarding malformed body:', escape(body));
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function decompress(body: string): string {
|
|
||||||
const charArray = body.split('').map(x => x.charCodeAt(0));
|
|
||||||
|
|
||||||
const byteArray = new Uint8Array(charArray);
|
|
||||||
|
|
||||||
let data;
|
|
||||||
try {
|
|
||||||
if (body) {
|
|
||||||
data = pako.inflate(byteArray);
|
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return String.fromCharCode.apply(null, new Uint8Array(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class RequestDetails extends Component<
|
export default class RequestDetails extends Component<
|
||||||
RequestDetailsProps,
|
RequestDetailsProps,
|
||||||
RequestDetailsState,
|
RequestDetailsState,
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ import {
|
|||||||
SearchableTable,
|
SearchableTable,
|
||||||
FlipperPlugin,
|
FlipperPlugin,
|
||||||
} from 'flipper';
|
} from 'flipper';
|
||||||
|
import type {Request, RequestId, Response} from './types.js';
|
||||||
|
import {getHeaderValue} from './utils.js';
|
||||||
import RequestDetails from './RequestDetails.js';
|
import RequestDetails from './RequestDetails.js';
|
||||||
import {URL} from 'url';
|
import {URL} from 'url';
|
||||||
import type {Notification} from '../../plugin';
|
import type {Notification} from '../../plugin';
|
||||||
|
|
||||||
type RequestId = string;
|
|
||||||
|
|
||||||
type PersistedState = {|
|
type PersistedState = {|
|
||||||
requests: {[id: RequestId]: Request},
|
requests: {[id: RequestId]: Request},
|
||||||
responses: {[id: RequestId]: Response},
|
responses: {[id: RequestId]: Response},
|
||||||
@@ -36,29 +36,6 @@ type State = {|
|
|||||||
selectedIds: Array<RequestId>,
|
selectedIds: Array<RequestId>,
|
||||||
|};
|
|};
|
||||||
|
|
||||||
export type Request = {|
|
|
||||||
id: RequestId,
|
|
||||||
timestamp: number,
|
|
||||||
method: string,
|
|
||||||
url: string,
|
|
||||||
headers: Array<Header>,
|
|
||||||
data: ?string,
|
|
||||||
|};
|
|
||||||
|
|
||||||
export type Response = {|
|
|
||||||
id: RequestId,
|
|
||||||
timestamp: number,
|
|
||||||
status: number,
|
|
||||||
reason: string,
|
|
||||||
headers: Array<Header>,
|
|
||||||
data: ?string,
|
|
||||||
|};
|
|
||||||
|
|
||||||
export type Header = {|
|
|
||||||
key: string,
|
|
||||||
value: string,
|
|
||||||
|};
|
|
||||||
|
|
||||||
const COLUMN_SIZE = {
|
const COLUMN_SIZE = {
|
||||||
requestTimestamp: 100,
|
requestTimestamp: 100,
|
||||||
responseTimestamp: 100,
|
responseTimestamp: 100,
|
||||||
@@ -103,15 +80,6 @@ const COLUMNS = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
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 formatBytes(count: number): string {
|
export function formatBytes(count: number): string {
|
||||||
if (count > 1024 * 1024) {
|
if (count > 1024 * 1024) {
|
||||||
return (count / (1024.0 * 1024)).toFixed(1) + ' MB';
|
return (count / (1024.0 * 1024)).toFixed(1) + ' MB';
|
||||||
|
|||||||
31
src/plugins/network/types.js
Normal file
31
src/plugins/network/types.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2018-present Facebook.
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type RequestId = string;
|
||||||
|
|
||||||
|
export type Request = {|
|
||||||
|
id: RequestId,
|
||||||
|
timestamp: number,
|
||||||
|
method: string,
|
||||||
|
url: string,
|
||||||
|
headers: Array<Header>,
|
||||||
|
data: ?string,
|
||||||
|
|};
|
||||||
|
|
||||||
|
export type Response = {|
|
||||||
|
id: RequestId,
|
||||||
|
timestamp: number,
|
||||||
|
status: number,
|
||||||
|
reason: string,
|
||||||
|
headers: Array<Header>,
|
||||||
|
data: ?string,
|
||||||
|
|};
|
||||||
|
|
||||||
|
export type Header = {|
|
||||||
|
key: string,
|
||||||
|
value: string,
|
||||||
|
|};
|
||||||
61
src/plugins/network/utils.js
Normal file
61
src/plugins/network/utils.js
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2018-present Facebook.
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
|
import pako from 'pako';
|
||||||
|
import type {Request, Response, Header} from './types.js';
|
||||||
|
|
||||||
|
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);
|
||||||
|
const body =
|
||||||
|
getHeaderValue(container.headers, 'Content-Encoding') === 'gzip'
|
||||||
|
? decompress(b64Decoded)
|
||||||
|
: 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.
|
||||||
|
try {
|
||||||
|
return decodeURIComponent(escape(body));
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Discarding malformed body:', escape(body));
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function decompress(body: string): string {
|
||||||
|
const charArray = body.split('').map(x => x.charCodeAt(0));
|
||||||
|
|
||||||
|
const byteArray = new Uint8Array(charArray);
|
||||||
|
|
||||||
|
let data;
|
||||||
|
try {
|
||||||
|
if (body) {
|
||||||
|
data = pako.inflate(byteArray);
|
||||||
|
} 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.fromCharCode.apply(null, new Uint8Array(data));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user