From f84098554a3d50ec02255603bb0a145b3aa0c6b2 Mon Sep 17 00:00:00 2001 From: Clemens Date: Wed, 13 Jul 2016 18:16:31 +0200 Subject: added code editor and file upload --- mitmproxy/web/app.py | 22 ++++++++---- web/package.json | 4 +-- web/src/js/app.jsx | 2 +- web/src/js/components/ContentView.jsx | 24 +++++++++++-- web/src/js/components/ContentView/ContentViews.jsx | 30 +++++++++++----- web/src/js/components/common/Button.jsx | 6 ++-- web/src/js/components/common/CodeEditor.jsx | 41 ++++++++++++++++++++++ web/src/js/components/common/MonacoEditor.jsx | 34 ------------------ web/src/js/ducks/flows.js | 8 +++++ 9 files changed, 115 insertions(+), 56 deletions(-) create mode 100644 web/src/js/components/common/CodeEditor.jsx delete mode 100644 web/src/js/components/common/MonacoEditor.jsx diff --git a/mitmproxy/web/app.py b/mitmproxy/web/app.py index 8434818d..c2d46d30 100644 --- a/mitmproxy/web/app.py +++ b/mitmproxy/web/app.py @@ -245,9 +245,6 @@ class FlowHandler(RequestHandler): request.port = int(v) elif k == "headers": request.headers.set_state(v) - elif k == "content": - print(v) - response.content = str(v) else: print("Warning: Unknown update {}.{}: {}".format(a, k, v)) @@ -262,9 +259,6 @@ class FlowHandler(RequestHandler): response.http_version = str(v) elif k == "headers": response.headers.set_state(v) - elif k == "content": - print(v) - response.content = str(v) else: print("Warning: Unknown update {}.{}: {}".format(a, k, v)) else: @@ -298,6 +292,22 @@ class ReplayFlow(RequestHandler): class FlowContent(RequestHandler): + def post (self, flow_id, message): + # handle request later now just change response content + + flow = self.flow + flow.backup() + content = '' + if (len(self.request.files.values()) > 0): + content = self.request.files.values()[0][0]["body"] + elif (len(self.request.arguments) > 0): + content = self.request.arguments['file'] + + flow.response.content = str(content) + self.state.update_flow(flow) + + + def get(self, flow_id, message): message = getattr(self.flow, message) diff --git a/web/package.json b/web/package.json index 1484961d..7cfd3d90 100644 --- a/web/package.json +++ b/web/package.json @@ -3,7 +3,7 @@ "private": true, "scripts": { "test": "jest", - "build": "gulp dev", + "build": "gulp prod", "start": "gulp" }, "jest": { @@ -29,7 +29,7 @@ "redux-logger": "^2.6.1", "redux-thunk": "^2.1.0", "shallowequal": "^0.2.2", - "monaco-editor": "^0.5.1" + "react-ace": "^3.5.0" }, "devDependencies": { "babel-core": "^6.7.7", diff --git a/web/src/js/app.jsx b/web/src/js/app.jsx index 51b2b639..5acf5dd4 100644 --- a/web/src/js/app.jsx +++ b/web/src/js/app.jsx @@ -12,7 +12,7 @@ import { add as addLog } from './ducks/eventLog' const middlewares = [thunk]; -if (process.env.NODE_ENV === 'development' || true) { +if (process.env.NODE_ENV === 'development' ) { const createLogger = require('redux-logger'); middlewares.push(createLogger()); } diff --git a/web/src/js/components/ContentView.jsx b/web/src/js/components/ContentView.jsx index f6dbe90a..6c9d9b26 100644 --- a/web/src/js/components/ContentView.jsx +++ b/web/src/js/components/ContentView.jsx @@ -4,6 +4,7 @@ import { ViewAuto, ViewImage } from './ContentView/ContentViews' import * as MetaViews from './ContentView/MetaViews' import ContentLoader from './ContentView/ContentLoader' import ViewSelector from './ContentView/ViewSelector' +import * as flowsActions from '../ducks/flows' export default class ContentView extends Component { @@ -40,6 +41,15 @@ export default class ContentView extends Component { return msg.contentLength > 1024 * 1024 * (ViewImage.matches(msg) ? 10 : 0.2) } + onOpenFile(e) { + if (e.target.files.length > 0) { + //alert(e.target.files[0]) + flowsActions.update_content(this.props.flow, e.target.files[0]) + //this.fileInput.value = '' + } + e.preventDefault() + } + render() { const { flow, message } = this.props const { displayLarge, View } = this.state @@ -60,10 +70,10 @@ export default class ContentView extends Component {
{View.textView ? ( - + flowsActions.update_content(this.props.flow, content)} content="" /> ) : ( - + flowsActions.update_content(this.props.flow, content)} message={message} /> )}
@@ -71,6 +81,16 @@ export default class ContentView extends Component { +   + {this.fileInput.click(); e.preventDefault();}}> + + + this.fileInput = ref} + className="hidden" + type="file" + onChange={e => this.onOpenFile(e)} + />
) diff --git a/web/src/js/components/ContentView/ContentViews.jsx b/web/src/js/components/ContentView/ContentViews.jsx index e5a864bf..617ed242 100644 --- a/web/src/js/components/ContentView/ContentViews.jsx +++ b/web/src/js/components/ContentView/ContentViews.jsx @@ -1,10 +1,12 @@ import React, { PropTypes } from 'react' import ContentLoader from './ContentLoader' import { MessageUtils } from '../../flow/utils.js' -import Button from '../common/Button' +import CodeEditor from '../common/CodeEditor' +import {formatSize} from '../../utils.js' -const views = [ViewAuto, ViewImage, ViewJSON, ViewRaw] + +const views = [ViewAuto, ViewImage, ViewJSON, ViewRaw, ViewFile] ViewImage.regex = /^image\/(png|jpe?g|gif|vnc.microsoft.icon|x-icon)$/i ViewImage.matches = msg => ViewImage.regex.test(MessageUtils.getContentType(msg)) @@ -30,12 +32,9 @@ ViewRaw.propTypes = { content: React.PropTypes.string.isRequired, } -export function ViewRaw({ content, onChange }) { +export function ViewRaw({ content, update_content }) { return ( -
- -
+ ) } @@ -66,13 +65,26 @@ ViewAuto.propTypes = { flow: React.PropTypes.object.isRequired, } -export function ViewAuto({ message, flow, onChange }) { +export function ViewAuto({ message, flow, update_content }) { const View = ViewAuto.findView(message) if (View.textView) { - return + return } else { return } } +ViewFile.matches = () => false + +ViewFile.propTypes = { + message: React.PropTypes.object.isRequired, + flow: React.PropTypes.object.isRequired, +} + +export function ViewFile({ message, flow }) { + return
+ {formatSize(message.contentLength)} content size. +
+} + export default views diff --git a/web/src/js/components/common/Button.jsx b/web/src/js/components/common/Button.jsx index 574288df..221c6ace 100644 --- a/web/src/js/components/common/Button.jsx +++ b/web/src/js/components/common/Button.jsx @@ -10,8 +10,10 @@ export default function Button({ onClick, text, icon, disabled }) {
- -   + {text}
) diff --git a/web/src/js/components/common/CodeEditor.jsx b/web/src/js/components/common/CodeEditor.jsx new file mode 100644 index 00000000..d7e6aabb --- /dev/null +++ b/web/src/js/components/common/CodeEditor.jsx @@ -0,0 +1,41 @@ +import React, { Component, PropTypes } from 'react' +import { render } from 'react-dom'; +import brace from 'brace'; +import AceEditor from 'react-ace'; +import Button from './Button' + + +import 'brace/mode/javascript'; +import 'brace/mode/json'; +import 'brace/theme/monokai'; + + + + +export default class CodeEditor extends Component{ + constructor( props ) { + super(props) + this.state = {value: this.props.value} + } + + onChange(newValue) { + this.setState({value: newValue}) + } + + render() { + return ( +
e.stopPropagation()}> + this.onChange(e)} + mode="javascript" + theme="monokai" + value={this.state.value} + width="100%" + name="codeEditor" + editorProps={{$blockScrolling: Infinity}} + /> +
+ ) + } +} diff --git a/web/src/js/components/common/MonacoEditor.jsx b/web/src/js/components/common/MonacoEditor.jsx deleted file mode 100644 index a0e8d58c..00000000 --- a/web/src/js/components/common/MonacoEditor.jsx +++ /dev/null @@ -1,34 +0,0 @@ -//not working -import React, { Component, PropTypes } from 'react' - -export default class MonacoEditor extends Component { - - constructor(props) { - super(props) - } - - onLoad(){ - window.MonacoEnvironment = { - getWorkerUrl: function(workerId, label) { - return 'worker-loader-proxy.js'; - } - }; - require.config({ - paths: { - vs: '../release/min/vs' - } - }); - - } - - - render() { - return ( -
this.editor = ref} - style="width:800px;height:600px;border:1px solid grey" - onLoad={this.onLoad()}> -
- ) - } -} diff --git a/web/src/js/ducks/flows.js b/web/src/js/ducks/flows.js index f0b09530..36274f39 100644 --- a/web/src/js/ducks/flows.js +++ b/web/src/js/ducks/flows.js @@ -117,6 +117,14 @@ export function update(flow, data) { return { type: REQUEST_ACTION } } +export function update_content(flow, file) { + const body = new FormData() + body.append('file', file) + fetchApi(`/flows/${flow.id}/response/content`, {method: 'post', body} ) + return { type: REQUEST_ACTION } +} + + /** * @public */ -- cgit v1.2.3