diff options
Diffstat (limited to 'web/src/js/components/flowdetail.jsx.js')
-rw-r--r-- | web/src/js/components/flowdetail.jsx.js | 123 |
1 files changed, 117 insertions, 6 deletions
diff --git a/web/src/js/components/flowdetail.jsx.js b/web/src/js/components/flowdetail.jsx.js index e5fe37a0..7c984193 100644 --- a/web/src/js/components/flowdetail.jsx.js +++ b/web/src/js/components/flowdetail.jsx.js @@ -3,7 +3,7 @@ var FlowDetailNav = React.createClass({ render: function(){ - var items = ["request", "response", "details"].map(function(e){ + var items = this.props.tabs.map(function(e){ var str = e.charAt(0).toUpperCase() + e.slice(1); var className = this.props.active === e ? "active" : ""; var onClick = function(){ @@ -28,11 +28,11 @@ var Headers = React.createClass({ var rows = this.props.message.headers.map(function(header){ return ( <tr> - <td className="header-name">{header[0]}</td> + <td className="header-name">{header[0]+":"}</td> <td className="header-value">{header[1]}</td> </tr> ); - }) + }); return ( <table className="header-table"> <tbody> @@ -41,7 +41,7 @@ var Headers = React.createClass({ </table> ); } -}) +}); var FlowDetailRequest = React.createClass({ render: function(){ @@ -99,9 +99,106 @@ var FlowDetailResponse = React.createClass({ } }); +var TimeStamp = React.createClass({ + render: function() { + var ts, delta; + + if(!this.props.t && this.props.optional){ + //should be return null, but that triggers a React bug. + return <tr></tr>; + } else if (!this.props.t){ + ts = "active"; + } 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; + } + } + + return <tr><td>{this.props.title + ":"}</td><td>{ts} {delta}</td></tr>; + } +}); + +var ConnectionInfo = React.createClass({ + + render: function() { + var conn = this.props.conn; + var address = conn.address.address.join(":"); + + var sni = <tr key="sni"></tr>; //should be null, but that triggers a React bug. + if(conn.sni){ + sni = <tr key="sni"><td><abbr title="TLS Server Name Indication">TLS SNI:</abbr></td><td>{conn.sni}</td></tr>; + } + return ( + <table className="connection-table"> + <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> + ); + } +}); + +var CertificateInfo = React.createClass({ + render: function(){ + //TODO: We should fetch human-readable certificate representation + // from the server + var flow = this.props.flow; + var client_conn = flow.client_conn; + var server_conn = flow.server_conn; + return ( + <div> + {client_conn.cert ? <h4>Client Certificate</h4> : null} + {client_conn.cert ? <pre>{client_conn.cert}</pre> : null} + + {server_conn.cert ? <h4>Server Certificate</h4> : null} + {server_conn.cert ? <pre>{server_conn.cert}</pre> : null} + </div> + ); + } +}); + var FlowDetailConnectionInfo = React.createClass({ render: function(){ - return <section>details</section>; + var flow = this.props.flow; + var client_conn = flow.client_conn; + var server_conn = flow.server_conn; + return ( + <section> + + <h4>Client Connection</h4> + <ConnectionInfo conn={client_conn}/> + + <h4>Server Connection</h4> + <ConnectionInfo conn={server_conn}/> + + <CertificateInfo flow={flow}/> + + </section> + ); } }); @@ -112,13 +209,27 @@ var tabs = { }; var FlowDetail = React.createClass({ + getDefaultProps: function(){ + return { + tabs: ["request","response", "details"] + }; + }, mixins: [StickyHeadMixin], + nextTab: function(i) { + var currentIndex = this.props.tabs.indexOf(this.props.active); + // JS modulo operator doesn't correct negative numbers, make sure that we are positive. + var nextIndex = (currentIndex + i + this.props.tabs.length) % this.props.tabs.length; + this.props.selectTab(this.props.tabs[nextIndex]); + }, render: function(){ var flow = JSON.stringify(this.props.flow, null, 2); var Tab = tabs[this.props.active]; return ( <div className="flow-detail" onScroll={this.adjustHead}> - <FlowDetailNav ref="head" active={this.props.active} selectTab={this.props.selectTab}/> + <FlowDetailNav ref="head" + tabs={this.props.tabs} + active={this.props.active} + selectTab={this.props.selectTab}/> <Tab flow={this.props.flow}/> </div> ); |