diff options
-rw-r--r-- | docs/install.rst | 24 | ||||
-rw-r--r-- | mitmproxy/platform/pf.py | 1 | ||||
-rw-r--r-- | mitmproxy/proxy/config.py | 2 | ||||
-rw-r--r-- | mitmproxy/web/static/app.js | 22 | ||||
-rw-r--r-- | netlib/http/http2/framereader.py | 3 | ||||
-rw-r--r-- | test/mitmproxy/test_protocol_http1.py | 8 | ||||
-rw-r--r-- | test/mitmproxy/test_protocol_http2.py | 41 | ||||
-rw-r--r-- | tox.ini | 2 | ||||
-rw-r--r-- | web/src/js/app.jsx | 12 | ||||
-rw-r--r-- | web/src/js/components/ProxyApp.jsx | 58 | ||||
-rw-r--r-- | web/src/js/connection.js | 49 | ||||
-rw-r--r-- | web/src/js/ducks/app.js | 27 | ||||
-rw-r--r-- | web/src/js/ducks/websocket.js | 118 |
13 files changed, 239 insertions, 128 deletions
diff --git a/docs/install.rst b/docs/install.rst index 566430f5..6d82f81f 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -11,8 +11,10 @@ Installation On Ubuntu Ubuntu comes with Python but we need to install pip, python-dev and several libraries. This was tested on a fully patched installation of Ubuntu 14.04. ->>> sudo apt-get install python-pip python-dev libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev zlib1g-dev ->>> sudo pip install mitmproxy +.. code:: bash + + sudo apt-get install python-pip python-dev libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev zlib1g-dev + sudo pip install mitmproxy # or pip install --user mitmproxy Once installation is complete you can run :ref:`mitmproxy` or :ref:`mitmdump` from a terminal. @@ -27,6 +29,20 @@ get set up to contribute to the project, install the dependencies as you would f mitmproxy installation (see :ref:`install-ubuntu`). Then see the Hacking_ section of the README on GitHub. +.. _install-fedora: + +Installation On Fedora +---------------------- + +Fedora comes with Python but we need to install pip, python-dev and several libraries. +This was tested on a fully patched installation of Fedora 23. + +.. code:: bash + + sudo dnf install -y python-pip python-devel libffi-devel openssl-devel libxml2-devel libxslt-devel libpng-devel libjpeg-devel + sudo pip install mitmproxy # or pip install --user mitmproxy + +Once installation is complete you can run :ref:`mitmproxy` or :ref:`mitmdump` from a terminal. .. _install-arch: @@ -87,7 +103,9 @@ Installation On Windows First, install the latest version of Python 2.7 from the `Python website`_. If you already have an older version of Python 2.7 installed, make sure to install pip_ -(pip is included in Python 2.7.9+ by default). +(pip is included in Python 2.7.9+ by default). If pip aborts with an error, make sure you are using the current version of pip. + +>>> python -m pip install --upgrade pip Next, add Python and the Python Scripts directory to your **PATH** variable. You can do this easily by running the following in powershell: diff --git a/mitmproxy/platform/pf.py b/mitmproxy/platform/pf.py index 97a4c192..c0397d78 100644 --- a/mitmproxy/platform/pf.py +++ b/mitmproxy/platform/pf.py @@ -8,6 +8,7 @@ def lookup(address, port, s): Returns an (address, port) tuple, or None. """ + s = s.decode() spec = "%s:%s" % (address, port) for i in s.split("\n"): if "ESTABLISHED:ESTABLISHED" in i and spec in i: diff --git a/mitmproxy/proxy/config.py b/mitmproxy/proxy/config.py index 9246fe04..32d881b0 100644 --- a/mitmproxy/proxy/config.py +++ b/mitmproxy/proxy/config.py @@ -199,7 +199,7 @@ def process_proxy_options(parser, options): password_manager = authentication.PassManHtpasswd( options.auth_htpasswd) except ValueError as v: - return parser.error(v.message) + return parser.error(v) authenticator = authentication.BasicProxyAuth(password_manager, "mitmproxy") else: authenticator = authentication.NullProxyAuth(None) diff --git a/mitmproxy/web/static/app.js b/mitmproxy/web/static/app.js index 3fe3ed03..7a8f3838 100644 --- a/mitmproxy/web/static/app.js +++ b/mitmproxy/web/static/app.js @@ -1,10 +1,10 @@ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.Query=exports.ConnectionActions=exports.StoreCmds=exports.ActionTypes=void 0;var _jquery=require("jquery"),_jquery2=_interopRequireDefault(_jquery),_dispatcher=require("./dispatcher.js"),_utils=require("./utils.js"),ActionTypes=exports.ActionTypes={CONNECTION_OPEN:"connection_open",CONNECTION_CLOSE:"connection_close",CONNECTION_ERROR:"connection_error",SETTINGS_STORE:"settings",EVENT_STORE:"events",FLOW_STORE:"flows"},StoreCmds=exports.StoreCmds={ADD:"add",UPDATE:"update",REMOVE:"remove",RESET:"reset"},ConnectionActions=exports.ConnectionActions={open:function(){_dispatcher.AppDispatcher.dispatchViewAction({type:ActionTypes.CONNECTION_OPEN})},close:function(){_dispatcher.AppDispatcher.dispatchViewAction({type:ActionTypes.CONNECTION_CLOSE})},error:function(){_dispatcher.AppDispatcher.dispatchViewAction({type:ActionTypes.CONNECTION_ERROR})}},Query=exports.Query={SEARCH:"s",HIGHLIGHT:"h",SHOW_EVENTLOG:"e"}; -},{"./dispatcher.js":41,"./utils.js":54,"jquery":"jquery"}],2:[function(require,module,exports){ -"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}var _react=require("react"),_react2=_interopRequireDefault(_react),_reactDom=require("react-dom"),_redux=require("redux"),_reactRedux=require("react-redux"),_reduxLogger=require("redux-logger"),_reduxLogger2=_interopRequireDefault(_reduxLogger),_reduxThunk=require("redux-thunk"),_reduxThunk2=_interopRequireDefault(_reduxThunk),_reactRouter=require("react-router"),_connection=require("./connection"),_connection2=_interopRequireDefault(_connection),_ProxyApp=require("./components/ProxyApp"),_ProxyApp2=_interopRequireDefault(_ProxyApp),_MainView=require("./components/MainView"),_MainView2=_interopRequireDefault(_MainView),_index=require("./ducks/index"),_index2=_interopRequireDefault(_index),_eventLog=require("./ducks/eventLog"),store=(0,_redux.createStore)(_index2["default"],(0,_redux.applyMiddleware)(_reduxThunk2["default"],(0,_reduxLogger2["default"])()));window.addEventListener("error",function(e){store.dispatch((0,_eventLog.add)(e))}),document.addEventListener("DOMContentLoaded",function(){window.ws=new _connection2["default"]("/updates",store.dispatch),(0,_reactDom.render)(_react2["default"].createElement(_reactRedux.Provider,{store:store},_react2["default"].createElement(_reactRouter.Router,{history:_reactRouter.hashHistory},_react2["default"].createElement(_reactRouter.Redirect,{from:"/",to:"/flows"}),_react2["default"].createElement(_reactRouter.Route,{path:"/",component:_ProxyApp2["default"]},_react2["default"].createElement(_reactRouter.Route,{path:"flows",component:_MainView2["default"]}),_react2["default"].createElement(_reactRouter.Route,{path:"flows/:flowId/:detailTab",component:_MainView2["default"]})))),document.getElementById("mitmproxy"))}); +},{"./dispatcher.js":40,"./utils.js":54,"jquery":"jquery"}],2:[function(require,module,exports){ +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}var _react=require("react"),_react2=_interopRequireDefault(_react),_reactDom=require("react-dom"),_redux=require("redux"),_reactRedux=require("react-redux"),_reduxLogger=require("redux-logger"),_reduxLogger2=_interopRequireDefault(_reduxLogger),_reduxThunk=require("redux-thunk"),_reduxThunk2=_interopRequireDefault(_reduxThunk),_reactRouter=require("react-router"),_ProxyApp=require("./components/ProxyApp"),_ProxyApp2=_interopRequireDefault(_ProxyApp),_MainView=require("./components/MainView"),_MainView2=_interopRequireDefault(_MainView),_index=require("./ducks/index"),_index2=_interopRequireDefault(_index),_eventLog=require("./ducks/eventLog"),store=(0,_redux.createStore)(_index2["default"],(0,_redux.applyMiddleware)(_reduxThunk2["default"],(0,_reduxLogger2["default"])()));window.addEventListener("error",function(e){store.dispatch((0,_eventLog.add)(e))}),document.addEventListener("DOMContentLoaded",function(){(0,_reactDom.render)(_react2["default"].createElement(_reactRedux.Provider,{store:store},_react2["default"].createElement(_reactRouter.Router,{history:_reactRouter.hashHistory},_react2["default"].createElement(_reactRouter.Redirect,{from:"/",to:"/flows"}),_react2["default"].createElement(_reactRouter.Route,{path:"/",component:_ProxyApp2["default"]},_react2["default"].createElement(_reactRouter.Route,{path:"flows",component:_MainView2["default"]}),_react2["default"].createElement(_reactRouter.Route,{path:"flows/:flowId/:detailTab",component:_MainView2["default"]})))),document.getElementById("mitmproxy"))}); -},{"./components/MainView":28,"./components/ProxyApp":30,"./connection":40,"./ducks/eventLog":42,"./ducks/index":44,"react":"react","react-dom":"react-dom","react-redux":"react-redux","react-router":"react-router","redux":"redux","redux-logger":"redux-logger","redux-thunk":"redux-thunk"}],3:[function(require,module,exports){ +},{"./components/MainView":28,"./components/ProxyApp":30,"./ducks/eventLog":42,"./ducks/index":44,"react":"react","react-dom":"react-dom","react-redux":"react-redux","react-router":"react-router","redux":"redux","redux-logger":"redux-logger","redux-thunk":"redux-thunk"}],3:[function(require,module,exports){ "use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t["default"]=e,t}function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},_createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_utils=require("../flow/utils.js"),_ContentViews=require("./ContentView/ContentViews"),_ContentErrors=require("./ContentView/ContentErrors"),ContentErrors=_interopRequireWildcard(_ContentErrors),_ContentLoader=require("./ContentView/ContentLoader"),_ContentLoader2=_interopRequireDefault(_ContentLoader),_ViewSelector=require("./ContentView/ViewSelector"),_ViewSelector2=_interopRequireDefault(_ViewSelector),ContentView=function(e){function t(e,r){_classCallCheck(this,t);var n=_possibleConstructorReturn(this,Object.getPrototypeOf(t).call(this,e,r));return n.state={displayLarge:!1,View:_ContentViews.ViewAuto},n.selectView=n.selectView.bind(n),n}return _inherits(t,e),_createClass(t,[{key:"selectView",value:function(e){this.setState({View:e})}},{key:"displayLarge",value:function(){this.setState({displayLarge:!0})}},{key:"componentWillReceiveProps",value:function(e){e.message!==this.props.message&&this.setState({displayLarge:!1,View:_ContentViews.ViewAuto})}},{key:"isContentTooLarge",value:function(e){return e.contentLength>1048576*(_ContentViews.ViewImage.matches(e)?10:.2)}},{key:"render",value:function(){var e=this.props,t=e.flow,r=e.message,n=this.state,o=n.displayLarge,a=n.View;return 0===r.contentLength?_react2["default"].createElement(ContentErrors.ContentEmpty,this.props):null===r.contentLength?_react2["default"].createElement(ContentErrors.ContentMissing,this.props):!o&&this.isContentTooLarge(r)?_react2["default"].createElement(ContentErrors.ContentTooLarge,_extends({},this.props,{onClick:this.displayLarge})):_react2["default"].createElement("div",null,a.textView?_react2["default"].createElement(_ContentLoader2["default"],{flow:t,message:r},_react2["default"].createElement(this.state.View,{content:""})):_react2["default"].createElement(a,{flow:t,message:r}),_react2["default"].createElement("div",{className:"view-options text-center"},_react2["default"].createElement(_ViewSelector2["default"],{onSelectView:this.selectView,active:a,message:r})," ",_react2["default"].createElement("a",{className:"btn btn-default btn-xs",href:_utils.MessageUtils.getContentURL(t,r)},_react2["default"].createElement("i",{className:"fa fa-download"}))))}}]),t}(_react.Component);ContentView.propTypes={flow:_react2["default"].PropTypes.object.isRequired,message:_react2["default"].PropTypes.object.isRequired},exports["default"]=ContentView; },{"../flow/utils.js":53,"./ContentView/ContentErrors":4,"./ContentView/ContentLoader":5,"./ContentView/ContentViews":6,"./ContentView/ViewSelector":7,"react":"react"}],4:[function(require,module,exports){ @@ -86,9 +86,9 @@ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function Prompt(e,t){function r(e){return _lodash2["default"].map(i,"key").includes(e)}function o(e){e.stopPropagation(),e.preventDefault();var r=i.find(function(t){return _utils.Key[t.key.toUpperCase()]===e.keyCode});(r||e.keyCode===_utils.Key.ESC||e.keyCode===_utils.Key.ENTER)&&(n(k||!1),t.returnFocus())}for(var a=e.prompt,n=e.done,u=e.options,i=[],s=0;s<u.length;s++){var l=u[s];if(_lodash2["default"].isString(l)){for(var p=l;p.length>0&&r(p[0]);)p=p.substr(1);l={text:l,key:p[0]}}if(!l.text||!l.key||r(l.key))throw"invalid options";i.push(l)}return _react2["default"].createElement("div",{tabIndex:"0",onKeyDown:o,onClick:onClick,className:"prompt-dialog"},_react2["default"].createElement("div",{className:"prompt-content"},a||_react2["default"].createElement("strong",null,"Select: "),i.map(function(e){function t(t){n(e.key),t.stopPropagation()}var r=e.text.indexOf(e.key);return _react2["default"].createElement("span",{key:e.key,className:"option",onClick:t},-1!==r?e.text.substring(0,r):e.text+"(",prefix,_react2["default"].createElement("strong",{className:"text-primary"},e.key),-1!==r?e.text.substring(r+1):")")})))}Object.defineProperty(exports,"__esModule",{value:!0}),exports["default"]=Prompt;var _react=require("react"),_react2=_interopRequireDefault(_react),_reactDom=require("react-dom"),_reactDom2=_interopRequireDefault(_reactDom),_lodash=require("lodash"),_lodash2=_interopRequireDefault(_lodash),_utils=require("../utils.js");Prompt.contextTypes={returnFocus:_react.PropTypes.func},Prompt.propTypes={options:_react.PropTypes.array.isRequired,done:_react.PropTypes.func.isRequired,prompt:_react.PropTypes.string}; },{"../utils.js":54,"lodash":"lodash","react":"react","react-dom":"react-dom"}],30:[function(require,module,exports){ -"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var o=t[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,r,o){return r&&e(t.prototype,r),o&&e(t,o),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_reactDom=require("react-dom"),_reactDom2=_interopRequireDefault(_reactDom),_lodash=require("lodash"),_lodash2=_interopRequireDefault(_lodash),_reactRedux=require("react-redux"),_Header=require("./Header"),_Header2=_interopRequireDefault(_Header),_EventLog=require("./EventLog"),_EventLog2=_interopRequireDefault(_EventLog),_Footer=require("./Footer"),_Footer2=_interopRequireDefault(_Footer),_utils=require("../utils.js"),ProxyAppMain=function(e){function t(e,r){_classCallCheck(this,t);var o=_possibleConstructorReturn(this,Object.getPrototypeOf(t).call(this,e,r));return o.focus=o.focus.bind(o),o.onKeyDown=o.onKeyDown.bind(o),o.updateLocation=o.updateLocation.bind(o),o}return _inherits(t,e),_createClass(t,[{key:"updateLocation",value:function(e,t){void 0===e&&(e=this.props.location.pathname);var r=this.props.location.query,o=!0,n=!1,a=void 0;try{for(var i,u=Object.keys(t||{})[Symbol.iterator]();!(o=(i=u.next()).done);o=!0){var c=i.value;r[c]=t[c]||void 0}}catch(l){n=!0,a=l}finally{try{!o&&u["return"]&&u["return"]()}finally{if(n)throw a}}this.context.router.replace({pathname:e,query:r})}},{key:"getQuery",value:function(){return _lodash2["default"].clone(this.props.location.query)}},{key:"componentDidMount",value:function(){this.focus()}},{key:"getChildContext",value:function(){return{returnFocus:this.focus}}},{key:"focus",value:function(){document.activeElement.blur(),window.getSelection().removeAllRanges(),_reactDom2["default"].findDOMNode(this).focus()}},{key:"onKeyDown",value:function(e){var t=this,r=null;switch(e.keyCode){case _utils.Key.I:r="intercept";break;case _utils.Key.L:r="search";break;case _utils.Key.H:r="highlight";break;default:var o=this.refs.view;return this.refs.view.getWrappedInstance&&(o=this.refs.view.getWrappedInstance()),void(o.onMainKeyDown&&o.onMainKeyDown(e))}r&&!function(){var e=t.refs.header;e.setState({active:_Header2["default"].entries[0]},function(){e.refs.active.refs[r].select()})}(),e.preventDefault()}},{key:"render",value:function(){var e=this.props,t=e.showEventLog,r=e.location,o=e.children,n=this.getQuery();return _react2["default"].createElement("div",{id:"container",tabIndex:"0",onKeyDown:this.onKeyDown},_react2["default"].createElement(_Header2["default"],{ref:"header",updateLocation:this.updateLocation,query:n}),_react2["default"].cloneElement(o,{ref:"view",location:r,query:n,updateLocation:this.updateLocation}),t&&_react2["default"].createElement(_EventLog2["default"],{key:"eventlog"}),_react2["default"].createElement(_Footer2["default"],null))}}]),t}(_react.Component);ProxyAppMain.childContextTypes={returnFocus:_react.PropTypes.func.isRequired},ProxyAppMain.contextTypes={router:_react.PropTypes.object.isRequired},exports["default"]=(0,_reactRedux.connect)(function(e){return{showEventLog:e.eventLog.visible}})(ProxyAppMain); +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_reactDom=require("react-dom"),_reactDom2=_interopRequireDefault(_reactDom),_lodash=require("lodash"),_lodash2=_interopRequireDefault(_lodash),_reactRedux=require("react-redux"),_app=require("../ducks/app"),_Header=require("./Header"),_Header2=_interopRequireDefault(_Header),_EventLog=require("./EventLog"),_EventLog2=_interopRequireDefault(_EventLog),_Footer=require("./Footer"),_Footer2=_interopRequireDefault(_Footer),_utils=require("../utils.js"),ProxyAppMain=function(e){function t(e,r){_classCallCheck(this,t);var n=_possibleConstructorReturn(this,Object.getPrototypeOf(t).call(this,e,r));return n.focus=n.focus.bind(n),n.onKeyDown=n.onKeyDown.bind(n),n.updateLocation=n.updateLocation.bind(n),n}return _inherits(t,e),_createClass(t,[{key:"componentWillMount",value:function(){this.props.appInit()}},{key:"componentDidMount",value:function(){this.focus()}},{key:"componentWillUnmount",value:function(){this.props.appDestruct()}},{key:"getChildContext",value:function(){return{returnFocus:this.focus}}},{key:"focus",value:function(){document.activeElement.blur(),window.getSelection().removeAllRanges(),_reactDom2["default"].findDOMNode(this).focus()}},{key:"onKeyDown",value:function(e){var t=this,r=null;switch(e.keyCode){case _utils.Key.I:r="intercept";break;case _utils.Key.L:r="search";break;case _utils.Key.H:r="highlight";break;default:var n=this.refs.view;return this.refs.view.getWrappedInstance&&(n=this.refs.view.getWrappedInstance()),void(n.onMainKeyDown&&n.onMainKeyDown(e))}r&&!function(){var e=t.refs.header;e.setState({active:_Header2["default"].entries[0]},function(){e.refs.active.refs[r].select()})}(),e.preventDefault()}},{key:"updateLocation",value:function(e,t){void 0===e&&(e=this.props.location.pathname);var r=this.props.location.query,n=!0,o=!1,a=void 0;try{for(var i,u=Object.keys(t||{})[Symbol.iterator]();!(n=(i=u.next()).done);n=!0){var c=i.value;r[c]=t[c]||void 0}}catch(s){o=!0,a=s}finally{try{!n&&u["return"]&&u["return"]()}finally{if(o)throw a}}this.context.router.replace({pathname:e,query:r})}},{key:"getQuery",value:function(){return _lodash2["default"].clone(this.props.location.query)}},{key:"render",value:function(){var e=this.props,t=e.showEventLog,r=e.location,n=e.children,o=this.getQuery();return _react2["default"].createElement("div",{id:"container",tabIndex:"0",onKeyDown:this.onKeyDown},_react2["default"].createElement(_Header2["default"],{ref:"header",updateLocation:this.updateLocation,query:o}),_react2["default"].cloneElement(n,{ref:"view",location:r,query:o,updateLocation:this.updateLocation}),t&&_react2["default"].createElement(_EventLog2["default"],{key:"eventlog"}),_react2["default"].createElement(_Footer2["default"],null))}}]),t}(_react.Component);ProxyAppMain.childContextTypes={returnFocus:_react.PropTypes.func.isRequired},ProxyAppMain.contextTypes={router:_react.PropTypes.object.isRequired},exports["default"]=(0,_reactRedux.connect)(function(e){return{showEventLog:e.eventLog.visible,settings:e.settings.settings}},{appInit:_app.init,appDestruct:_app.destruct})(ProxyAppMain); -},{"../utils.js":54,"./EventLog":8,"./Footer":19,"./Header":20,"lodash":"lodash","react":"react","react-dom":"react-dom","react-redux":"react-redux"}],31:[function(require,module,exports){ +},{"../ducks/app":41,"../utils.js":54,"./EventLog":8,"./Footer":19,"./Header":20,"lodash":"lodash","react":"react","react-dom":"react-dom","react-redux":"react-redux"}],31:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o])}return e},_createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var o=t[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,r,o){return r&&e(t.prototype,r),o&&e(t,o),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_reactDom=require("react-dom"),_reactDom2=_interopRequireDefault(_reactDom),_ValidateEditor=require("./ValueEditor/ValidateEditor"),_ValidateEditor2=_interopRequireDefault(_ValidateEditor),ValueEditor=function(e){function t(e){_classCallCheck(this,t);var r=_possibleConstructorReturn(this,Object.getPrototypeOf(t).call(this,e));return r.focus=r.focus.bind(r),r}return _inherits(t,e),_createClass(t,[{key:"render",value:function(){var e=this,t=this.props.inline?"span":"div";return _react2["default"].createElement(_ValidateEditor2["default"],_extends({},this.props,{onStop:function(){return e.context.returnFocus()},tag:t}))}},{key:"focus",value:function(){_reactDom2["default"].findDOMNode(this).focus()}}]),t}(_react.Component);ValueEditor.contextTypes={returnFocus:_react.PropTypes.func},ValueEditor.propTypes={content:_react.PropTypes.string.isRequired,onDone:_react.PropTypes.func.isRequired,inline:_react.PropTypes.bool},exports["default"]=ValueEditor; },{"./ValueEditor/ValidateEditor":33,"react":"react","react-dom":"react-dom"}],32:[function(require,module,exports){ @@ -116,12 +116,12 @@ "use strict";function calcVScroll(t){if(!t)return{start:0,end:0,paddingTop:0,paddingBottom:0};var e=t.itemCount,o=t.rowHeight,r=t.viewportTop,a=t.viewportHeight,i=t.itemHeights,l=r+a,n=0,c=0,d=0,p=0;if(i)for(var h=0,s=0;e>h;h++){var m=i[h]||o;r>=s&&h%2===0&&(d=s,n=h),l>=s?c=h+1:p+=m,s+=m}else n=-2&Math.max(0,Math.floor(r/o)-1),c=Math.min(e,n+Math.ceil(a/o)+2),d=Math.min(n,e)*o,p=Math.max(0,e-c)*o;return{start:n,end:c,paddingTop:d,paddingBottom:p}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.calcVScroll=calcVScroll; },{}],40:[function(require,module,exports){ -"use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var n={};if(null!=e)for(var t in e)Object.prototype.hasOwnProperty.call(e,t)&&(n[t]=e[t]);return n["default"]=e,n}function Connection(e,n){"/"===e[0]&&(e=location.origin.replace("http","ws")+e);var t=new WebSocket(e);return t.onopen=function(){n(webSocketActions.connected()),n(settingsActions.fetchSettings()),n(eventLogActions.fetchData()),n(flowActions.fetchData()).then(function(){console.log("flows are loaded now"),_actions.ConnectionActions.open()})},t.onmessage=function(e){var t=JSON.parse(e.data);switch(_dispatcher.AppDispatcher.dispatchServerAction(t),t.type){case eventLogActions.WS_MSG_TYPE:return n(eventLogActions.handleWsMsg(t));case flowActions.WS_MSG_TYPE:return n(flowActions.handleWsMsg(t));case settingsActions.UPDATE_SETTINGS:return n(settingsActions.handleWsMsg(t));default:console.warn("unknown message",t)}},t.onerror=function(){_actions.ConnectionActions.error(),n(eventLogActions.add("WebSocket connection error."))},t.onclose=function(){_actions.ConnectionActions.close(),n(eventLogActions.add("WebSocket connection closed.")),n(webSocketActions.disconnected())},t}Object.defineProperty(exports,"__esModule",{value:!0}),exports["default"]=Connection;var _actions=require("./actions.js"),_dispatcher=require("./dispatcher.js"),_websocket=require("./ducks/websocket"),webSocketActions=_interopRequireWildcard(_websocket),_eventLog=require("./ducks/eventLog"),eventLogActions=_interopRequireWildcard(_eventLog),_flows=require("./ducks/flows"),flowActions=_interopRequireWildcard(_flows),_settings=require("./ducks/settings"),settingsActions=_interopRequireWildcard(_settings); - -},{"./actions.js":1,"./dispatcher.js":41,"./ducks/eventLog":42,"./ducks/flows":43,"./ducks/settings":45,"./ducks/websocket":51}],41:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.AppDispatcher=void 0;var _flux=require("flux"),_flux2=_interopRequireDefault(_flux),PayloadSources={VIEW:"view",SERVER:"server"},AppDispatcher=exports.AppDispatcher=new _flux2["default"].Dispatcher;AppDispatcher.dispatchViewAction=function(e){e.source=PayloadSources.VIEW,this.dispatch(e)},AppDispatcher.dispatchServerAction=function(e){e.source=PayloadSources.SERVER,this.dispatch(e)}; -},{"flux":"flux"}],42:[function(require,module,exports){ +},{"flux":"flux"}],41:[function(require,module,exports){ +"use strict";function reduce(){var e=arguments.length<=0||void 0===arguments[0]?defaultState:arguments[0],t=arguments[1];switch(t.type){default:return e}}function init(){return function(e){e((0,_websocket.connect)()),e({type:INIT})}}function destruct(){return function(e){e((0,_websocket.disconnect)()),e({type:DESTRUCT})}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.INIT=void 0,exports.reduce=reduce,exports.init=init,exports.destruct=destruct;var _websocket=require("./websocket"),INIT=exports.INIT="APP_INIT",defaultState={}; + +},{"./websocket":51}],42:[function(require,module,exports){ "use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t["default"]=e,t}function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function reduce(){var e=arguments.length<=0||void 0===arguments[0]?defaultState:arguments[0],t=arguments[1];switch(t.type){case TOGGLE_VISIBILITY:return _extends({},e,{visible:!e.visible});case TOGGLE_FILTER:var r=_extends({},e.filters,_defineProperty({},t.filter,!e.filters[t.filter]));return _extends({},e,{filters:r,view:(0,viewActions["default"])(e.view,viewActions.updateFilter(e.list,function(e){return r[e.level]}))});case ADD:var i={id:"log-"+e.logId,message:t.message,level:t.level};return _extends({},e,{logId:e.logId+1,list:(0,listActions["default"])(e.list,listActions.add(i)),view:(0,viewActions["default"])(e.view,viewActions.add(i,function(t){return e.filters[t.level]}))});case REQUEST:return _extends({},e,{list:(0,listActions["default"])(e.list,listActions.request())});case RECEIVE:var s=(0,listActions["default"])(e.list,listActions.receive(t.list));return _extends({},e,{list:s,view:(0,viewActions["default"])(e.view,viewActions.receive(s,function(t){return e.filters[t.level]}))});default:return _extends({},e,{list:(0,listActions["default"])(e.list,t),view:(0,viewActions["default"])(e.view,t)})}}function toggleFilter(e){return{type:TOGGLE_FILTER,filter:e}}function toggleVisibility(){return{type:TOGGLE_VISIBILITY}}function add(e){var t=arguments.length<=1||void 0===arguments[1]?"web":arguments[1];return{type:ADD,message:e,level:t}}function handleWsMsg(e){switch(e.cmd){case websocketActions.CMD_ADD:return add(e.data.message,e.data.level);case websocketActions.CMD_RESET:return fetchData();default:return{type:UNKNOWN_CMD,msg:e}}}function fetchData(){return function(e){return e(request()),(0,_utils.fetchApi)("/events").then(function(e){return e.json()}).then(function(t){return e(receive(t.data))})["catch"](function(t){return e(fetchError(t))})}}function request(){return{type:REQUEST}}function receive(e){return{type:RECEIVE,list:e}}function fetchError(e){return{type:FETCH_ERROR,error:e}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.FETCH_ERROR=exports.UNKNOWN_CMD=exports.TOGGLE_FILTER=exports.TOGGLE_VISIBILITY=exports.RECEIVE=exports.REQUEST=exports.ADD=exports.WS_MSG_TYPE=void 0;var _extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var i in r)Object.prototype.hasOwnProperty.call(r,i)&&(e[i]=r[i])}return e};exports["default"]=reduce,exports.toggleFilter=toggleFilter,exports.toggleVisibility=toggleVisibility,exports.add=add,exports.handleWsMsg=handleWsMsg,exports.fetchData=fetchData,exports.request=request,exports.receive=receive,exports.fetchError=fetchError;var _utils=require("../utils"),_list=require("./utils/list"),listActions=_interopRequireWildcard(_list),_view=require("./utils/view"),viewActions=_interopRequireWildcard(_view),_websocket=require("./websocket"),websocketActions=_interopRequireWildcard(_websocket),WS_MSG_TYPE=exports.WS_MSG_TYPE="UPDATE_EVENTLOG",ADD=exports.ADD="EVENTLOG_ADD",REQUEST=exports.REQUEST="EVENTLOG_REQUEST",RECEIVE=exports.RECEIVE="EVENTLOG_RECEIVE",TOGGLE_VISIBILITY=exports.TOGGLE_VISIBILITY="EVENTLOG_TOGGLE_VISIBILITY",TOGGLE_FILTER=exports.TOGGLE_FILTER="EVENTLOG_TOGGLE_FILTER",UNKNOWN_CMD=exports.UNKNOWN_CMD="EVENTLOG_UNKNOWN_CMD",FETCH_ERROR=exports.FETCH_ERROR="EVENTLOG_FETCH_ERROR",defaultState={logId:0,visible:!1,filters:{debug:!1,info:!0,web:!0},list:void 0,view:void 0}; },{"../utils":54,"./utils/list":47,"./utils/view":48,"./websocket":51}],43:[function(require,module,exports){ @@ -149,9 +149,9 @@ "use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t["default"]=e,t}function reduce(){var e=arguments.length<=0||void 0===arguments[0]?defaultState:arguments[0],t=arguments[1];switch(t.type){case UPDATE_HIGHLIGHT:return _extends({},e,{highlight:t.highlight});case SELECT:return _extends({},e,{selected:[t.id]});case UPDATE_FILTER:return _extends({},e,{filter:t.filter,view:(0,viewActions["default"])(e.view,viewActions.updateFilter(t.list,makeFilter(t.filter),makeSorter(e.sorter)))});case UPDATE_SORTER:var r={column:t.column,desc:t.desc};return _extends({},e,{sorter:r,view:(0,viewActions["default"])(e.view,viewActions.updateSorter(makeSorter(r)))});case viewsActions.ADD:return _extends({},e,{view:(0,viewActions["default"])(e.view,viewActions.add(t.item,makeFilter(e.filter),makeSorter(e.sorter)))});case viewsActions.UPDATE:return _extends({},e,{view:(0,viewActions["default"])(e.view,viewActions.update(t.id,t.item,makeFilter(e.filter),makeSorter(e.sorter)))});case viewsActions.REMOVE:return _extends({},e,{view:(0,viewActions["default"])(e.view,viewActions.remove(t.id))});case viewsActions.RECEIVE:return _extends({},e,{view:(0,viewActions["default"])(e.view,viewActions.receive(t.list,makeFilter(e.filter),makeSorter(e.sorter)))});default:return _extends({},e,{view:(0,viewActions["default"])(e.view,t)})}}function updateFilter(e){return function(t,r){return{type:UPDATE_FILTER,filter:e,list:r().flows.list}}}function updateHighlight(e){return{type:UPDATE_HIGHLIGHT,highlight:e}}function updateSorter(e,t){return{type:UPDATE_SORTER,column:e,desc:t}}function select(e){return{type:SELECT,currentSelection:getState().flows.views.main.selected[0],id:e}}function makeFilter(e){return e?Filt.parse(e):void 0}function makeSorter(e){var t=e.column,r=e.desc,i=sortKeyFuns[t];return i?function(e,t){var n=i(e),s=i(t);return n>s?r?-1:1:s>n?r?1:-1:0}:void 0}Object.defineProperty(exports,"__esModule",{value:!0}),exports.SELECT=exports.UPDATE_HIGHLIGHT=exports.UPDATE_SORTER=exports.UPDATE_FILTER=void 0;var _extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var i in r)Object.prototype.hasOwnProperty.call(r,i)&&(e[i]=r[i])}return e};exports["default"]=reduce,exports.updateFilter=updateFilter,exports.updateHighlight=updateHighlight,exports.updateSorter=updateSorter,exports.select=select;var _utils=require("../../flow/utils"),_view=require("../utils/view"),viewActions=_interopRequireWildcard(_view),_views=require("../views"),viewsActions=_interopRequireWildcard(_views),UPDATE_FILTER=exports.UPDATE_FILTER="FLOW_VIEWS_MAIN_UPDATE_FILTER",UPDATE_SORTER=exports.UPDATE_SORTER="FLOW_VIEWS_MAIN_UPDATE_SORTER",UPDATE_HIGHLIGHT=exports.UPDATE_HIGHLIGHT="FLOW_VIEWS_MAIN_UPDATE_HIGHLIGHT",SELECT=exports.SELECT="FLOW_VIEWS_MAIN_SELECT",sortKeyFuns={TLSColumn:function(e){return e.request.scheme},PathColumn:function(e){return _utils.RequestUtils.pretty_url(e.request)},MethodColumn:function(e){return e.request.method},StatusColumn:function(e){return e.response&&e.response.status_code},TimeColumn:function(e){return e.response&&e.response.timestamp_end-e.request.timestamp_start},SizeColumn:function(e){var t=e.request.contentLength;return e.response&&(t+=e.response.contentLength||0),t}},defaultState={highlight:null,selected:[],filter:null,sorter:{column:null,desc:!1},view:void 0}; },{"../../flow/utils":53,"../utils/view":48,"../views":49}],51:[function(require,module,exports){ -"use strict";function reducer(){var e=arguments.length<=0||void 0===arguments[0]?defaultState:arguments[0],t=arguments[1];switch(t.type){case CONNECTED:return{connected:!0};case DISCONNECTED:return{connected:!1};default:return e}}function connected(){return{type:CONNECTED}}function disconnected(){return{type:DISCONNECTED}}Object.defineProperty(exports,"__esModule",{value:!0}),exports["default"]=reducer,exports.connected=connected,exports.disconnected=disconnected;var CONNECTED="WEBSOCKET_CONNECTED",DISCONNECTED="WEBSOCKET_DISCONNECTED",CMD_ADD=exports.CMD_ADD="add",CMD_UPDATE=exports.CMD_UPDATE="update",CMD_REMOVE=exports.CMD_REMOVE="remove",CMD_RESET=exports.CMD_RESET="reset",defaultState={connected:!1}; +"use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function reduce(){var e,t=arguments.length<=0||void 0===arguments[0]?defaultState:arguments[0],n=arguments[1];switch(n.type){case CONNECT:return _extends({},t,_defineProperty({},SYM_SOCKET,n.socket));case CONNECTED:return _extends({},t,{connected:!0});case DISCONNECT:return _extends({},t,{connected:!1});case DISCONNECTED:return _extends({},t,(e={},_defineProperty(e,SYM_SOCKET,null),_defineProperty(e,"connected",!1),e));default:return t}}function connect(){return function(e){var t=new WebSocket(location.origin.replace("http","ws")+"/updates");return window.ws=t,t.addEventListener("open",function(){return e(onConnect())}),t.addEventListener("close",function(){return e(onDisconnect())}),t.addEventListener("message",function(t){return e(onMessage(t))}),t.addEventListener("error",function(t){return e(onError(t))}),e({type:CONNECT,socket:t}),t}}function disconnect(){return function(e,t){t().settings[SYM_SOCKET].close(),e({type:DISCONNECT})}}function onConnect(){return function(e){e({type:CONNECTED}),e(settingsActions.fetchSettings()),e(flowsActions.fetchFlows()).then(function(){return _actions.ConnectionActions.open()})}}function onMessage(e){return function(t){var n=JSON.parse(e.data);switch(_dispatcher.AppDispatcher.dispatchServerAction(n),n.type){case eventLogActions.WS_MSG_TYPE:return t(eventLogActions.handleWsMsg(n));case flowsActions.WS_MSG_TYPE:return t(flowsActions.handleWsMsg(n));case settingsActions.UPDATE_SETTINGS:return t(settingsActions.handleWsMsg(n));default:console.warn("unknown message",n)}t({type:MESSAGE,msg:e})}}function onDisconnect(){return function(e){_actions.ConnectionActions.close(),e(eventLogActions.addLogEntry("WebSocket connection closed.")),e({type:DISCONNECTED})}}function onError(e){return function(t){_actions.ConnectionActions.error(),t(eventLogActions.addLogEntry("WebSocket connection error.")),t({type:ERROR,error:e})}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.MESSAGE=exports.ERROR=exports.DISCONNECTED=exports.DISCONNECT=exports.CONNECTED=exports.CONNECT=exports.SYM_SOCKET=exports.CMD_RESET=exports.CMD_REMOVE=exports.CMD_UPDATE=exports.CMD_ADD=void 0;var _extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e};exports["default"]=reduce,exports.connect=connect,exports.disconnect=disconnect,exports.onConnect=onConnect,exports.onMessage=onMessage,exports.onDisconnect=onDisconnect,exports.onError=onError;var _actions=require("../actions.js"),_dispatcher=require("../dispatcher.js"),_eventLog=require("./eventLog"),eventLogActions=_interopRequireWildcard(_eventLog),_flows=require("./flows"),flowsActions=_interopRequireWildcard(_flows),_settings=require("./settings"),settingsActions=_interopRequireWildcard(_settings),CMD_ADD=exports.CMD_ADD="add",CMD_UPDATE=exports.CMD_UPDATE="update",CMD_REMOVE=exports.CMD_REMOVE="remove",CMD_RESET=exports.CMD_RESET="reset",SYM_SOCKET=exports.SYM_SOCKET=Symbol("WEBSOCKET_SYM_SOCKET"),CONNECT=exports.CONNECT="WEBSOCKET_CONNECT",CONNECTED=exports.CONNECTED="WEBSOCKET_CONNECTED",DISCONNECT=exports.DISCONNECT="WEBSOCKET_DISCONNECT",DISCONNECTED=exports.DISCONNECTED="WEBSOCKET_DISCONNECTED",ERROR=exports.ERROR="WEBSOCKET_ERROR",MESSAGE=exports.MESSAGE="WEBSOCKET_MESSAGE",defaultState={connected:!1,socket:null}; -},{}],52:[function(require,module,exports){ +},{"../actions.js":1,"../dispatcher.js":40,"./eventLog":42,"./flows":43,"./settings":45}],52:[function(require,module,exports){ "use strict";module.exports=function(){function e(e,t){function r(){this.constructor=e}r.prototype=t.prototype,e.prototype=new r}function t(e,r,n,i){this.message=e,this.expected=r,this.found=n,this.location=i,this.name="SyntaxError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,t)}function r(e){function r(t){var r,n,i=Ot[t];if(i)return i;for(r=t-1;!Ot[r];)r--;for(i=Ot[r],i={line:i.line,column:i.column,seenCR:i.seenCR};t>r;)n=e.charAt(r),"\n"===n?(i.seenCR||i.line++,i.column=1,i.seenCR=!1):"\r"===n||"\u2028"===n||"\u2029"===n?(i.line++,i.column=1,i.seenCR=!0):(i.column++,i.seenCR=!1),r++;return Ot[t]=i,i}function n(e,t){var n=r(e),i=r(t);return{start:{offset:e,line:n.line,column:n.column},end:{offset:t,line:i.line,column:i.column}}}function i(e){Pt>Mt||(Mt>Pt&&(Pt=Mt,Qt=[]),Qt.push(e))}function s(e,r,n,i){function s(e){var t=1;for(e.sort(function(e,t){return e.description<t.description?-1:e.description>t.description?1:0});t<e.length;)e[t-1]===e[t]?e.splice(t,1):t++}function u(e,t){function r(e){function t(e){return e.charCodeAt(0).toString(16).toUpperCase()}return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\x08/g,"\\b").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\r/g,"\\r").replace(/[\x00-\x07\x0B\x0E\x0F]/g,function(e){return"\\x0"+t(e)}).replace(/[\x10-\x1F\x80-\xFF]/g,function(e){return"\\x"+t(e)}).replace(/[\u0100-\u0FFF]/g,function(e){return"\\u0"+t(e)}).replace(/[\u1000-\uFFFF]/g,function(e){return"\\u"+t(e)})}var n,i,s,u=new Array(e.length);for(s=0;s<e.length;s++)u[s]=e[s].description;return n=e.length>1?u.slice(0,-1).join(", ")+" or "+u[e.length-1]:u[0],i=t?'"'+r(t)+'"':"end of input","Expected "+n+" but "+i+" found."}return null!==r&&s(r),new t(null!==e?e:u(r,n),r,n,i)}function u(){var e,t,r,n;return Vt++,e=Mt,t=a(),t!==P?(r=l(),r!==P?(n=a(),n!==P?(Nt=e,t=X(r),e=t):(Mt=e,e=P)):(Mt=e,e=P)):(Mt=e,e=P),Vt--,e===P&&(t=P,0===Vt&&i(W)),e}function c(){var t,r;return Vt++,Z.test(e.charAt(Mt))?(t=e.charAt(Mt),Mt++):(t=P,0===Vt&&i($)),Vt--,t===P&&(r=P,0===Vt&&i(Y)),t}function o(){var t,r;return Vt++,te.test(e.charAt(Mt))?(t=e.charAt(Mt),Mt++):(t=P,0===Vt&&i(re)),Vt--,t===P&&(r=P,0===Vt&&i(ee)),t}function a(){var e,t;for(Vt++,e=[],t=c();t!==P;)e.push(t),t=c();return Vt--,e===P&&(t=P,0===Vt&&i(ne)),e}function l(){var t,r,n,s,u,c;return t=Mt,r=p(),r!==P?(n=a(),n!==P?(124===e.charCodeAt(Mt)?(s=ie,Mt++):(s=P,0===Vt&&i(se)),s!==P?(u=a(),u!==P?(c=l(),c!==P?(Nt=t,r=ue(r,c),t=r):(Mt=t,t=P)):(Mt=t,t=P)):(Mt=t,t=P)):(Mt=t,t=P)):(Mt=t,t=P),t===P&&(t=p()),t}function p(){var t,r,n,s,u,o;if(t=Mt,r=f(),r!==P?(n=a(),n!==P?(38===e.charCodeAt(Mt)?(s=ce,Mt++):(s=P,0===Vt&&i(oe)),s!==P?(u=a(),u!==P?(o=p(),o!==P?(Nt=t,r=ae(r,o),t=r):(Mt=t,t=P)):(Mt=t,t=P)):(Mt=t,t=P)):(Mt=t,t=P)):(Mt=t,t=P),t===P){if(t=Mt,r=f(),r!==P){if(n=[],s=c(),s!==P)for(;s!==P;)n.push(s),s=c();else n=P;n!==P?(s=p(),s!==P?(Nt=t,r=ae(r,s),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;t===P&&(t=f())}return t}function f(){var t,r,n,s;return t=Mt,33===e.charCodeAt(Mt)?(r=le,Mt++):(r=P,0===Vt&&i(pe)),r!==P?(n=a(),n!==P?(s=f(),s!==P?(Nt=t,r=fe(s),t=r):(Mt=t,t=P)):(Mt=t,t=P)):(Mt=t,t=P),t===P&&(t=h()),t}function h(){var t,r,n,s,u,c;return t=Mt,40===e.charCodeAt(Mt)?(r=he,Mt++):(r=P,0===Vt&&i(de)),r!==P?(n=a(),n!==P?(s=l(),s!==P?(u=a(),u!==P?(41===e.charCodeAt(Mt)?(c=ve,Mt++):(c=P,0===Vt&&i(ye)),c!==P?(Nt=t,r=ge(s),t=r):(Mt=t,t=P)):(Mt=t,t=P)):(Mt=t,t=P)):(Mt=t,t=P)):(Mt=t,t=P),t===P&&(t=d()),t}function d(){var e;return e=v(),e===P&&(e=g()),e}function v(){var t,r;return t=y(),t===P&&(t=Mt,e.substr(Mt,2)===Ae?(r=Ae,Mt+=2):(r=P,0===Vt&&i(xe)),r!==P&&(Nt=t,r=Re()),t=r,t===P&&(t=Mt,e.substr(Mt,2)===me?(r=me,Mt+=2):(r=P,0===Vt&&i(qe)),r!==P&&(Nt=t,r=Ce()),t=r,t===P&&(t=Mt,e.substr(Mt,2)===we?(r=we,Mt+=2):(r=P,0===Vt&&i(Ee)),r!==P&&(Nt=t,r=be()),t=r,t===P&&(t=Mt,e.substr(Mt,2)===Fe?(r=Fe,Mt+=2):(r=P,0===Vt&&i(Ue)),r!==P&&(Nt=t,r=je()),t=r)))),t}function y(){var t,r;return t=Mt,e.substr(Mt,4)===Te?(r=Te,Mt+=4):(r=P,0===Vt&&i(_e)),r!==P&&(Nt=t,r=Se()),t=r,t===P&&(t=Mt,e.substr(Mt,5)===ke?(r=ke,Mt+=5):(r=P,0===Vt&&i(Be)),r!==P&&(Nt=t,r=Ie()),t=r),t}function g(){var t,r,n,s;if(t=Mt,e.substr(Mt,2)===ze?(r=ze,Mt+=2):(r=P,0===Vt&&i(De)),r!==P){if(n=[],s=c(),s!==P)for(;s!==P;)n.push(s),s=c();else n=P;n!==P?(s=A(),s!==P?(Nt=t,r=Ge(s),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;if(t===P){if(t=Mt,e.substr(Mt,2)===He?(r=He,Mt+=2):(r=P,0===Vt&&i(Je)),r!==P){if(n=[],s=c(),s!==P)for(;s!==P;)n.push(s),s=c();else n=P;n!==P?(s=x(),s!==P?(Nt=t,r=Ke(s),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;if(t===P){if(t=Mt,e.substr(Mt,2)===Le?(r=Le,Mt+=2):(r=P,0===Vt&&i(Me)),r!==P){if(n=[],s=c(),s!==P)for(;s!==P;)n.push(s),s=c();else n=P;n!==P?(s=x(),s!==P?(Nt=t,r=Ne(s),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;if(t===P){if(t=Mt,e.substr(Mt,3)===Oe?(r=Oe,Mt+=3):(r=P,0===Vt&&i(Pe)),r!==P){if(n=[],s=c(),s!==P)for(;s!==P;)n.push(s),s=c();else n=P;n!==P?(s=x(),s!==P?(Nt=t,r=Qe(s),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;if(t===P){if(t=Mt,e.substr(Mt,3)===Ve?(r=Ve,Mt+=3):(r=P,0===Vt&&i(We)),r!==P){if(n=[],s=c(),s!==P)for(;s!==P;)n.push(s),s=c();else n=P;n!==P?(s=x(),s!==P?(Nt=t,r=Xe(s),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;if(t===P){if(t=Mt,e.substr(Mt,2)===Ye?(r=Ye,Mt+=2):(r=P,0===Vt&&i(Ze)),r!==P){if(n=[],s=c(),s!==P)for(;s!==P;)n.push(s),s=c();else n=P;n!==P?(s=x(),s!==P?(Nt=t,r=$e(s),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;if(t===P){if(t=Mt,e.substr(Mt,2)===et?(r=et,Mt+=2):(r=P,0===Vt&&i(tt)),r!==P){if(n=[],s=c(),s!==P)for(;s!==P;)n.push(s),s=c();else n=P;n!==P?(s=x(),s!==P?(Nt=t,r=rt(s),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;if(t===P){if(t=Mt,e.substr(Mt,3)===nt?(r=nt,Mt+=3):(r=P,0===Vt&&i(it)),r!==P){if(n=[],s=c(),s!==P)for(;s!==P;)n.push(s),s=c();else n=P;n!==P?(s=x(),s!==P?(Nt=t,r=st(s),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;if(t===P){if(t=Mt,e.substr(Mt,3)===ut?(r=ut,Mt+=3):(r=P,0===Vt&&i(ct)),r!==P){if(n=[],s=c(),s!==P)for(;s!==P;)n.push(s),s=c();else n=P;n!==P?(s=x(),s!==P?(Nt=t,r=ot(s),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;if(t===P){if(t=Mt,e.substr(Mt,2)===at?(r=at,Mt+=2):(r=P,0===Vt&&i(lt)),r!==P){if(n=[],s=c(),s!==P)for(;s!==P;)n.push(s),s=c();else n=P;n!==P?(s=x(),s!==P?(Nt=t,r=pt(s),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;t===P&&(t=Mt,r=x(),r!==P&&(Nt=t,r=pt(r)),t=r)}}}}}}}}}return t}function A(){var t,r,n,s;if(Vt++,t=Mt,ht.test(e.charAt(Mt))?(r=e.charAt(Mt),Mt++):(r=P,0===Vt&&i(dt)),r===P&&(r=null),r!==P){if(n=[],vt.test(e.charAt(Mt))?(s=e.charAt(Mt),Mt++):(s=P,0===Vt&&i(yt)),s!==P)for(;s!==P;)n.push(s),vt.test(e.charAt(Mt))?(s=e.charAt(Mt),Mt++):(s=P,0===Vt&&i(yt));else n=P;n!==P?(ht.test(e.charAt(Mt))?(s=e.charAt(Mt),Mt++):(s=P,0===Vt&&i(dt)),s===P&&(s=null),s!==P?(Nt=t,r=gt(n),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;return Vt--,t===P&&(r=P,0===Vt&&i(ft)),t}function x(){var t,r,n,s;if(Vt++,t=Mt,34===e.charCodeAt(Mt)?(r=xt,Mt++):(r=P,0===Vt&&i(Rt)),r!==P){for(n=[],s=R();s!==P;)n.push(s),s=R();n!==P?(34===e.charCodeAt(Mt)?(s=xt,Mt++):(s=P,0===Vt&&i(Rt)),s!==P?(Nt=t,r=mt(n),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;if(t===P){if(t=Mt,39===e.charCodeAt(Mt)?(r=qt,Mt++):(r=P,0===Vt&&i(Ct)),r!==P){for(n=[],s=m();s!==P;)n.push(s),s=m();n!==P?(39===e.charCodeAt(Mt)?(s=qt,Mt++):(s=P,0===Vt&&i(Ct)),s!==P?(Nt=t,r=mt(n),t=r):(Mt=t,t=P)):(Mt=t,t=P)}else Mt=t,t=P;if(t===P)if(t=Mt,r=Mt,Vt++,n=o(),Vt--,n===P?r=void 0:(Mt=r,r=P),r!==P){if(n=[],s=q(),s!==P)for(;s!==P;)n.push(s),s=q();else n=P;n!==P?(Nt=t,r=mt(n),t=r):(Mt=t,t=P)}else Mt=t,t=P}return Vt--,t===P&&(r=P,0===Vt&&i(At)),t}function R(){var t,r,n;return t=Mt,r=Mt,Vt++,wt.test(e.charAt(Mt))?(n=e.charAt(Mt),Mt++):(n=P,0===Vt&&i(Et)),Vt--,n===P?r=void 0:(Mt=r,r=P),r!==P?(e.length>Mt?(n=e.charAt(Mt),Mt++):(n=P,0===Vt&&i(bt)),n!==P?(Nt=t,r=Ft(n),t=r):(Mt=t,t=P)):(Mt=t,t=P),t===P&&(t=Mt,92===e.charCodeAt(Mt)?(r=Ut,Mt++):(r=P,0===Vt&&i(jt)),r!==P?(n=C(),n!==P?(Nt=t,r=Ft(n),t=r):(Mt=t,t=P)):(Mt=t,t=P)),t}function m(){var t,r,n;return t=Mt,r=Mt,Vt++,Tt.test(e.charAt(Mt))?(n=e.charAt(Mt),Mt++):(n=P,0===Vt&&i(_t)),Vt--,n===P?r=void 0:(Mt=r,r=P),r!==P?(e.length>Mt?(n=e.charAt(Mt),Mt++):(n=P,0===Vt&&i(bt)),n!==P?(Nt=t,r=Ft(n),t=r):(Mt=t,t=P)):(Mt=t,t=P),t===P&&(t=Mt,92===e.charCodeAt(Mt)?(r=Ut,Mt++):(r=P,0===Vt&&i(jt)),r!==P?(n=C(),n!==P?(Nt=t,r=Ft(n),t=r):(Mt=t,t=P)):(Mt=t,t=P)),t}function q(){var t,r,n;return t=Mt,r=Mt,Vt++,n=c(),Vt--,n===P?r=void 0:(Mt=r,r=P),r!==P?(e.length>Mt?(n=e.charAt(Mt),Mt++):(n=P,0===Vt&&i(bt)),n!==P?(Nt=t,r=Ft(n),t=r):(Mt=t,t=P)):(Mt=t,t=P),t}function C(){var t,r;return St.test(e.charAt(Mt))?(t=e.charAt(Mt),Mt++):(t=P,0===Vt&&i(kt)),t===P&&(t=Mt,110===e.charCodeAt(Mt)?(r=Bt,Mt++):(r=P,0===Vt&&i(It)),r!==P&&(Nt=t,r=zt()),t=r,t===P&&(t=Mt,114===e.charCodeAt(Mt)?(r=Dt,Mt++):(r=P,0===Vt&&i(Gt)),r!==P&&(Nt=t,r=Ht()),t=r,t===P&&(t=Mt,116===e.charCodeAt(Mt)?(r=Jt,Mt++):(r=P,0===Vt&&i(Kt)),r!==P&&(Nt=t,r=Lt()),t=r))),t}function w(e,t){function r(){return e.apply(this,arguments)||t.apply(this,arguments)}return r.desc=e.desc+" or "+t.desc,r}function E(e,t){function r(){return e.apply(this,arguments)&&t.apply(this,arguments)}return r.desc=e.desc+" and "+t.desc,r}function b(e){function t(){return!e.apply(this,arguments)}return t.desc="not "+e.desc,t}function F(e){function t(){return e.apply(this,arguments)}return t.desc="("+e.desc+")",t}function U(e){return!0}function j(e){return!1}function T(e){if(e.response)for(var t=Wt.ResponseUtils.getContentType(e.response),r=Xt.length;r--;)if(Xt[r].test(t))return!0;return!1}function _(e){function t(t){return t.response&&t.response.status_code===e}return t.desc="resp. code is "+e,t}function S(e){function t(t){return t.request&&e.test(t.request.host)}return e=new RegExp(e,"i"),t.desc="domain matches "+e,t}function k(e){return!!e.error}function B(e){function t(t){return t.request&&Wt.RequestUtils.match_header(t.request,e)||t.response&&Wt.ResponseUtils.match_header(t.response,e)}return e=new RegExp(e,"i"),t.desc="header matches "+e,t}function I(e){function t(t){return t.request&&Wt.RequestUtils.match_header(t.request,e)}return e=new RegExp(e,"i"),t.desc="req. header matches "+e,t}function z(e){function t(t){return t.response&&Wt.ResponseUtils.match_header(t.response,e)}return e=new RegExp(e,"i"),t.desc="resp. header matches "+e,t}function D(e){function t(t){return t.request&&e.test(t.request.method)}return e=new RegExp(e,"i"),t.desc="method matches "+e,t}function G(e){return e.request&&!e.response}function H(e){return!!e.response}function J(e){function t(t){return t.request&&e.test(Wt.RequestUtils.getContentType(t.request))||t.response&&e.test(Wt.ResponseUtils.getContentType(t.response))}return e=new RegExp(e,"i"),t.desc="content type matches "+e,t}function K(e){function t(t){return t.request&&e.test(Wt.RequestUtils.getContentType(t.request))}return e=new RegExp(e,"i"),t.desc="req. content type matches "+e,t}function L(e){function t(t){return t.response&&e.test(Wt.ResponseUtils.getContentType(t.response))}return e=new RegExp(e,"i"),t.desc="resp. content type matches "+e,t}function M(e){function t(t){return t.request&&e.test(Wt.RequestUtils.pretty_url(t.request))}return e=new RegExp(e,"i"),t.desc="url matches "+e,t}var N,O=arguments.length>1?arguments[1]:{},P={},Q={start:u},V=u,W={type:"other",description:"filter expression"},X=function(e){return e},Y={type:"other",description:"whitespace"},Z=/^[ \t\n\r]/,$={type:"class",value:"[ \\t\\n\\r]",description:"[ \\t\\n\\r]"},ee={type:"other",description:"control character"},te=/^[|&!()~"]/,re={type:"class",value:'[|&!()~"]',description:'[|&!()~"]'},ne={type:"other",description:"optional whitespace"},ie="|",se={type:"literal",value:"|",description:'"|"'},ue=function(e,t){return w(e,t)},ce="&",oe={type:"literal",value:"&",description:'"&"'},ae=function(e,t){return E(e,t)},le="!",pe={type:"literal",value:"!",description:'"!"'},fe=function(e){return b(e)},he="(",de={type:"literal",value:"(",description:'"("'},ve=")",ye={type:"literal",value:")",description:'")"'},ge=function(e){return F(e)},Ae="~a",xe={type:"literal",value:"~a",description:'"~a"'},Re=function(){return T},me="~e",qe={type:"literal",value:"~e",description:'"~e"'},Ce=function(){return k},we="~q",Ee={type:"literal",value:"~q",description:'"~q"'},be=function(){return G},Fe="~s",Ue={type:"literal",value:"~s",description:'"~s"'},je=function(){return H},Te="true",_e={type:"literal",value:"true",description:'"true"'},Se=function(){return U},ke="false",Be={type:"literal",value:"false",description:'"false"'},Ie=function(){return j},ze="~c",De={type:"literal",value:"~c",description:'"~c"'},Ge=function(e){return _(e)},He="~d",Je={type:"literal",value:"~d",description:'"~d"'},Ke=function(e){return S(e)},Le="~h",Me={type:"literal",value:"~h",description:'"~h"'},Ne=function(e){return B(e)},Oe="~hq",Pe={type:"literal",value:"~hq",description:'"~hq"'},Qe=function(e){return I(e)},Ve="~hs",We={type:"literal",value:"~hs",description:'"~hs"'},Xe=function(e){return z(e)},Ye="~m",Ze={type:"literal",value:"~m",description:'"~m"'},$e=function(e){return D(e)},et="~t",tt={type:"literal",value:"~t",description:'"~t"'},rt=function(e){return J(e)},nt="~tq",it={type:"literal",value:"~tq",description:'"~tq"'},st=function(e){return K(e)},ut="~ts",ct={type:"literal",value:"~ts",description:'"~ts"'},ot=function(e){return L(e)},at="~u",lt={type:"literal",value:"~u",description:'"~u"'},pt=function(e){return M(e)},ft={type:"other",description:"integer"},ht=/^['"]/,dt={type:"class",value:"['\"]",description:"['\"]"},vt=/^[0-9]/,yt={type:"class",value:"[0-9]",description:"[0-9]"},gt=function(e){return parseInt(e.join(""),10)},At={type:"other",description:"string"},xt='"',Rt={type:"literal",value:'"',description:'"\\""'},mt=function(e){return e.join("")},qt="'",Ct={type:"literal",value:"'",description:'"\'"'},wt=/^["\\]/,Et={type:"class",value:'["\\\\]',description:'["\\\\]'},bt={type:"any",description:"any character"},Ft=function(e){return e},Ut="\\",jt={type:"literal",value:"\\",description:'"\\\\"'},Tt=/^['\\]/,_t={type:"class",value:"['\\\\]",description:"['\\\\]"},St=/^['"\\]/,kt={type:"class",value:"['\"\\\\]",description:"['\"\\\\]"},Bt="n",It={type:"literal",value:"n",description:'"n"'},zt=function(){return"\n"},Dt="r",Gt={type:"literal",value:"r",description:'"r"'},Ht=function(){return"\r"},Jt="t",Kt={type:"literal",value:"t",description:'"t"'},Lt=function(){return" "},Mt=0,Nt=0,Ot=[{line:1,column:1,seenCR:!1}],Pt=0,Qt=[],Vt=0;if("startRule"in O){if(!(O.startRule in Q))throw new Error("Can't start parsing from rule \""+O.startRule+'".');V=Q[O.startRule]}var Wt=require("../flow/utils.js");U.desc="true",j.desc="false";var Xt=[new RegExp("text/javascript"),new RegExp("application/x-javascript"),new RegExp("application/javascript"),new RegExp("text/css"),new RegExp("image/.*"),new RegExp("application/x-shockwave-flash")];if(T.desc="is asset",k.desc="has error",G.desc="has no response",H.desc="has response",N=V(),N!==P&&Mt===e.length)return N;throw N!==P&&Mt<e.length&&i({type:"end",description:"end of input"}),s(null,Qt,Pt<e.length?e.charAt(Pt):null,Pt<e.length?n(Pt,Pt+1):n(Pt,Pt))}return e(t,Error),{SyntaxError:t,parse:r}}(); },{"../flow/utils.js":53}],53:[function(require,module,exports){ diff --git a/netlib/http/http2/framereader.py b/netlib/http/http2/framereader.py index d45be646..eb9b069a 100644 --- a/netlib/http/http2/framereader.py +++ b/netlib/http/http2/framereader.py @@ -1,6 +1,7 @@ import codecs import hyperframe +from ...exceptions import HttpException def http2_read_raw_frame(rfile): @@ -8,7 +9,7 @@ def http2_read_raw_frame(rfile): length = int(codecs.encode(header[:3], 'hex_codec'), 16) if length == 4740180: - raise ValueError("Length field looks more like HTTP/1.1: %s" % rfile.peek(20)) + raise HttpException("Length field looks more like HTTP/1.1:\n{}".format(rfile.read(-1))) body = rfile.safe_read(length) return [header, body] diff --git a/test/mitmproxy/test_protocol_http1.py b/test/mitmproxy/test_protocol_http1.py index e0a57b4e..cf7bd598 100644 --- a/test/mitmproxy/test_protocol_http1.py +++ b/test/mitmproxy/test_protocol_http1.py @@ -18,14 +18,14 @@ class TestInvalidRequests(tservers.HTTPProxyTest): p = self.pathoc() r = p.request("connect:'%s:%s'" % ("127.0.0.1", self.server2.port)) assert r.status_code == 400 - assert "Invalid HTTP request form" in r.content + assert b"Invalid HTTP request form" in r.content def test_relative_request(self): p = self.pathoc_raw() p.connect() r = p.request("get:/p/200") assert r.status_code == 400 - assert "Invalid HTTP request form" in r.content + assert b"Invalid HTTP request form" in r.content class TestExpectHeader(tservers.HTTPProxyTest): @@ -43,8 +43,8 @@ class TestExpectHeader(tservers.HTTPProxyTest): ) client.wfile.flush() - assert client.rfile.readline() == "HTTP/1.1 100 Continue\r\n" - assert client.rfile.readline() == "\r\n" + assert client.rfile.readline() == b"HTTP/1.1 100 Continue\r\n" + assert client.rfile.readline() == b"\r\n" client.wfile.write(b"0123456789abcdef\r\n") client.wfile.flush() diff --git a/test/mitmproxy/test_protocol_http2.py b/test/mitmproxy/test_protocol_http2.py index 23072260..932c8df2 100644 --- a/test/mitmproxy/test_protocol_http2.py +++ b/test/mitmproxy/test_protocol_http2.py @@ -13,6 +13,7 @@ from mitmproxy.cmdline import APP_HOST, APP_PORT import netlib from ..netlib import tservers as netlib_tservers +from netlib.exceptions import HttpException from netlib.http.http2 import framereader from . import tservers @@ -50,6 +51,9 @@ class _Http2ServerBase(netlib_tservers.ServerTestBase): try: raw = b''.join(framereader.http2_read_raw_frame(self.rfile)) events = h2_conn.receive_data(raw) + except HttpException: + print(traceback.format_exc()) + assert False except: break self.wfile.write(h2_conn.data_to_send()) @@ -60,9 +64,7 @@ class _Http2ServerBase(netlib_tservers.ServerTestBase): if not self.server.handle_server_event(event, h2_conn, self.rfile, self.wfile): done = True break - except Exception as e: - print(repr(e)) - print(traceback.format_exc()) + except: done = True break @@ -200,9 +202,12 @@ class TestSimple(_Http2TestBase, _Http2ServerBase): done = False while not done: try: - events = h2_conn.receive_data(b''.join(framereader.http2_read_raw_frame(client.rfile))) - except: - break + raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) + events = h2_conn.receive_data(raw) + except HttpException: + print(traceback.format_exc()) + assert False + client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() @@ -270,9 +275,12 @@ class TestWithBodies(_Http2TestBase, _Http2ServerBase): done = False while not done: try: - events = h2_conn.receive_data(b''.join(framereader.http2_read_raw_frame(client.rfile))) - except: - break + raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) + events = h2_conn.receive_data(raw) + except HttpException: + print(traceback.format_exc()) + assert False + client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() @@ -364,6 +372,9 @@ class TestPushPromise(_Http2TestBase, _Http2ServerBase): try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) + except HttpException: + print(traceback.format_exc()) + assert False except: break client.wfile.write(h2_conn.data_to_send()) @@ -412,9 +423,12 @@ class TestPushPromise(_Http2TestBase, _Http2ServerBase): responses = 0 while not done: try: - events = h2_conn.receive_data(b''.join(framereader.http2_read_raw_frame(client.rfile))) - except: - break + raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) + events = h2_conn.receive_data(raw) + except HttpException: + print(traceback.format_exc()) + assert False + client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() @@ -481,6 +495,9 @@ class TestConnectionLost(_Http2TestBase, _Http2ServerBase): try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) h2_conn.receive_data(raw) + except HttpException: + print(traceback.format_exc()) + assert False except: break try: @@ -7,7 +7,7 @@ deps = codecov>=2.0.5 passenv = CI TRAVIS_BUILD_ID TRAVIS TRAVIS_BRANCH TRAVIS_JOB_NUMBER TRAVIS_PULL_REQUEST TRAVIS_JOB_ID TRAVIS_REPO_SLUG TRAVIS_COMMIT setenv = - PY3TESTS = test/netlib test/pathod/ test/mitmproxy/script test/mitmproxy/test_contentview.py test/mitmproxy/test_custom_contentview.py test/mitmproxy/test_app.py test/mitmproxy/test_controller.py test/mitmproxy/test_fuzzing.py test/mitmproxy/test_script.py test/mitmproxy/test_web_app.py test/mitmproxy/test_utils.py test/mitmproxy/test_stateobject.py test/mitmproxy/test_cmdline.py test/mitmproxy/test_contrib_tnetstring.py + PY3TESTS = test/netlib test/pathod/ test/mitmproxy/script test/mitmproxy/test_contentview.py test/mitmproxy/test_custom_contentview.py test/mitmproxy/test_app.py test/mitmproxy/test_controller.py test/mitmproxy/test_fuzzing.py test/mitmproxy/test_script.py test/mitmproxy/test_web_app.py test/mitmproxy/test_utils.py test/mitmproxy/test_stateobject.py test/mitmproxy/test_cmdline.py test/mitmproxy/test_contrib_tnetstring.py test/mitmproxy/test_proxy.py test/mitmproxy/test_protocol_http1.py test/mitmproxy/test_platform_pf.py [testenv:py27] commands = diff --git a/web/src/js/app.jsx b/web/src/js/app.jsx index 1291df7a..23297f63 100644 --- a/web/src/js/app.jsx +++ b/web/src/js/app.jsx @@ -1,16 +1,15 @@ -import React from "react" +import React from 'react' import { render } from 'react-dom' import { applyMiddleware, createStore } from 'redux' import { Provider } from 'react-redux' import createLogger from 'redux-logger' import thunkMiddleware from 'redux-thunk' -import { Route, Router as ReactRouter, hashHistory, Redirect } from "react-router" +import { Route, Router as ReactRouter, hashHistory, Redirect } from 'react-router' -import Connection from "./connection" -import ProxyApp from "./components/ProxyApp" +import ProxyApp from './components/ProxyApp' import MainView from './components/MainView' import rootReducer from './ducks/index' -import { add as addLog } from "./ducks/eventLog" +import { add as addLog } from './ducks/eventLog' // logger must be last const store = createStore( @@ -18,14 +17,13 @@ const store = createStore( applyMiddleware(thunkMiddleware, createLogger()) ) +// @todo move to ProxyApp window.addEventListener('error', msg => { store.dispatch(addLog(msg)) }) // @todo remove this document.addEventListener('DOMContentLoaded', () => { - window.ws = new Connection("/updates", store.dispatch) - render( <Provider store={store}> <ReactRouter history={hashHistory}> diff --git a/web/src/js/components/ProxyApp.jsx b/web/src/js/components/ProxyApp.jsx index 5d795b57..84564c32 100644 --- a/web/src/js/components/ProxyApp.jsx +++ b/web/src/js/components/ProxyApp.jsx @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom' import _ from 'lodash' import { connect } from 'react-redux' +import { init as appInit, destruct as appDestruct } from '../ducks/app' import Header from './Header' import EventLog from './EventLog' import Footer from './Footer' @@ -26,27 +27,8 @@ class ProxyAppMain extends Component { this.updateLocation = this.updateLocation.bind(this) } - /** - * @todo move to actions - */ - updateLocation(pathname, queryUpdate) { - if (pathname === undefined) { - pathname = this.props.location.pathname - } - const query = this.props.location.query - for (const key of Object.keys(queryUpdate || {})) { - query[key] = queryUpdate[key] || undefined - } - this.context.router.replace({ pathname, query }) - } - - /** - * @todo pass in with props - */ - getQuery() { - // For whatever reason, react-router always returns the same object, which makes comparing - // the current props with nextProps impossible. As a workaround, we just clone the query object. - return _.clone(this.props.location.query) + componentWillMount() { + this.props.appInit() } /** @@ -56,6 +38,10 @@ class ProxyAppMain extends Component { this.focus() } + componentWillUnmount() { + this.props.appDestruct() + } + /** * @todo use props */ @@ -110,6 +96,29 @@ class ProxyAppMain extends Component { e.preventDefault() } + /** + * @todo move to actions + */ + updateLocation(pathname, queryUpdate) { + if (pathname === undefined) { + pathname = this.props.location.pathname + } + const query = this.props.location.query + for (const key of Object.keys(queryUpdate || {})) { + query[key] = queryUpdate[key] || undefined + } + this.context.router.replace({ pathname, query }) + } + + /** + * @todo pass in with props + */ + getQuery() { + // For whatever reason, react-router always returns the same object, which makes comparing + // the current props with nextProps impossible. As a workaround, we just clone the query object. + return _.clone(this.props.location.query) + } + render() { const { showEventLog, location, children } = this.props const query = this.getQuery() @@ -132,5 +141,10 @@ class ProxyAppMain extends Component { export default connect( state => ({ showEventLog: state.eventLog.visible, - }) + settings: state.settings.settings, + }), + { + appInit, + appDestruct, + } )(ProxyAppMain) diff --git a/web/src/js/connection.js b/web/src/js/connection.js deleted file mode 100644 index 6292cd57..00000000 --- a/web/src/js/connection.js +++ /dev/null @@ -1,49 +0,0 @@ -import {ConnectionActions} from "./actions.js"; -import {AppDispatcher} from "./dispatcher.js"; -import * as webSocketActions from "./ducks/websocket" -import * as eventLogActions from "./ducks/eventLog" -import * as flowActions from "./ducks/flows" -import * as settingsActions from './ducks/settings' - -export default function Connection(url, dispatch) { - if (url[0] === "/") { - url = location.origin.replace("http", "ws") + url; - } - - var ws = new WebSocket(url); - ws.onopen = function () { - dispatch(webSocketActions.connected()) - dispatch(settingsActions.fetchSettings()) - dispatch(eventLogActions.fetchData()) - dispatch(flowActions.fetchData()) - // workaround to make sure that our state is already available. - .then(() => { - console.log("flows are loaded now") - ConnectionActions.open() - }) - }; - ws.onmessage = function (m) { - var message = JSON.parse(m.data); - AppDispatcher.dispatchServerAction(message); - switch (message.type) { - case eventLogActions.WS_MSG_TYPE: - return dispatch(eventLogActions.handleWsMsg(message)) - case flowActions.WS_MSG_TYPE: - return dispatch(flowActions.handleWsMsg(message)) - case settingsActions.UPDATE_SETTINGS: - return dispatch(settingsActions.handleWsMsg(message)) - default: - console.warn("unknown message", message) - } - }; - ws.onerror = function () { - ConnectionActions.error(); - dispatch(eventLogActions.add("WebSocket connection error.")); - }; - ws.onclose = function () { - ConnectionActions.close(); - dispatch(eventLogActions.add("WebSocket connection closed.")); - dispatch(webSocketActions.disconnected()); - }; - return ws; -} diff --git a/web/src/js/ducks/app.js b/web/src/js/ducks/app.js new file mode 100644 index 00000000..f1dcb490 --- /dev/null +++ b/web/src/js/ducks/app.js @@ -0,0 +1,27 @@ +import { connect as wsConnect, disconnect as wsDisconnect } from './websocket' + +export const INIT = 'APP_INIT' + +const defaultState = {} + +export function reduce(state = defaultState, action) { + switch (action.type) { + + default: + return state + } +} + +export function init() { + return dispatch => { + dispatch(wsConnect()) + dispatch({ type: INIT }) + } +} + +export function destruct() { + return dispatch => { + dispatch(wsDisconnect()) + dispatch({ type: DESTRUCT }) + } +} diff --git a/web/src/js/ducks/websocket.js b/web/src/js/ducks/websocket.js index c10f9f5e..c79d887a 100644 --- a/web/src/js/ducks/websocket.js +++ b/web/src/js/ducks/websocket.js @@ -1,34 +1,118 @@ -const CONNECTED = 'WEBSOCKET_CONNECTED' -const DISCONNECTED = 'WEBSOCKET_DISCONNECTED' +import { ConnectionActions } from '../actions.js' +import { AppDispatcher } from '../dispatcher.js' +import * as eventLogActions from './eventLog' +import * as flowsActions from './flows' +import * as settingsActions from './settings' export const CMD_ADD = 'add' export const CMD_UPDATE = 'update' export const CMD_REMOVE = 'remove' export const CMD_RESET = 'reset' -const defaultState = { - connected: false, - /* we may want to have an error message attribute here at some point */ -} -export default function reducer(state = defaultState, action) { +export const SYM_SOCKET = Symbol('WEBSOCKET_SYM_SOCKET') + +export const CONNECT = 'WEBSOCKET_CONNECT' +export const CONNECTED = 'WEBSOCKET_CONNECTED' +export const DISCONNECT = 'WEBSOCKET_DISCONNECT' +export const DISCONNECTED = 'WEBSOCKET_DISCONNECTED' +export const ERROR = 'WEBSOCKET_ERROR' +export const MESSAGE = 'WEBSOCKET_MESSAGE' + +/* we may want to have an error message attribute here at some point */ +const defaultState = { connected: false, socket: null } + +export default function reduce(state = defaultState, action) { switch (action.type) { + + case CONNECT: + return { ...state, [SYM_SOCKET]: action.socket } + case CONNECTED: - return { - connected: true - } + return { ...state, connected: true } + + case DISCONNECT: + return { ...state, connected: false } + case DISCONNECTED: - return { - connected: false - } + return { ...state, [SYM_SOCKET]: null, connected: false } + default: return state } } +export function connect() { + return dispatch => { + const socket = new WebSocket(location.origin.replace('http', 'ws') + '/updates') + + // @todo remove this + window.ws = socket + + socket.addEventListener('open', () => dispatch(onConnect())) + socket.addEventListener('close', () => dispatch(onDisconnect())) + socket.addEventListener('message', msg => dispatch(onMessage(msg))) + socket.addEventListener('error', error => dispatch(onError(error))) + + dispatch({ type: CONNECT, socket }) + + return socket + } +} + +export function disconnect() { + return (dispatch, getState) => { + getState().settings[SYM_SOCKET].close() + dispatch({ type: DISCONNECT }) + } +} + +export function onConnect() { + // workaround to make sure that our state is already available. + return dispatch => { + dispatch({ type: CONNECTED }) + dispatch(settingsActions.fetchSettings()) + dispatch(flowsActions.fetchFlows()).then(() => ConnectionActions.open()) + } +} + +export function onMessage(msg) { + return dispatch => { + const data = JSON.parse(msg.data) + + AppDispatcher.dispatchServerAction(data) + + switch (data.type) { + + case eventLogActions.WS_MSG_TYPE: + return dispatch(eventLogActions.handleWsMsg(data)) + + case flowsActions.WS_MSG_TYPE: + return dispatch(flowsActions.handleWsMsg(data)) -export function connected() { - return {type: CONNECTED} + case settingsActions.UPDATE_SETTINGS: + return dispatch(settingsActions.handleWsMsg(data)) + + default: + console.warn('unknown message', data) + } + + dispatch({ type: MESSAGE, msg }) + } +} + +export function onDisconnect() { + return dispatch => { + ConnectionActions.close() + dispatch(eventLogActions.addLogEntry('WebSocket connection closed.')) + dispatch({ type: DISCONNECTED }) + } } -export function disconnected() { - return {type: DISCONNECTED} + +export function onError(error) { + // @todo let event log subscribe WebSocketActions.ERROR + return dispatch => { + ConnectionActions.error() + dispatch(eventLogActions.addLogEntry('WebSocket connection error.')) + dispatch({ type: ERROR, error }) + } } |