aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/js
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2014-09-21 23:43:27 +0200
committerMaximilian Hils <git@maximilianhils.com>2014-09-21 23:43:27 +0200
commit9cda2eb3a3d8da1522a18dc1d0dd6ae5f29f4607 (patch)
treeff20b491654a8b5ac2eaf54fafc1af61c4d5e503 /web/src/js
parent60cec1f9b6efe17936d721907ea45b2fff482f6b (diff)
downloadmitmproxy-9cda2eb3a3d8da1522a18dc1d0dd6ae5f29f4607.tar.gz
mitmproxy-9cda2eb3a3d8da1522a18dc1d0dd6ae5f29f4607.tar.bz2
mitmproxy-9cda2eb3a3d8da1522a18dc1d0dd6ae5f29f4607.zip
web: various improvements
Diffstat (limited to 'web/src/js')
-rw-r--r--web/src/js/components/flowdetail.jsx.js134
-rw-r--r--web/src/js/components/flowtable-columns.jsx.js4
-rw-r--r--web/src/js/components/header.jsx.js4
-rw-r--r--web/src/js/utils.js6
4 files changed, 105 insertions, 43 deletions
diff --git a/web/src/js/components/flowdetail.jsx.js b/web/src/js/components/flowdetail.jsx.js
index 7c984193..ad1cfe67 100644
--- a/web/src/js/components/flowdetail.jsx.js
+++ b/web/src/js/components/flowdetail.jsx.js
@@ -25,9 +25,9 @@ var FlowDetailNav = React.createClass({
var Headers = React.createClass({
render: function(){
- var rows = this.props.message.headers.map(function(header){
+ var rows = this.props.message.headers.map(function(header, i){
return (
- <tr>
+ <tr key={i}>
<td className="header-name">{header[0]+":"}</td>
<td className="header-value">{header[1]}</td>
</tr>
@@ -62,7 +62,7 @@ var FlowDetailRequest = React.createClass({
return (
<section>
- <code>{ first_line }</code>
+ <div className="first-line">{ first_line }</div>
<Headers message={flow.request}/>
<hr/>
{content}
@@ -90,7 +90,7 @@ var FlowDetailResponse = React.createClass({
return (
<section>
- <code>{ first_line }</code>
+ <div className="first-line">{ first_line }</div>
<Headers message={flow.response}/>
<hr/>
{content}
@@ -101,23 +101,21 @@ var FlowDetailResponse = React.createClass({
var TimeStamp = React.createClass({
render: function() {
- var ts, delta;
- if(!this.props.t && this.props.optional){
+ if(!this.props.t){
//should be return null, but that triggers a React bug.
return <tr></tr>;
- } else if (!this.props.t){
- ts = "active";
+ }
+
+ var ts = (new Date(this.props.t * 1000)).toISOString();
+ ts = ts.replace("T", " ").replace("Z","");
+
+ var delta;
+ if(this.props.deltaTo){
+ delta = formatTimeDelta(1000 * (this.props.t-this.props.deltaTo));
+ delta = <span className="text-muted">{"(" + delta + ")"}</span>;
} else {
- ts = (new Date(this.props.t * 1000)).toISOString();
- ts = ts.replace("T", " ").replace("Z","");
-
- if(this.props.deltaTo){
- delta = Math.round((this.props.t-this.props.deltaTo)*1000) + "ms";
- delta = <span className="text-muted">{"(" + delta + ")"}</span>;
- } else {
- delta = null;
- }
+ delta = null;
}
return <tr><td>{this.props.title + ":"}</td><td>{ts} {delta}</td></tr>;
@@ -139,23 +137,6 @@ var ConnectionInfo = React.createClass({
<tbody>
<tr key="address"><td>Address:</td><td>{address}</td></tr>
{sni}
- <TimeStamp title="Start time"
- key="start"
- t={conn.timestamp_start} />
- <TimeStamp title="TCP Setup"
- key="tcpsetup"
- t={conn.timestamp_tcp_setup}
- deltaTo={conn.timestamp_start}
- optional={true} />
- <TimeStamp title="SSL handshake"
- key="sslsetup"
- t={conn.timestamp_ssl_setup}
- deltaTo={conn.timestamp_start}
- optional={true} />
- <TimeStamp title="End time"
- key="end"
- t={conn.timestamp_end}
- deltaTo={conn.timestamp_start} />
</tbody>
</table>
);
@@ -169,13 +150,92 @@ var CertificateInfo = React.createClass({
var flow = this.props.flow;
var client_conn = flow.client_conn;
var server_conn = flow.server_conn;
+
+ var preStyle = {maxHeight: 100};
return (
<div>
{client_conn.cert ? <h4>Client Certificate</h4> : null}
- {client_conn.cert ? <pre>{client_conn.cert}</pre> : null}
+ {client_conn.cert ? <pre style={preStyle}>{client_conn.cert}</pre> : null}
{server_conn.cert ? <h4>Server Certificate</h4> : null}
- {server_conn.cert ? <pre>{server_conn.cert}</pre> : null}
+ {server_conn.cert ? <pre style={preStyle}>{server_conn.cert}</pre> : null}
+ </div>
+ );
+ }
+});
+
+var Timing = React.createClass({
+ render: function(){
+ var flow = this.props.flow;
+ var sc = flow.server_conn;
+ var cc = flow.client_conn;
+ var req = flow.request;
+ var resp = flow.response;
+
+ var timestamps = [
+ {
+ title: "Server conn. initiated",
+ t: sc.timestamp_start,
+ deltaTo: req.timestamp_start
+ }, {
+ title: "Server conn. TCP handshake",
+ t: sc.timestamp_tcp_setup,
+ deltaTo: req.timestamp_start
+ }, {
+ title: "Server conn. SSL handshake",
+ t: sc.timestamp_ssl_setup,
+ deltaTo: req.timestamp_start
+ }, {
+ title: "Client conn. established",
+ t: cc.timestamp_start,
+ deltaTo: req.timestamp_start
+ }, {
+ title: "Client conn. SSL handshake",
+ t: cc.timestamp_ssl_setup,
+ deltaTo: req.timestamp_start
+ }, {
+ title: "First request byte",
+ t: req.timestamp_start,
+ }, {
+ title: "Request complete",
+ t: req.timestamp_end,
+ deltaTo: req.timestamp_start
+ }
+ ];
+
+ if (flow.response) {
+ timestamps.push(
+ {
+ title: "First response byte",
+ t: resp.timestamp_start,
+ deltaTo: req.timestamp_start
+ }, {
+ title: "Response complete",
+ t: resp.timestamp_end,
+ deltaTo: req.timestamp_start
+ }
+ );
+ }
+
+ //Add unique key for each row.
+ timestamps.forEach(function(e){
+ e.key = e.title;
+ });
+
+ timestamps = _.sortBy(timestamps, 't');
+
+ var rows = timestamps.map(function(e){
+ return TimeStamp(e);
+ });
+
+ return (
+ <div>
+ <h4>Timing</h4>
+ <table>
+ <tbody>
+ {rows}
+ </tbody>
+ </table>
</div>
);
}
@@ -197,6 +257,8 @@ var FlowDetailConnectionInfo = React.createClass({
<CertificateInfo flow={flow}/>
+ <Timing flow={flow}/>
+
</section>
);
}
diff --git a/web/src/js/components/flowtable-columns.jsx.js b/web/src/js/components/flowtable-columns.jsx.js
index ec63b03f..88e0cf22 100644
--- a/web/src/js/components/flowtable-columns.jsx.js
+++ b/web/src/js/components/flowtable-columns.jsx.js
@@ -34,7 +34,6 @@ var IconColumn = React.createClass({
var contentType = ResponseUtils.getContentType(flow.response);
//TODO: We should assign a type to the flow somewhere else.
- var icon;
if(flow.response.code == 304) {
icon = "resource-icon-not-modified";
} else if(300 <= flow.response.code && flow.response.code < 400) {
@@ -112,9 +111,10 @@ var SizeColumn = React.createClass({
},
render: function(){
var flow = this.props.flow;
+
var total = flow.request.contentLength;
if(flow.response){
- total += flow.response.contentLength;
+ total += flow.response.contentLength || 0;
}
var size = formatSize(total);
return <td className="col-size">{size}</td>;
diff --git a/web/src/js/components/header.jsx.js b/web/src/js/components/header.jsx.js
index 92a58282..994bc759 100644
--- a/web/src/js/components/header.jsx.js
+++ b/web/src/js/components/header.jsx.js
@@ -62,12 +62,12 @@ var Header = React.createClass({
console.log("File click");
},
render: function () {
- var header = header_entries.map(function(entry){
+ var header = header_entries.map(function(entry, i){
var classes = React.addons.classSet({
active: entry == this.state.active
});
return (
- <a key={entry.title}
+ <a key={i}
href="#"
className={classes}
onClick={this.handleClick.bind(this, entry)}
diff --git a/web/src/js/utils.js b/web/src/js/utils.js
index 782618c2..95859381 100644
--- a/web/src/js/utils.js
+++ b/web/src/js/utils.js
@@ -41,7 +41,7 @@ var Key = {
var formatSize = function (bytes) {
var size = bytes;
var prefix = ["B", "KB", "MB", "GB", "TB"];
- while (size >= 1024 && prefix.length > 1) {
+ while (Math.abs(size) >= 1024 && prefix.length > 1) {
prefix.shift();
size = size / 1024;
}
@@ -50,9 +50,9 @@ var formatSize = function (bytes) {
var formatTimeDelta = function (milliseconds) {
var time = milliseconds;
- var prefix = ["ms", "s", "m", "h"];
+ var prefix = ["ms", "s", "min", "h"];
var div = [1000, 60, 60];
- while (time >= div[0] && prefix.length > 1) {
+ while (Math.abs(time) >= div[0] && prefix.length > 1) {
prefix.shift();
time = time / div.shift();
}