aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/web/static/app.js211
-rw-r--r--mitmproxy/web/static/vendor.js24
-rw-r--r--web/package.json2
-rw-r--r--web/src/js/app.js9
-rw-r--r--web/src/js/components/eventlog.js1
-rw-r--r--web/src/js/connection.js15
-rw-r--r--web/src/js/ducks/eventLog.js29
-rw-r--r--web/src/js/ducks/list.js21
-rw-r--r--web/src/js/ducks/utils/list.js121
9 files changed, 360 insertions, 73 deletions
diff --git a/mitmproxy/web/static/app.js b/mitmproxy/web/static/app.js
index b78dd337..83fd0c58 100644
--- a/mitmproxy/web/static/app.js
+++ b/mitmproxy/web/static/app.js
@@ -469,6 +469,10 @@ var _reduxLogger = require('redux-logger');
var _reduxLogger2 = _interopRequireDefault(_reduxLogger);
+var _reduxThunk = require('redux-thunk');
+
+var _reduxThunk2 = _interopRequireDefault(_reduxThunk);
+
var _connection = require('./connection');
var _connection2 = _interopRequireDefault(_connection);
@@ -485,7 +489,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
// logger must be last
var logger = (0, _reduxLogger2.default)();
-var store = (0, _redux.createStore)(_index2.default, (0, _redux.applyMiddleware)(logger));
+var store = (0, _redux.createStore)(_index2.default, (0, _redux.applyMiddleware)(_reduxThunk2.default, logger));
window.onerror = function (msg) {
store.dispatch((0, _eventLog.addLogEntry)(msg));
@@ -501,7 +505,7 @@ document.addEventListener('DOMContentLoaded', function () {
), document.getElementById("mitmproxy"));
});
-},{"./components/proxyapp.js":20,"./connection":21,"./ducks/eventLog":23,"./ducks/index":24,"react":"react","react-dom":"react-dom","react-redux":"react-redux","redux":"redux","redux-logger":"redux-logger"}],4:[function(require,module,exports){
+},{"./components/proxyapp.js":20,"./connection":21,"./ducks/eventLog":23,"./ducks/index":24,"react":"react","react-dom":"react-dom","react-redux":"react-redux","redux":"redux","redux-logger":"redux-logger","redux-thunk":"redux-thunk"}],4:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
@@ -1094,7 +1098,6 @@ var EventLogContents = function (_React$Component) {
}, {
key: "setHeight",
value: function setHeight(id, node) {
- console.log("setHeight", id, node);
if (node && !this.heights[id]) {
var height = node.offsetHeight;
if (this.heights[id] !== height) {
@@ -4402,7 +4405,11 @@ var _dispatcher = require("./dispatcher.js");
var _websocket = require("./ducks/websocket");
-var websocketActions = _interopRequireWildcard(_websocket);
+var webSocketActions = _interopRequireWildcard(_websocket);
+
+var _eventLog = require("./ducks/eventLog");
+
+var eventLogActions = _interopRequireWildcard(_eventLog);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
@@ -4413,14 +4420,20 @@ function Connection(url, dispatch) {
var ws = new WebSocket(url);
ws.onopen = function () {
- dispatch(websocketActions.connected());
+ dispatch(webSocketActions.connected());
+ dispatch(eventLogActions.fetchLogEntries());
_actions.ConnectionActions.open();
//TODO: fetch stuff!
};
ws.onmessage = function (m) {
var message = JSON.parse(m.data);
_dispatcher.AppDispatcher.dispatchServerAction(message);
- dispatch(message);
+ switch (message.type) {
+ case eventLogActions.UPDATE_LOG:
+ return dispatch(eventLogActions.updateLogEntries(message));
+ default:
+ console.warn("unknown message", message);
+ }
};
ws.onerror = function () {
_actions.ConnectionActions.error();
@@ -4434,7 +4447,7 @@ function Connection(url, dispatch) {
return ws;
}
-},{"./actions.js":2,"./dispatcher.js":22,"./ducks/websocket":26}],22:[function(require,module,exports){
+},{"./actions.js":2,"./dispatcher.js":22,"./ducks/eventLog":23,"./ducks/websocket":26}],22:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
@@ -4469,6 +4482,7 @@ AppDispatcher.dispatchServerAction = function (action) {
Object.defineProperty(exports, "__esModule", {
value: true
});
+exports.fetchLogEntries = exports.updateLogEntries = exports.UPDATE_LOG = undefined;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
@@ -4477,7 +4491,7 @@ exports.toggleEventLogFilter = toggleEventLogFilter;
exports.toggleEventLogVisibility = toggleEventLogVisibility;
exports.addLogEntry = addLogEntry;
-var _list = require('./list');
+var _list = require('./utils/list');
var _list2 = _interopRequireDefault(_list);
@@ -4487,7 +4501,17 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
var TOGGLE_FILTER = 'TOGGLE_EVENTLOG_FILTER';
var TOGGLE_VISIBILITY = 'TOGGLE_EVENTLOG_VISIBILITY';
-var UPDATE_LIST = "UPDATE_EVENTLOG";
+var UPDATE_LOG = exports.UPDATE_LOG = "UPDATE_EVENTLOG";
+
+var _makeList = (0, _list2.default)(UPDATE_LOG, "/events");
+
+var reduceList = _makeList.reduceList;
+var addToList = _makeList.addToList;
+var updateList = _makeList.updateList;
+var fetchList = _makeList.fetchList;
+exports.updateLogEntries = updateList;
+exports.fetchLogEntries = fetchList;
+
var defaultState = {
visible: false,
@@ -4496,7 +4520,7 @@ var defaultState = {
"info": true,
"web": true
},
- events: (0, _list2.default)(),
+ events: reduceList(),
filteredEvents: []
};
@@ -4517,8 +4541,8 @@ function reducer() {
return _extends({}, state, {
visible: !state.visible
});
- case UPDATE_LIST:
- var events = (0, _list2.default)(state.events, action);
+ case UPDATE_LOG:
+ var events = reduceList(state.events, action);
return _extends({}, state, {
events: events,
filteredEvents: events.list.filter(function (x) {
@@ -4540,14 +4564,14 @@ var id = 0;
function addLogEntry(message) {
var level = arguments.length <= 1 || arguments[1] === undefined ? "web" : arguments[1];
- return {
- type: UPDATE_LIST,
- cmd: _list.ADD,
- data: { message: message, level: level, id: 'log-' + id++ }
- };
+ return addToList({
+ message: message,
+ level: level,
+ id: 'log-' + id++
+ });
}
-},{"./list":25}],24:[function(require,module,exports){
+},{"./utils/list":25}],24:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
@@ -4574,7 +4598,7 @@ var rootReducer = (0, _redux.combineReducers)({
exports.default = rootReducer;
},{"./eventLog.js":23,"./websocket.js":26,"redux":"redux"}],25:[function(require,module,exports){
-'use strict';
+"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
@@ -4582,38 +4606,155 @@ Object.defineProperty(exports, "__esModule", {
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-exports.default = getList;
+exports.default = makeList;
+
+var _utils = require("../../utils");
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
-var ADD = exports.ADD = 'add';
+var ADD = "ADD";
+var REQUEST_LIST = "REQUEST_LIST";
+var RECEIVE_LIST = "RECEIVE_LIST";
var defaultState = {
list: [],
- //isFetching: false,
- //updateBeforeFetch: [],
+ isFetching: false,
+ actionsDuringFetch: [],
+ byId: {},
indexOf: {}
};
-//views: {}
-function getList() {
- var state = arguments.length <= 0 || arguments[0] === undefined ? defaultState : arguments[0];
- var action = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
+function makeList(actionType, fetchURL) {
+ function reduceList() {
+ var state = arguments.length <= 0 || arguments[0] === undefined ? defaultState : arguments[0];
+ var action = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
- switch (action.cmd) {
- case ADD:
- return {
- list: [].concat(_toConsumableArray(state.list), [action.data]),
- indexOf: _extends({}, state.indexOf, _defineProperty({}, action.data.id, state.list.length))
- };
- default:
+
+ if (action.type !== actionType) {
return state;
+ }
+
+ // Handle cases where we finished fetching or are still fetching.
+ if (action.cmd === RECEIVE_LIST) {
+ var s = {
+ isFetching: false,
+ actionsDuringFetch: [],
+ list: action.list,
+ byId: {},
+ indexOf: {}
+ };
+ for (var i = 0; i < action.list.length; i++) {
+ var item = action.list[i];
+ s.byId[item.id] = item;
+ s.indexOf[item.id] = i;
+ }
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = state.actionsDuringFetch[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ action = _step.value;
+
+ s = reduceList(s, action);
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator.return) {
+ _iterator.return();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return s;
+ } else if (state.isFetching) {
+ return _extends({}, state, {
+ actionsDuringFetch: [].concat(_toConsumableArray(state.actionsDuringFetch), [action])
+ });
+ }
+
+ switch (action.cmd) {
+ case ADD:
+ return {
+ list: [].concat(_toConsumableArray(state.list), [action.item]),
+ byId: _extends({}, state.byId, _defineProperty({}, action.item.id, action.item)),
+ indexOf: _extends({}, state.indexOf, _defineProperty({}, action.item.id, state.list.length))
+ };
+
+ case REQUEST_LIST:
+ return _extends({}, defaultState, {
+ isFetching: true
+ });
+
+ default:
+ console.debug("unknown action", action.type);
+ return state;
+ }
+ }
+
+ function addToList(item) {
+ return {
+ type: actionType,
+ cmd: ADD,
+ item: item
+ };
+ }
+
+ function updateList(action) {
+ /* This action creater takes all WebSocket events */
+ return function (dispatch) {
+ switch (action.cmd) {
+ case "add":
+ return dispatch(addToList(action.data));
+ case "reset":
+ return dispatch(fetchList());
+ default:
+ console.error("unknown list update", action);
+ }
+ };
}
+
+ function requestList() {
+ return {
+ type: actionType,
+ cmd: REQUEST_LIST
+ };
+ }
+
+ function receiveList(list) {
+ return {
+ type: actionType,
+ cmd: RECEIVE_LIST,
+ list: list
+ };
+ }
+
+ function fetchList() {
+ return function (dispatch) {
+
+ dispatch(requestList());
+
+ (0, _utils.fetchApi)(fetchURL).then(function (response) {
+ return response.json().then(function (json) {
+ dispatch(receiveList(json.data));
+ });
+ });
+ };
+ }
+
+ return { reduceList: reduceList, addToList: addToList, updateList: updateList, fetchList: fetchList };
}
-},{}],26:[function(require,module,exports){
+},{"../../utils":31}],26:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
diff --git a/mitmproxy/web/static/vendor.js b/mitmproxy/web/static/vendor.js
index 61596f06..7fab13f5 100644
--- a/mitmproxy/web/static/vendor.js
+++ b/mitmproxy/web/static/vendor.js
@@ -53581,6 +53581,30 @@ function createLogger() {
}
module.exports = createLogger;
+},{}],"redux-thunk":[function(require,module,exports){
+'use strict';
+
+exports.__esModule = true;
+function createThunkMiddleware(extraArgument) {
+ return function (_ref) {
+ var dispatch = _ref.dispatch;
+ var getState = _ref.getState;
+ return function (next) {
+ return function (action) {
+ if (typeof action === 'function') {
+ return action(dispatch, getState, extraArgument);
+ }
+
+ return next(action);
+ };
+ };
+ };
+}
+
+var thunk = createThunkMiddleware();
+thunk.withExtraArgument = createThunkMiddleware;
+
+exports['default'] = thunk;
},{}],"redux":[function(require,module,exports){
(function (process){
'use strict';
diff --git a/web/package.json b/web/package.json
index bb32a2dc..3bbed9e8 100644
--- a/web/package.json
+++ b/web/package.json
@@ -27,6 +27,7 @@
"react-router": "^2.4.0",
"redux": "^3.5.2",
"redux-logger": "^2.6.1",
+ "redux-thunk": "^2.1.0",
"shallowequal": "^0.2.2"
},
"devDependencies": {
@@ -52,6 +53,7 @@
"gulp-sourcemaps": "^1.6.0",
"gulp-util": "^3.0.7",
"jest": "^0.1.40",
+ "redux-thunk": "^2.1.0",
"uglifyify": "^3.0.1",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0",
diff --git a/web/src/js/app.js b/web/src/js/app.js
index fc99f1d2..b49de002 100644
--- a/web/src/js/app.js
+++ b/web/src/js/app.js
@@ -2,7 +2,9 @@ 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 createLogger from 'redux-logger'
+import thunkMiddleware from 'redux-thunk'
+
import Connection from "./connection"
import {App} from "./components/proxyapp.js"
@@ -11,7 +13,10 @@ import {addLogEntry} from "./ducks/eventLog";
// logger must be last
const logger = createLogger();
-const store = createStore(rootReducer, applyMiddleware(logger));
+const store = createStore(
+ rootReducer,
+ applyMiddleware(thunkMiddleware, logger)
+);
window.onerror = function (msg) {
store.dispatch(addLogEntry(msg));
diff --git a/web/src/js/components/eventlog.js b/web/src/js/components/eventlog.js
index 95889a66..6ada58ff 100644
--- a/web/src/js/components/eventlog.js
+++ b/web/src/js/components/eventlog.js
@@ -64,7 +64,6 @@ class EventLogContents extends React.Component {
}
setHeight(id, node) {
- console.log("setHeight", id, node);
if (node && !this.heights[id]) {
const height = node.offsetHeight;
if (this.heights[id] !== height) {
diff --git a/web/src/js/connection.js b/web/src/js/connection.js
index 75c2cf25..090dbb29 100644
--- a/web/src/js/connection.js
+++ b/web/src/js/connection.js
@@ -1,6 +1,7 @@
import {ConnectionActions, EventLogActions} from "./actions.js";
import {AppDispatcher} from "./dispatcher.js";
-import * as websocketActions from "./ducks/websocket"
+import * as webSocketActions from "./ducks/websocket"
+import * as eventLogActions from "./ducks/eventLog"
export default function Connection(url, dispatch) {
if (url[0] === "/") {
@@ -9,14 +10,20 @@ export default function Connection(url, dispatch) {
var ws = new WebSocket(url);
ws.onopen = function () {
- dispatch(websocketActions.connected());
- ConnectionActions.open();
+ dispatch(webSocketActions.connected())
+ dispatch(eventLogActions.fetchLogEntries())
+ ConnectionActions.open()
//TODO: fetch stuff!
};
ws.onmessage = function (m) {
var message = JSON.parse(m.data);
AppDispatcher.dispatchServerAction(message);
- dispatch(message);
+ switch (message.type) {
+ case eventLogActions.UPDATE_LOG:
+ return dispatch(eventLogActions.updateLogEntries(message))
+ default:
+ console.warn("unknown message", message)
+ }
};
ws.onerror = function () {
ConnectionActions.error();
diff --git a/web/src/js/ducks/eventLog.js b/web/src/js/ducks/eventLog.js
index 2040711c..081a2276 100644
--- a/web/src/js/ducks/eventLog.js
+++ b/web/src/js/ducks/eventLog.js
@@ -1,8 +1,17 @@
-import getList, {ADD} from "./list"
+import makeList, {ADD} from "./utils/list"
+
const TOGGLE_FILTER = 'TOGGLE_EVENTLOG_FILTER'
const TOGGLE_VISIBILITY = 'TOGGLE_EVENTLOG_VISIBILITY'
-const UPDATE_LIST = "UPDATE_EVENTLOG"
+export const UPDATE_LOG = "UPDATE_EVENTLOG"
+
+const {
+ reduceList,
+ addToList,
+ updateList,
+ fetchList,
+} = makeList(UPDATE_LOG, "/events");
+export {updateList as updateLogEntries, fetchList as fetchLogEntries}
const defaultState = {
visible: false,
@@ -11,7 +20,7 @@ const defaultState = {
"info": true,
"web": true
},
- events: getList(),
+ events: reduceList(),
filteredEvents: [],
}
@@ -32,8 +41,8 @@ export default function reducer(state = defaultState, action) {
...state,
visible: !state.visible
}
- case UPDATE_LIST:
- const events = getList(state.events, action)
+ case UPDATE_LOG:
+ const events = reduceList(state.events, action)
return {
...state,
events,
@@ -53,9 +62,9 @@ export function toggleEventLogVisibility() {
}
let id = 0;
export function addLogEntry(message, level = "web") {
- return {
- type: UPDATE_LIST,
- cmd: ADD,
- data: {message, level, id: `log-${id++}`}
- }
+ return addToList({
+ message,
+ level,
+ id: `log-${id++}`
+ })
} \ No newline at end of file
diff --git a/web/src/js/ducks/list.js b/web/src/js/ducks/list.js
deleted file mode 100644
index 0b3771e2..00000000
--- a/web/src/js/ducks/list.js
+++ /dev/null
@@ -1,21 +0,0 @@
-export const ADD = 'add'
-
-const defaultState = {
- list: [],
- //isFetching: false,
- //updateBeforeFetch: [],
- indexOf: {},
- //views: {}
-};
-
-export default function getList(state = defaultState, action = {}) {
- switch (action.cmd) {
- case ADD:
- return {
- list: [...state.list, action.data],
- indexOf: {...state.indexOf, [action.data.id]: state.list.length},
- }
- default:
- return state
- }
-} \ No newline at end of file
diff --git a/web/src/js/ducks/utils/list.js b/web/src/js/ducks/utils/list.js
new file mode 100644
index 00000000..37b2ae3a
--- /dev/null
+++ b/web/src/js/ducks/utils/list.js
@@ -0,0 +1,121 @@
+import {fetchApi} from "../../utils";
+
+const ADD = "ADD"
+const REQUEST_LIST = "REQUEST_LIST"
+const RECEIVE_LIST = "RECEIVE_LIST"
+
+
+const defaultState = {
+ list: [],
+ isFetching: false,
+ actionsDuringFetch: [],
+ byId: {},
+ indexOf: {},
+};
+
+export default function makeList(actionType, fetchURL) {
+ function reduceList(state = defaultState, action = {}) {
+
+ if (action.type !== actionType) {
+ return state
+ }
+
+ // Handle cases where we finished fetching or are still fetching.
+ if (action.cmd === RECEIVE_LIST) {
+ let s = {
+ isFetching: false,
+ actionsDuringFetch: [],
+ list: action.list,
+ byId: {},
+ indexOf: {}
+ }
+ for (let i = 0; i < action.list.length; i++) {
+ let item = action.list[i]
+ s.byId[item.id] = item
+ s.indexOf[item.id] = i
+ }
+ for (action of state.actionsDuringFetch) {
+ s = reduceList(s, action)
+ }
+ return s
+ } else if (state.isFetching) {
+ return {
+ ...state,
+ actionsDuringFetch: [...state.actionsDuringFetch, action]
+ }
+ }
+
+ switch (action.cmd) {
+ case ADD:
+ return {
+ list: [...state.list, action.item],
+ byId: {...state.byId, [action.item.id]: action.item},
+ indexOf: {...state.indexOf, [action.item.id]: state.list.length},
+ }
+
+ case REQUEST_LIST:
+ return {
+ ...defaultState,
+ isFetching: true
+ }
+
+ default:
+ console.debug("unknown action", action.type)
+ return state
+ }
+ }
+
+ function addToList(item) {
+ return {
+ type: actionType,
+ cmd: ADD,
+ item
+ }
+ }
+
+
+ function updateList(action) {
+ /* This action creater takes all WebSocket events */
+ return dispatch => {
+ switch (action.cmd) {
+ case "add":
+ return dispatch(addToList(action.data))
+ case "reset":
+ return dispatch(fetchList())
+ default:
+ console.error("unknown list update", action)
+ }
+ }
+ }
+
+ function requestList() {
+ return {
+ type: actionType,
+ cmd: REQUEST_LIST,
+ }
+ }
+
+ function receiveList(list) {
+ return {
+ type: actionType,
+ cmd: RECEIVE_LIST,
+ list
+ }
+ }
+
+ function fetchList() {
+ return dispatch => {
+
+ dispatch(requestList())
+
+ fetchApi(fetchURL).then(response => {
+ return response.json().then(json => {
+ dispatch(receiveList(json.data))
+ })
+ })
+ }
+ }
+
+
+ return {reduceList, addToList, updateList, fetchList}
+} \ No newline at end of file