func main() { 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 := NewLogger("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.Println("Got SIGINT exiting") sl.Add(1) sl.Close() logger.Close() sl.Done() }() log.Println("Starting Proxy") http.Serve(sl, proxy) sl.Wait() log.Println("All connections closed - exit") }
func main() { cwd, _ := os.Getwd() 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") cacheDir := flag.String("p", cwd, "cache directory, by default the working directory") flag.Parse() proxy := goproxy.NewProxyHttpServer() proxy.Verbose = *verbose store, err := NewPkgStore(*cacheDir) if err != nil { log.Fatal(fmt.Printf("Could not create package cache directory: %s", *cacheDir)) } else { log.Printf("Using cache directory: %s", *cacheDir) } tr := transport.Transport{Proxy: transport.ProxyFromEnvironment} r := regexp.MustCompile(`/([^/]+)/os/(i686|x86_64)/(.+\.pkg\.tar.+)`) proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) { uri := req.URL.RequestURI() if r.MatchString(uri) == true { pkgInfo := r.FindStringSubmatch(uri) pkgFile := store.NewPkg(pkgInfo[1], pkgInfo[2], pkgInfo[3]) log.Printf("Request: %s/%s/%s", pkgFile.repo, pkgFile.arch, pkgFile.fname) if store.HasPkg(pkgFile) { log.Printf("Serving cached package: %s/%s/%s", pkgFile.repo, pkgFile.arch, pkgFile.fname) return req, NewCachedResponse(req, store, pkgFile) } else { ctx.RoundTripper = goproxy.RoundTripperFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (resp *http.Response, err error) { resp, err = tr.RoundTrip(req) ctx.UserData = pkgFile return }) } } return req, nil }) proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response { if ctx.UserData != nil { store.PutPkg(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.Println("Got SIGINT exiting") sl.Add(1) sl.Close() sl.Done() }() log.Println("Starting Proxy") http.Serve(sl, proxy) sl.Wait() log.Println("All connections closed - exit") }