echo-server/.proxy.go

60 lines
1.3 KiB
Go
Executable File

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")
}