From f20d5ed67f387eba870ca5810b43eb193dc4568e Mon Sep 17 00:00:00 2001 From: Siqi Liu Date: Wed, 27 Jul 2016 12:17:03 -0700 Subject: [PATCH] Intercept XMLHttpRequest network operations and gather their information in inspector tool Summary: This diff - creates `XHRInterceptor` to intercept all XMLHttpRequest network operations in React Native by monkey-patching. - enables `XHRInterceptor` in RN development tool "inspector". This interception and inspector tool work well on both Android and iOS. And this supports interception on any network API based on XMLHttpRequest, especially the Fetch API. By now, we can intercept 12 information fields of a XMLHttpRequest including method, url, data sent, status, response type, response size, requestHeaders, responseHeaders, response, responseURL, responseType and timeout. Follow-up: - Will add UIs in the inspector on top of this diff, to display all the network operation information. (Not in this diff just to make this shorter) - Will extend this to gather other valuable information towards one XMLHttpRequest. - Should support other network request APIs like WebSocket. Reviewed By: davidaurelio Differential Revision: D3598873 fbshipit-source-id: 3221050ab2ebd876a718fc326646c344d0944a5f --- Libraries/Inspector/Inspector.js | 14 +++ Libraries/Inspector/InspectorPanel.js | 11 ++ Libraries/Inspector/NetworkOverlay.js | 124 +++++++++++++++++++++ Libraries/Utilities/XHRInterceptor.js | 149 ++++++++++++++++++++++++++ 4 files changed, 298 insertions(+) create mode 100644 Libraries/Inspector/NetworkOverlay.js create mode 100644 Libraries/Utilities/XHRInterceptor.js diff --git a/Libraries/Inspector/Inspector.js b/Libraries/Inspector/Inspector.js index 0967f9dc3..f1121e1a6 100644 --- a/Libraries/Inspector/Inspector.js +++ b/Libraries/Inspector/Inspector.js @@ -44,6 +44,7 @@ class Inspector extends React.Component { perfing: bool, inspected: any, inspectedViewTag: any, + networking: bool, }; _subs: ?Array<() => void>; @@ -60,6 +61,7 @@ class Inspector extends React.Component { inspected: null, selection: null, inspectedViewTag: this.props.inspectedViewTag, + networking: false, }; } @@ -174,6 +176,7 @@ class Inspector extends React.Component { perfing: val, inspecting: false, inspected: null, + networking: false, }); } @@ -191,6 +194,15 @@ class Inspector extends React.Component { }); } + setNetworking(val: bool) { + this.setState({ + networking: val, + perfing: false, + inspecting: false, + inspected: null, + }); + } + render() { var panelContainerStyle = (this.state.panelPos === 'bottom') ? {bottom: 0} : {top: 0}; return ( @@ -214,6 +226,8 @@ class Inspector extends React.Component { setSelection={this.setSelection.bind(this)} touchTargetting={Touchable.TOUCH_TARGET_DEBUG} setTouchTargetting={this.setTouchTargetting.bind(this)} + networking={this.state.networking} + setNetworking={this.setNetworking.bind(this)} /> diff --git a/Libraries/Inspector/InspectorPanel.js b/Libraries/Inspector/InspectorPanel.js index 9078a8e46..9c00b1eba 100644 --- a/Libraries/Inspector/InspectorPanel.js +++ b/Libraries/Inspector/InspectorPanel.js @@ -19,6 +19,7 @@ var ElementProperties = require('ElementProperties'); var PerformanceOverlay = require('PerformanceOverlay'); var Touchable = require('Touchable'); var TouchableHighlight = require('TouchableHighlight'); +var NetworkOverlay = require('NetworkOverlay'); var PropTypes = React.PropTypes; @@ -51,6 +52,10 @@ class InspectorPanel extends React.Component { contents = ( ); + } else if (this.props.networking) { + contents = ( + + ); } else { contents = ( @@ -71,6 +76,10 @@ class InspectorPanel extends React.Component { pressed={this.props.perfing} onClick={this.props.setPerfing} /> +