Golang ReverseProxy not working

I do not know why this reverse proxy does not work. I have seen several examples, and I cannot find anything wrong with that.

package main import ( "log" "net/url" "net/http" "net/http/httputil" ) func report(r *http.Request){ log.Print("URL: " + r.URL.Path) log.Print("Scheme: " + r.URL.Scheme) log.Print("Host: " + r.URL.Host) //r.URL.Scheme = "http" //r.URL.Host = "stackoverflow.com" //r.Header.Set("Host", "stackoverflow.com") //log.Print("Header Host: " + r.Header.Get("Host")) } func main() { proxy := httputil.NewSingleHostReverseProxy( &url.URL{Scheme:"http",Host:"myrealserver.com"}) proxy.Director = report // http.Handle("/", proxy) error := http.ListenAndServe("mylocalhost.com:8080", proxy) if(error != nil) { log.Fatal(error) } } 

He writes:

 2014/04/18 21:32:50 URL: /arg/es 2014/04/18 21:32:50 Scheme: 2014/04/18 21:32:50 Host: 2014/04/18 21:32:50 http: proxy error: unsupported protocol scheme "" 2014/04/18 21:32:51 URL: /favicon.ico 2014/04/18 21:32:51 Scheme: 2014/04/18 21:32:51 Host: 2014/04/18 21:32:51 http: proxy error: unsupported protocol scheme "" 

If I uncomment the line that overrides the schema, the error message becomes:

 2014/04/18 21:38:05 http: proxy error: http: no Host in request URL 

If I uncomment the line that redefines the host, then the target server will become stackoverflow.com (I mean, it never uses "myrealserver.com").

If I ask mylocalhost.com:8080/somepath (or even /), then I get 404 from Stackoverflow, regardless of whether stackoverflow.com/somepath exists or not. It says:

 Couldn't find mylocalhost.com:8080 The Q&A site mylocalhost.com:8080 doesn't seem to exist... yet 

It does not translate the host header automatically.

If then I uncomment the line that sets (and the other that prints) the host header. Then I can read "stackoverflow.com" in the journal, but I still get the same 404-page reporting that I am trying to access "mylocalhost.com".

I am using go1.2.1 linux/amd64

How should I make the program work as a proxy?

+8
go proxy
source share
1 answer

Thanks to Alex from the Golang Nuts, I now have an answer.

Here's what Alex said:

You just need to set http.Request.Host [and the scheme] in the Director to get it working: http://play.golang.org/p/I17ZSM6LQb

If you read the source of SingleHostReverseProxy ( http://golang.org/src/pkg/net/http/httputil/reverseproxy.go#L61 ), this sets up its own Director, which you override. So you need to redefine what it already does, plus an additional host change.

In any case, this did not solve the header problem: the target server still received "localhost: 8080" as the HTTP host name, so I did it without the ReverseProxy package, only with http and roundTripper, plus a helper function that copies everything headers:

 package main import ( "flag" "fmt" "os" "log" "net/http" "io/ioutil" ) var target *string func main() { target = flag.String("target", "http://stackoverflow.com", "target URL for reverse proxy") flag.Parse() http.HandleFunc("/", report) log.Fatal(http.ListenAndServe("127.0.0.1:8080", nil)) } func report(w http.ResponseWriter, r *http.Request){ uri := *target+r.RequestURI fmt.Println(r.Method + ": " + uri) if r.Method == "POST" { body, err := ioutil.ReadAll(r.Body) fatal(err) fmt.Printf("Body: %v\n", string(body)); } rr, err := http.NewRequest(r.Method, uri, r.Body) fatal(err) copyHeader(r.Header, &rr.Header) // Create a client and query the target var transport http.Transport resp, err := transport.RoundTrip(rr) fatal(err) fmt.Printf("Resp-Headers: %v\n", resp.Header); defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) fatal(err) dH := w.Header() copyHeader(resp.Header, &dH) dH.Add("Requested-Host", rr.Host) w.Write(body) } func fatal(err error) { if err != nil { log.Fatal(err) os.Exit(1) } } func copyHeader(source http.Header, dest *http.Header){ for n, v := range source { for _, vv := range v { dest.Add(n, vv) } } } 

Now I can see StackOverflow or any other site as it should be.
However, I am still working on POST calls, so this is work in progress.

+9
source share

All Articles