capture/main.go

93 lines
2 KiB
Go
Raw Normal View History

2017-11-08 00:10:54 +01:00
package main
import (
"bytes"
"compress/gzip"
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"
"net/http"
"net/http/httputil"
)
type Capture map[string]interface{}
2017-11-08 00:10:54 +01:00
var captures []Capture
var maxCaptures int
type Transport struct {
http.RoundTripper
}
2017-11-08 00:10:54 +01:00
func main() {
2017-11-18 12:05:41 +01:00
targetURL, proxyPort, dashboard, maxCaptrs := parseFlags()
maxCaptures = maxCaptrs
2017-11-08 00:10:54 +01:00
2017-11-18 12:05:41 +01:00
proxy := httputil.NewSingleHostReverseProxy(targetURL)
proxy.Transport = Transport{http.DefaultTransport}
2017-11-08 00:10:54 +01:00
http.Handle("/", getProxyHandler(proxy))
http.Handle("/socket.io/", getSocketHandler())
2017-11-18 12:05:41 +01:00
http.Handle("/"+dashboard+"/", getDashboardHandler())
2017-11-18 13:23:36 +01:00
fmt.Printf("\nListening on http://localhost:%s\n\n", proxyPort)
2017-11-18 12:05:41 +01:00
http.ListenAndServe(":"+proxyPort, nil)
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
func (t Transport) RoundTrip(req *http.Request) (*http.Response, error) {
2017-11-19 16:51:26 +01:00
reqDump, err := httputil.DumpRequest(req, true)
if err != nil {
return nil, err
}
2017-11-08 00:10:54 +01:00
2017-11-18 12:42:53 +01:00
res, err := t.RoundTripper.RoundTrip(req)
2017-11-19 16:51:26 +01:00
if err != nil {
return nil, errors.New(err.Error() + ": " + req.URL.String())
}
2017-11-08 00:10:54 +01:00
2017-11-19 16:51:26 +01:00
resDump, err := DumpResponse(res)
if err != nil {
return nil, err
}
capture := Capture{
"url": req.URL.Path,
"method": req.Method,
"status": res.StatusCode,
"request": string(reqDump),
"response": string(resDump),
}
save(capture)
2017-11-19 16:51:26 +01:00
return res, nil
2017-11-08 00:10:54 +01:00
}
func DumpResponse(res *http.Response) ([]byte, error) {
var originalBody bytes.Buffer
res.Body = ioutil.NopCloser(io.TeeReader(res.Body, &originalBody))
if res.Header.Get("Content-Encoding") == "gzip" {
res.Body, _ = gzip.NewReader(res.Body)
}
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
func save(capture Capture) {
2017-11-08 00:10:54 +01:00
captures = append([]Capture{capture}, captures...)
if len(captures) > maxCaptures {
captures = captures[:len(captures)-1]
}
emit(captures)
}