func main() { log.SetFormatter(&log.TextFormatter{}) // For TTY verbose := flag.Bool("v", false, "should every proxy request be logged to stdout") addr := flag.String("l", ":8080", "on which address should the proxy listen") flag.Parse() proxy := goproxy.NewProxyHttpServer() proxy.Verbose = *verbose if err := os.MkdirAll("db", 0755); err != nil { log.Fatal("Can't create dir", err) } logger, err := NewLogstashLogger("db") // ---------------------------------------------- if err != nil { log.Fatal("can't open log file", err) } tr := transport.Transport{Proxy: transport.ProxyFromEnvironment} // For every incoming request, override the RoundTripper to extract // connection information. Store it is session context log it after // handling the response. proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) { ctx.RoundTripper = goproxy.RoundTripperFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (resp *http.Response, err error) { ctx.UserData, resp, err = tr.DetailedRoundTrip(req) return }) logger.LogReq(req, ctx) return req, nil }) proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response { logger.LogResp(resp, ctx) return resp }) l, err := net.Listen("tcp", *addr) if err != nil { log.Fatal("listen:", err) } sl := newStoppableListener(l) ch := make(chan os.Signal) signal.Notify(ch, os.Interrupt) go func() { <-ch log.Info("Got SIGINT exiting") sl.Add(1) sl.Close() logger.Close() sl.Done() }() log.Info("Starting Proxy") http.Serve(sl, proxy) sl.Wait() log.Info("All connections closed - exit") }
func startInTheMiddle(args Args) { proxy.WaitForExitSignal() tr := transport.Transport{Proxy: transport.ProxyFromEnvironment} proxy.Start(proxy.Options{ Ip: args.Ip, Port: args.Port, ExportFolder: args.ExportFolder, Record: args.Record, OnRequest: func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) { ctx.RoundTripper = goproxy.RoundTripperFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (resp *http.Response, err error) { ctx.UserData, resp, err = tr.DetailedRoundTrip(req) return }) reqBody, err := httputil.DumpRequest(req, true) if err != nil { logger.Error(err) os.Exit(1) } r := httper.NewRequest(string(reqBody)) logger.Info(inPFunc("--> ") + r.ToString()) if !args.Record { resp, err := cacher.Find(req) if err == nil { logger.Debug("Cache HIT") return req, resp } logger.Debug("Cache MISSED") } return req, nil }, OnResponse: func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response { respBody, err := httputil.DumpResponse(resp, true) if err != nil { logger.Error(err) os.Exit(1) } r := httper.NewResponse(string(respBody)) logger.Info(outPFunc("<-- ") + r.ToString()) return resp }, }) }