Skip to content

Commit

Permalink
web inspection first release
Browse files Browse the repository at this point in the history
  • Loading branch information
thebinary committed Jul 26, 2020
1 parent edb5e87 commit ee4834b
Show file tree
Hide file tree
Showing 8 changed files with 261 additions and 45 deletions.
67 changes: 45 additions & 22 deletions inspector.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ func init() {
DefaultInspectTransport = &InspectTransport{}
}

//NewInspectTransport returns a new instance of InspectTransport
//NewInspectTransport returns a new instance of InspectTranspor
//TODO: optimized transport
func NewInspectTransport(responseHeaders, responseBody, requestHeaders bool) (transport *InspectTransport) {
return &InspectTransport{
ResponseHeaders: responseHeaders,
Expand All @@ -38,12 +39,26 @@ func (i *InspectTransport) RoundTrip(request *http.Request) (response *http.Resp
response, err = http.DefaultTransport.RoundTrip(request)
elapsed := time.Since(start)

//Get Remote originating IP
var remoteIP string
if r := request.Header.Get("X-Real-Ip"); r != "" {
remoteIP = r
} else {
remoteIP = request.RemoteAddr
}

// Extract request headers
rHeaders := map[string][]string{}
for k, v := range request.Header {
rHeaders[k] = v
}

//Extract response headers
respHeaders := map[string][]string{}
for k, v := range response.Header {
respHeaders[k] = v
}

// default loggin
// eg: 2020/07/25 18:30:26 1.1.1.1 4.046181ms GET "/test" HTTP/1.1 200 839 "" "curl/7.54.0"
accessLog := fmt.Sprintf("%s %-12s %s \"%s\" HTTP/%d.%d %d %d \"%s\" \"%s\"",
Expand All @@ -52,42 +67,50 @@ func (i *InspectTransport) RoundTrip(request *http.Request) (response *http.Resp
response.StatusCode, response.ContentLength,
request.Referer(), request.UserAgent())
log.Println(accessLog)

if i.WebChannel != nil {
go func() {
i.WebChannel <- webLog{
Timestamp: time.Now().Unix(),
ResponseTime: elapsed.String(),
Method: request.Method,
Path: request.URL.Path,
HTTPVersion: fmt.Sprintf("%d.%d", request.ProtoMajor, request.ProtoMinor),
StatusCode: response.StatusCode,
ResponseContentLength: response.ContentLength,
Referer: request.Referer(),
UserAgent: request.UserAgent(),
}
}()
w := webLog{
Timestamp: time.Now().Unix(),
ResponseTime: elapsed.String(),
Method: request.Method,
Path: request.URL.Path,
HTTPVersion: fmt.Sprintf("%d.%d", request.ProtoMajor, request.ProtoMinor),
StatusCode: response.StatusCode,
Status: response.Status,
ResponseContentLength: response.ContentLength,
Referer: request.Referer(),
UserAgent: request.UserAgent(),
RemoteIP: remoteIP,
RequestHeaders: rHeaders,
ResponseHeaders: respHeaders,
}

if i.RequestHeaders {
if req, err := httputil.DumpRequestOut(request, false); err == nil {
if req, err := httputil.DumpRequestOut(request, false); err == nil {
reqStr := string(req)
if i.RequestHeaders {
fmt.Println("")
fmt.Println("---- REQUEST ----")
fmt.Println(string(req))
fmt.Println(reqStr)
fmt.Println("-----------------")
fmt.Println("")
}
}

if i.ResponseHeaders || i.ResponseBody {
if resp, err := httputil.DumpResponse(response, i.ResponseBody); err == nil {
if resp, err := httputil.DumpResponse(response, true); err == nil {
respStr := string(resp)
//TODO: [FIX] handle headerOnly or bodyOnly cases for logging
if i.ResponseHeaders || i.ResponseBody {
fmt.Println("")
fmt.Println("---- RESPONSE ----")
fmt.Println(string(resp))
fmt.Println(respStr)
fmt.Println("------------------")
fmt.Println("")
}
}

if i.WebChannel != nil {
go func() {
i.WebChannel <- w
}()
}

return response, err
}
8 changes: 7 additions & 1 deletion inspector/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^5.14.0",
"@fortawesome/fontawesome-svg-core": "^1.2.30",
"@fortawesome/free-solid-svg-icons": "^5.14.0",
"@fortawesome/vue-fontawesome": "^0.1.10",
"buefy": "^0.8.20",
"bulma": "^0.9.0",
"core-js": "^3.6.5",
"vue": "^2.6.11"
},
Expand Down Expand Up @@ -39,4 +45,4 @@
"last 2 versions",
"not dead"
]
}
}
29 changes: 26 additions & 3 deletions inspector/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
<template>
<div id="app">
<Logger />
<nav id="navbar" class="navbar">
<div class="navbar-brand">
<div class="navbar-item has-text-light">
<b-icon id="app-title-icon" icon="binoculars"></b-icon>
<p id="app-title" class="is-size-6 has-text-weight-bold">
Ported Inspector
</p>
</div>
</div>
</nav>
<div id="app-container">
<Logger />
</div>
</div>
</template>

Expand All @@ -21,7 +33,18 @@ export default {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
margin-left: 20px;
margin-top: 20px;
//margin: 20px;
}
#navbar {
background-color: #236993;
}
#app-container {
margin: 20px;
}
#app-title-icon {
margin-right: 0.3em;
}
.primary-text {
color: #236993;
}
</style>
21 changes: 21 additions & 0 deletions inspector/src/components/Headers.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template>
<div>
<div v-for="(value, key) in data" :key="key">
<span class="primary-text has-text-weight-bold"> {{ key }}</span>
<span class="">: {{ value[0] }}</span>
</div>
</div>
</template>

<script>
export default {
name: "Headers",
props: {
data: {
type: Object,
},
},
};
</script>

<style></style>
85 changes: 80 additions & 5 deletions inspector/src/components/Logger.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,78 @@
<b v-else class="inactive">Inactive</b>
</div>
<br />
<div class="log" v-for="item in logs" v-bind:key="item">{{ item }}</div>
<b-collapse
class="card"
animation="slide"
v-for="item in logs"
:key="item.id"
:open="item.isOpen == true"
@open="item.isOpen = true"
>
<div slot="trigger" slot-scope="props" class="card-header" role="button">
<div class="card-header-title">
<div class="r-ip">{{ item.ip }}</div>
<div class="r-method">
<span class="method" :class="item.m">{{ item.m + " " }}</span>
<span>{{ item.p }}</span>
</div>
<div class="r-status">{{ item.s }}</div>
<div class="r-cLength">{{ item.rpl }} B</div>
<div class="r-rtt">{{ item.rtt }}</div>
</div>
<a class="card-header-icon">
<b-icon
:icon="props.open ? 'arrow-down' : 'arrow-up'"
class="is-size-7 primary-text"
>
</b-icon>
</a>
</div>
<div class="card-content">
<p class="is-uppercase has-text-weight-bold is-size-6">
Request Headers
</p>
<Headers :data="item.rh" />
<br />
<p class="is-uppercase has-text-weight-bold is-size-6">
Response Headers
</p>
<Headers :data="item.rph" />
</div>
</b-collapse>
</div>
</template>

<script>
import Headers from "./Headers.vue";
const maxRecords = 50;
const webSocketURL = "ws://" + window.location.host + "/porter/stream";
export default {
name: "Logger",
components: {
Headers,
},
data: function() {
return {
connected: false,
isOpen: -1,
logs: [],
stream: null,
};
},
created: function() {
this.stream = new WebSocket(
"ws://" + window.location.host + "/porter/stream"
);
this.stream = new WebSocket(webSocketURL);
this.stream.onopen = function() {
this.connected = true;
console.log("Connected");
}.bind(this);
this.stream.onmessage = function(event) {
let data = JSON.parse(event.data);
let d = JSON.parse(event.data);
let data = JSON.parse(d);
data.id = data.t + "-" + data.rtt;
data.isOpen = false;
//this.logs.unshift(data);
this.logs.push(data);
if (this.logs.length > maxRecords) {
Expand All @@ -55,4 +100,34 @@ export default {
.inactive {
color: #ff0000d6;
}
.method {
font-weight: bold;
}
.GET {
color: green;
}
.POST {
color: orange;
}
.PATCH {
color: darkorange;
}
.DELETE {
color: red;
}
.request-time {
color: darkgray;
}
.r-method {
flex-grow: 8;
}
.r-ip {
flex-grow: 1;
}
.r-status {
flex-grow: 1;
}
.r-cLength {
flex-grow: 1;
}
</style>
28 changes: 23 additions & 5 deletions inspector/src/main.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
import Vue from 'vue'
import App from './App.vue'
import Vue from "vue";
import App from "./App.vue";
import Buefy from "buefy";
import "buefy/dist/buefy.css";

Vue.config.productionTip = false
import { library } from "@fortawesome/fontawesome-svg-core";
import {
faBinoculars,
faArrowUp,
faArrowDown,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";

library.add(faBinoculars, faArrowUp, faArrowDown);
Vue.component("vue-fontawesome", FontAwesomeIcon);

Vue.use(Buefy, {
defaultIconComponent: "vue-fontawesome",
defaultIconPack: "fas",
});
Vue.component("fai", FontAwesomeIcon);
Vue.config.productionTip = false;

new Vue({
render: h => h(App),
}).$mount('#app')
render: (h) => h(App),
}).$mount("#app");
Loading

0 comments on commit ee4834b

Please sign in to comment.