diff --git a/app.go b/app.go new file mode 100644 index 0000000..231b8ce --- /dev/null +++ b/app.go @@ -0,0 +1,24 @@ +package main + +import ( + "fmt" + "net/http" +) + +func requestsHandler(w http.ResponseWriter, r *http.Request) { + fmt.Printf("we have %d requests in history when user checked", len(requestHistory)) + for _, req := range requestHistory { + fmt.Fprintln(w, req.RequestURI) + } +} + +func appServer() { + var addr string + if err := conf.Get("app_addr", &addr); err != nil { + bail(1, "error reading app_addr from config: %s", err) + } + + m := http.NewServeMux() + m.HandleFunc("/requests", requestsHandler) + http.ListenAndServe(addr, m) +} diff --git a/history.go b/history.go new file mode 100644 index 0000000..4b2ad02 --- /dev/null +++ b/history.go @@ -0,0 +1,25 @@ +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "net/http" +) + +var lastId int + +func freezeRequest(r *http.Request) error { + var buf bytes.Buffer + if _, err := buf.ReadFrom(r.Body); err != nil { + return fmt.Errorf("unable to clone request: error reading original request body: %s", err) + } + + if err := r.Body.Close(); err != nil { + return fmt.Errorf("unable to clone request: cannot close original request body: %s", err) + } + r.Body = ioutil.NopCloser(&buf) + return nil +} + +var requestHistory []http.Request diff --git a/main.go b/main.go index 5084339..56dc884 100644 --- a/main.go +++ b/main.go @@ -12,10 +12,17 @@ import ( "unicode" ) -var client = new(http.Client) +var ( + client = new(http.Client) + conf *moon.Doc +) func httpHandler(w http.ResponseWriter, r *http.Request) { fmt.Println("from:", r.RemoteAddr) + if err := freezeRequest(r); err != nil { + fmt.Printf("error freezing request: %s\n", err) + return + } b, err := httputil.DumpRequest(r, true) if err != nil { fmt.Printf("error dumping request: %s\n", err) @@ -23,6 +30,7 @@ func httpHandler(w http.ResponseWriter, r *http.Request) { } os.Stdout.Write(b) + requestURI := r.RequestURI r.RequestURI = "" r.URL.Scheme = strings.Map(unicode.ToLower, r.URL.Scheme) @@ -44,6 +52,12 @@ func httpHandler(w http.ResponseWriter, r *http.Request) { if _, err := io.Copy(w, res.Body); err != nil { fmt.Printf("error copying body: %s\n", err) } + + if requestHistory == nil { + requestHistory = make([]http.Request, 0, 100) + } + r.RequestURI = requestURI + requestHistory = append(requestHistory, *r) } func bail(status int, t string, args ...interface{}) { @@ -55,21 +69,28 @@ func bail(status int, t string, args ...interface{}) { os.Exit(status) } +func proxyListener() { + var addr string + if err := conf.Get("proxy_addr", &addr); err != nil { + bail(1, "error reading proxy_addr from config: %s", err) + } + + m := http.NewServeMux() + m.HandleFunc("/", httpHandler) + http.ListenAndServe(addr, m) +} + func main() { var configPath string flag.StringVar(&configPath, "config", "./prox_config.moon", "path to configuration file") flag.Parse() - conf, err := moon.ReadFile(configPath) + var err error + conf, err = moon.ReadFile(configPath) if err != nil { bail(1, "unable to read config: %s", err) } - var addr string - if err := conf.Get("proxy_addr", &addr); err != nil { - bail(1, "error reading proxy_addr from config: %s", err) - } - - http.HandleFunc("/", httpHandler) - http.ListenAndServe(addr, nil) + go appServer() + proxyListener() } diff --git a/prox_config.moon b/prox_config.moon index 5d8bbad..72a875d 100644 --- a/prox_config.moon +++ b/prox_config.moon @@ -1,3 +1,7 @@ # address for web browsers to use in their proxy settings. Browsers send their # normal traffic to this port to be proxied. proxy_addr: ":8080" + +# http address for the user app. Users navigate to this address to view their +# prox history. +app_addr: ":9000"