Merge pull request #1190 from mitmproxy/file_menu_save_open

File menu save open
This commit is contained in:
Maximilian Hils 2016-06-02 23:42:35 -07:00
commit 65fde7f554
7 changed files with 2073 additions and 1546 deletions

View File

@ -8,6 +8,8 @@ import re
import six
import tornado.websocket
from io import BytesIO
from mitmproxy.flow import FlowWriter, FlowReader
from mitmproxy import filt
from mitmproxy import version
@ -159,6 +161,26 @@ class Flows(RequestHandler):
data=[_strip_content(f.get_state()) for f in self.state.flows]
))
class DumpFlows(RequestHandler):
def get(self):
self.set_header("Content-Disposition", "attachment; filename=flows")
self.set_header("Content-Type", "application/octet-stream")
bio = BytesIO()
fw = FlowWriter(bio)
for f in self.state.flows:
fw.add(f)
self.write(bio.getvalue())
bio.close()
def post(self):
self.state.clear()
content = self.request.files.values()[0][0]["body"]
bio = BytesIO(content)
self.state.load_flows(FlowReader(bio).stream())
bio.close()
class ClearAll(RequestHandler):
@ -356,6 +378,7 @@ class Application(tornado.web.Application):
(r"/updates", ClientConnection),
(r"/events", Events),
(r"/flows", Flows),
(r"/flows/dump", DumpFlows),
(r"/flows/accept", AcceptFlows),
(r"/flows/(?P<flow_id>[0-9a-f\-]+)", FlowHandler),
(r"/flows/(?P<flow_id>[0-9a-f\-]+)/accept", AcceptFlow),

View File

@ -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])

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
import $ from "jquery";
import _ from "lodash";
import {AppDispatcher} from "./dispatcher.js";
import {fetchApi} from "./utils.js";
export var ActionTypes = {
// Connection
@ -117,6 +117,16 @@ export var FlowActions = {
},
clear: function(){
$.post("/clear");
},
download: () => window.location = "/flows/dump",
upload: (file) => {
let data = new FormData();
data.append('file', file);
fetchApi("/flows/dump", {
method: 'post',
body: data
})
}
};

View File

@ -344,12 +344,19 @@ var FileMenu = React.createClass({
}
},
handleOpenClick: function (e) {
this.fileInput.click();
e.preventDefault();
},
handleOpenFile: function (e) {
if (e.target.files.length > 0) {
FlowActions.upload(e.target.files[0]);
this.fileInput.value = "";
}
e.preventDefault();
console.error("unimplemented: handleOpenClick");
},
handleSaveClick: function (e) {
e.preventDefault();
console.error("unimplemented: handleSaveClick");
FlowActions.download();
},
handleShutdownClick: function (e) {
e.preventDefault();
@ -368,6 +375,20 @@ var FileMenu = React.createClass({
New
</a>
</li>
<li>
<a href="#" onClick={this.handleOpenClick}>
<i className="fa fa-fw fa-folder-open"></i>
Open...
</a>
<input ref={(ref) => this.fileInput = ref} className="hidden" type="file" onChange={this.handleOpenFile}/>
</li>
<li>
<a href="#" onClick={this.handleSaveClick}>
<i className="fa fa-fw fa-floppy-o"></i>
Save...
</a>
</li>
<li role="presentation" className="divider"></li>
<li>
<a href="http://mitm.it/" target="_blank">
@ -376,18 +397,6 @@ var FileMenu = React.createClass({
</a>
</li>
{/*
<li>
<a href="#" onClick={this.handleOpenClick}>
<i className="fa fa-fw fa-folder-open"></i>
Open
</a>
</li>
<li>
<a href="#" onClick={this.handleSaveClick}>
<i className="fa fa-fw fa-save"></i>
Save
</a>
</li>
<li role="presentation" className="divider"></li>
<li>
<a href="#" onClick={this.handleShutdownClick}>

View File

@ -2,7 +2,7 @@
import _ from "lodash";
import $ from "jquery";
import {EventEmitter} from 'events';
import { EventLogActions } from "../actions.js"
import {ActionTypes, StoreCmds} from "../actions.js";
import {AppDispatcher} from "../dispatcher.js";

View File

@ -80,7 +80,7 @@ function getCookie(name) {
var r = document.cookie.match(new RegExp("\\b" + name + "=([^;]*)\\b"));
return r ? r[1] : undefined;
}
var xsrf = $.param({_xsrf: getCookie("_xsrf")});
const xsrf = `_xsrf=${getCookie("_xsrf")}`;
//Tornado XSRF Protection.
$.ajaxPrefilter(function (options) {
@ -101,4 +101,16 @@ $(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) {
console.error(thrownError, message, arguments);
actions.EventLogActions.add_event(thrownError + ": " + message);
alert(message);
});
});
export function fetchApi(url, options) {
if(url.indexOf("?") === -1){
url += "?" + xsrf;
} else {
url += "&" + xsrf;
}
return fetch(url, {
...options,
credentials: 'same-origin'
});
}