diff --git a/http_server/code/src/trafficLog.jsx b/http_server/code/src/trafficLog.jsx index 37d36d0..075f216 100644 --- a/http_server/code/src/trafficLog.jsx +++ b/http_server/code/src/trafficLog.jsx @@ -1,21 +1,106 @@ import { h, render, Component } from "preact"; +/** + * @typedef {'urlParam' | 'body' | 'header'} Source; + */ + +/** + * A number, or a string containing a number. + * @typedef {{ + * body: string, + * headers: [[string, string]], + * url: URL, + * id: string, + * kv: Map, + * }} Req + */ + +/** + * @returns {Req | null} + */ +function process_msg(s) { + let obj = JSON.parse(s); + if (obj.type !== "data") return; + if (!obj.payload || !obj.payload.data || !obj.payload.data.requestReceived) + return null; + let req = obj.payload.data.requestReceived; + if (!req.rawHeaders || !req.body || !req.url) return null; + + /** + *@type {Map<[Source, string], string>} + */ + let kv = new Map(); + /** + *@type {string} + */ + let body = req.body; + /** + *@type {string} + */ + let decoded_body; + try { + decoded_body = atob(body); + } catch { + decoded_body = ""; + } + + kv.set(["body", "raw"], decoded_body); + + /** + *@type {string} + */ + let url = new URL(req.url); + + const params = new URLSearchParams(url.search); + + for (const [k, v] of params.entries()) { + kv.set(["urlParam", k], v); + } + + /** + *@type {[[string, string]]} + */ + let headers = JSON.parse(req.rawHeaders); + + for (const [k, v] of headers) { + kv.set(["header", k], v); + } + + /** + *@type {[[string, string]]} + */ + let id = req.id; + + /** + *@type Req + */ + let ret_req = { id, body: decoded_body, url, headers, kv }; + return ret_req; +} + class TrafficLog extends Component { constructor() { super(); - this.state = { content: [] }; + /** + * @type {{requests: [Req]}} + */ + this.state = { requests: [] }; } componentDidMount() { // This should also be dynamic this.connection = new WebSocket("ws://localhost:10001"); this.connection.onmessage = (msg) => { - this.setState({ content: [...this.state.content, msg.data] }); + let req = process_msg(msg.data); + if (req) { + console.log(req); + this.setState({ requests: [...this.state.requests, req] }); + } }; this.connection.onclose = this.connection.onerror = () => { var element = document.getElementById("httptoolkit-frame"); element.parentNode.removeChild(element); - } + }; } componentWillUnmount() { @@ -23,15 +108,21 @@ class TrafficLog extends Component { } render() { - const contentWithLineBreaks = this.state.content - .map((text) => { + const contentWithLineBreaks = this.state.requests.map( + ( + /** + * @type {Req} + */ + req + ) => { return ( - {text.substring(0, 100)} + {req.url.href}
); - }); + } + ); return {contentWithLineBreaks}; }