package main import ( "flag" "io" "log" "net" "net/http" "net/http/httputil" "time" ) func main() { port := flag.String("p", "8889", "port to bind to") flag.Parse() log.Printf("listening on %s", *port) if err := http.ListenAndServe(":"+*port, http.HandlerFunc(echo)); err != nil { panic(err) } } func echo(w http.ResponseWriter, r *http.Request) { b, _ := httputil.DumpRequest(r, true) log.Printf("DUMP:\n%s", b) u := *r.URL u.Path = "" proxy := httputil.NewSingleHostReverseProxy(&u) proxy.ServeHTTP(w, r) } func echo2(w http.ResponseWriter, r *http.Request) { log.Printf("echo start") dest_conn, err := net.DialTimeout("tcp", r.Host, 10*time.Second) if err != nil { http.Error(w, err.Error(), http.StatusServiceUnavailable) return } log.Printf("echo dialed") hijacker, ok := w.(http.Hijacker) if !ok { http.Error(w, "Hijacking not supported", http.StatusInternalServerError) return } client_conn, _, err := hijacker.Hijack() if err != nil { http.Error(w, err.Error(), http.StatusServiceUnavailable) } log.Printf("echo hijacked") transfer := func(destination io.WriteCloser, source io.ReadCloser) { defer destination.Close() defer source.Close() io.Copy(destination, source) } go transfer(dest_conn, client_conn) go transfer(client_conn, dest_conn) log.Printf("echo transferred") }