aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/web/app.py3
-rw-r--r--mitmproxy/web/static/app.js75
-rw-r--r--web/src/js/actions.js15
3 files changed, 74 insertions, 19 deletions
diff --git a/mitmproxy/web/app.py b/mitmproxy/web/app.py
index af2f6e8c..594f1d3a 100644
--- a/mitmproxy/web/app.py
+++ b/mitmproxy/web/app.py
@@ -176,7 +176,8 @@ class DumpFlows(RequestHandler):
def post(self):
self.state.clear()
- bio = BytesIO(self.request.body)
+ content = self.request.files.values()[0][0]["body"]
+ bio = BytesIO(content)
self.state.load_flows(FlowReader(bio).stream())
bio.close()
diff --git a/mitmproxy/web/static/app.js b/mitmproxy/web/static/app.js
index e02df55a..12eea3e0 100644
--- a/mitmproxy/web/static/app.js
+++ b/mitmproxy/web/static/app.js
@@ -310,12 +310,10 @@ var _jquery = require("jquery");
var _jquery2 = _interopRequireDefault(_jquery);
-var _lodash = require("lodash");
-
-var _lodash2 = _interopRequireDefault(_lodash);
-
var _dispatcher = require("./dispatcher.js");
+var _utils = require("./utils.js");
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var ActionTypes = exports.ActionTypes = {
@@ -433,6 +431,18 @@ var FlowActions = exports.FlowActions = {
},
clear: function clear() {
_jquery2.default.post("/clear");
+ },
+ download: function download() {
+ return window.location = "/flows/dump";
+ },
+
+ upload: function upload(file) {
+ var data = new FormData();
+ data.append('file', file);
+ (0, _utils.fetchApi)("/flows/dump", {
+ method: 'post',
+ body: data
+ });
}
};
@@ -442,7 +452,7 @@ var Query = exports.Query = {
SHOW_EVENTLOG: "e"
};
-},{"./dispatcher.js":22,"jquery":"jquery","lodash":"lodash"}],3:[function(require,module,exports){
+},{"./dispatcher.js":22,"./utils.js":27,"jquery":"jquery"}],3:[function(require,module,exports){
"use strict";
var _react = require("react");
@@ -3513,18 +3523,27 @@ var FileMenu = _react2.default.createClass({
}
},
handleOpenClick: function handleOpenClick(e) {
+ this.fileInput.click();
+ e.preventDefault();
+ },
+ handleOpenFile: function handleOpenFile(e) {
+ if (e.target.files.length > 0) {
+ _actions.FlowActions.upload(e.target.files[0]);
+ this.fileInput.value = "";
+ }
e.preventDefault();
- console.error("unimplemented: handleOpenClick");
},
handleSaveClick: function handleSaveClick(e) {
e.preventDefault();
- console.error("unimplemented: handleSaveClick");
+ _actions.FlowActions.download();
},
handleShutdownClick: function handleShutdownClick(e) {
e.preventDefault();
console.error("unimplemented: handleShutdownClick");
},
render: function render() {
+ var _this = this;
+
var fileMenuClass = "dropdown pull-left" + (this.state.showFileMenu ? " open" : "");
return _react2.default.createElement(
@@ -3548,6 +3567,29 @@ var FileMenu = _react2.default.createClass({
"New"
)
),
+ _react2.default.createElement(
+ "li",
+ null,
+ _react2.default.createElement(
+ "a",
+ { href: "#", onClick: this.handleOpenClick },
+ _react2.default.createElement("i", { className: "fa fa-fw fa-folder-open" }),
+ "Open..."
+ ),
+ _react2.default.createElement("input", { ref: function ref(_ref) {
+ return _this.fileInput = _ref;
+ }, className: "hidden", type: "file", onChange: this.handleOpenFile })
+ ),
+ _react2.default.createElement(
+ "li",
+ null,
+ _react2.default.createElement(
+ "a",
+ { href: "#", onClick: this.handleSaveClick },
+ _react2.default.createElement("i", { className: "fa fa-fw fa-floppy-o" }),
+ "Save..."
+ )
+ ),
_react2.default.createElement("li", { role: "presentation", className: "divider" }),
_react2.default.createElement(
"li",
@@ -6602,7 +6644,7 @@ _lodash2.default.extend(LiveStoreMixin.prototype, {
this._fetchxhr = _jquery2.default.getJSON("/" + this.type).done(function (message) {
this.handle_fetch(message.data);
}.bind(this)).fail(function () {
- EventLogActions.add_event("Could not fetch " + this.type);
+ _actions.EventLogActions.add_event("Could not fetch " + this.type);
}.bind(this));
}
},
@@ -6792,7 +6834,11 @@ Object.defineProperty(exports, "__esModule", {
value: true
});
exports.formatTimeStamp = exports.formatTimeDelta = exports.formatSize = exports.Key = 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; };
+
exports.reverseString = reverseString;
+exports.fetchApi = fetchApi;
var _jquery = require("jquery");
@@ -6877,7 +6923,7 @@ function getCookie(name) {
var r = document.cookie.match(new RegExp("\\b" + name + "=([^;]*)\\b"));
return r ? r[1] : undefined;
}
-var xsrf = _jquery2.default.param({ _xsrf: getCookie("_xsrf") });
+var xsrf = "_xsrf=" + getCookie("_xsrf");
//Tornado XSRF Protection.
_jquery2.default.ajaxPrefilter(function (options) {
@@ -6900,6 +6946,17 @@ _jquery2.default.ajaxPrefilter(function (options) {
alert(message);
});
+function fetchApi(url, options) {
+ if (url.indexOf("?") === -1) {
+ url += "?" + xsrf;
+ } else {
+ url += "&" + xsrf;
+ }
+ return fetch(url, _extends({}, options, {
+ credentials: 'same-origin'
+ }));
+}
+
},{"./actions.js":2,"jquery":"jquery","lodash":"lodash","react":"react"}]},{},[3])
diff --git a/web/src/js/actions.js b/web/src/js/actions.js
index 9325765b..c77cdf73 100644
--- a/web/src/js/actions.js
+++ b/web/src/js/actions.js
@@ -121,15 +121,12 @@ export var FlowActions = {
download: () => window.location = "/flows/dump",
upload: (file) => {
- var filereader = new FileReader();
- filereader.file = file;
- filereader.onload = (e) => {
- fetchApi("/flows/dump", {
- method: 'post',
- body: e.currentTarget.result
- })
- };
- filereader.readAsBinaryString(file);
+ let data = new FormData();
+ data.append('file', file);
+ fetchApi("/flows/dump", {
+ method: 'post',
+ body: data
+ })
}
};