capture/main.go

142 lines
3 KiB
Go
Raw Normal View History

2017-11-08 00:10:54 +01:00
package main
import (
"bytes"
"compress/gzip"
2018-07-21 19:50:53 +02:00
"encoding/json"
2017-11-19 16:51:26 +01:00
"errors"
2017-11-18 13:23:36 +01:00
"fmt"
2017-11-08 00:10:54 +01:00
"io"
"io/ioutil"
2017-11-21 22:36:40 +01:00
"log"
2017-11-08 00:10:54 +01:00
"net/http"
"net/http/httputil"
2018-07-21 19:50:53 +02:00
"strconv"
"strings"
2017-11-08 00:10:54 +01:00
2017-11-21 22:36:40 +01:00
"github.com/googollee/go-socket.io"
)
type Transport struct {
http.RoundTripper
}
2018-07-27 00:49:12 +02:00
var captureID = 0
2018-07-21 19:50:53 +02:00
var captures Captures
var socket socketio.Socket
var host string
var dashboardPath string
var dashboardItemsPath string
2017-11-08 00:10:54 +01:00
func main() {
2018-07-21 19:50:53 +02:00
parseArgs()
2017-11-08 00:10:54 +01:00
2018-07-21 19:50:53 +02:00
proxy := httputil.NewSingleHostReverseProxy(args.url)
proxy.Transport = Transport{http.DefaultTransport}
2018-07-21 19:50:53 +02:00
dashboardPath = "/" + args.dashboard + "/"
dashboardItemsPath = dashboardPath + "items/"
2017-11-08 00:10:54 +01:00
http.Handle("/", getProxyHandler(proxy))
http.Handle("/socket.io/", getSocketHandler())
2018-07-21 19:50:53 +02:00
http.Handle(dashboardItemsPath, getCapturesHandler())
http.Handle(dashboardPath, getDashboardHandler())
host = "http://localhost:" + args.port
2017-11-18 13:23:36 +01:00
2018-07-21 19:50:53 +02:00
fmt.Printf("\nListening on %s", host)
fmt.Printf("\n %s/%s\n\n", host, args.dashboard)
2017-11-18 13:23:36 +01:00
2018-07-21 19:50:53 +02:00
http.ListenAndServe(":"+args.port, nil)
}
func getCapturesHandler() http.Handler {
return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
id := strings.TrimPrefix(req.URL.Path, dashboardItemsPath)
i, _ := strconv.Atoi(id)
json, _ := json.Marshal(captures[i])
res.Header().Add("Content-Type", "application/json")
res.Write([]byte(json))
})
2017-11-08 00:10:54 +01:00
}
func getProxyHandler(handler http.Handler) http.Handler {
return http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
request.Host = request.URL.Host
handler.ServeHTTP(response, request)
})
}
2017-11-08 00:10:54 +01:00
2017-11-21 22:36:40 +01:00
func getSocketHandler() http.Handler {
server, err := socketio.NewServer(nil)
if err != nil {
log.Fatal(err)
}
server.On("connection", func(so socketio.Socket) {
socket = so
emit()
})
server.On("error", func(so socketio.Socket, err error) {
log.Println("socket error:", err)
})
return server
}
func (t Transport) RoundTrip(req *http.Request) (*http.Response, error) {
2017-11-08 00:10:54 +01:00
2018-07-21 19:50:53 +02:00
reqDump, err := DumpRequest(req)
2017-11-19 16:51:26 +01:00
if err != nil {
2018-07-21 19:50:53 +02:00
return nil, err
2017-11-19 16:51:26 +01:00
}
2017-11-08 00:10:54 +01:00
2018-07-22 20:14:27 +02:00
res, err := t.RoundTripper.RoundTrip(req)
if err != nil {
return nil, errors.New("uh oh | " + err.Error() + " | " + req.URL.String())
}
2017-11-19 16:51:26 +01:00
resDump, err := DumpResponse(res)
if err != nil {
return nil, err
}
2018-07-21 19:50:53 +02:00
capture := Capture{
2018-07-27 00:49:12 +02:00
ID: captureID,
2018-07-21 19:50:53 +02:00
Path: req.URL.Path,
Method: req.Method,
Status: res.StatusCode,
Request: string(reqDump),
Response: string(resDump),
}
2018-07-27 00:49:12 +02:00
captureID++
2017-11-21 22:36:40 +01:00
captures.Add(capture)
emit()
2017-11-19 16:51:26 +01:00
return res, nil
2017-11-08 00:10:54 +01:00
}
2018-07-21 19:50:53 +02:00
func DumpRequest(req *http.Request) ([]byte, error) {
return httputil.DumpRequest(req, true)
}
func DumpResponse(res *http.Response) ([]byte, error) {
var originalBody bytes.Buffer
2018-07-22 20:14:27 +02:00
reader := io.TeeReader(res.Body, &originalBody)
if res.Header.Get("Content-Encoding") == "gzip" {
2018-07-22 20:14:27 +02:00
reader, _ = gzip.NewReader(reader)
}
2018-07-22 20:14:27 +02:00
res.Body = ioutil.NopCloser(reader)
2017-11-18 12:42:53 +01:00
resDump, err := httputil.DumpResponse(res, true)
res.Body = ioutil.NopCloser(&originalBody)
2017-11-18 12:42:53 +01:00
return resDump, err
}
2017-11-08 00:10:54 +01:00
2017-11-21 22:36:40 +01:00
func emit() {
if socket == nil {
return
2017-11-08 00:10:54 +01:00
}
2018-07-22 20:14:27 +02:00
socket.Emit("captures", captures.ToReferences(host+dashboardItemsPath))
2017-11-08 00:10:54 +01:00
}