Proxy request host is overwritten by the real request

I am trying to serve a proxy like this:


import (
	"net/http"
)

func main() {
	http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		println(r.Host)
	}))
}

and calling it with curl curl -k -x http://localhost:8080 http://golang.org/ I get golang.org printed out. Why I do not get the proxy hostname localhost? is that a bug or limitation with the http proxy?

I execute this and receive the correct host, “localhost”

bash-3.2# go run main.go
localhost:8080
localhost:8080
localhost:8080
localhost:8080

Your code is not a proxy but a simple handler on default route /. You can’t get the server address from your remote request but you can write a simple service for this. See a dummy example below.

package main

import (
	"net/http"
)

var s string

func main() {
	ip := "127.0.0.1"
	port := "8080"
	s = ip + ":" + port

	http.ListenAndServe(s, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		println(ip)
	}))
}

Did you call curl -k -x http://localhost:8080 http://golang.org/?
Which golang version and OS are you using?

The IP of the server will change based on the request so I need a way to get the server binded IP.

when you send “curl -k -x” with this options:

-x, --proxy [PROTOCOL://]HOST[:PORT]  Use proxy on given port

so return the “http://golang.org”

Ok, that was an example. You can get the server address from system but not from the request. From remote request you can only obtain the remote (requester) ip, if you want r.Host from your first code.

I should use LocalAddrContextKey but looks like there is a known bug with setting it https://github.com/golang/go/issues/18686
A workaround is to hijack the http.ResponseWriter ex:

package main

import (
	"net/http"
)

func main() {
	http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		println(r.Host)
	
		hij, ok := w.(http.Hijacker)
		if !ok {
			panic("http server does not support hijacker")
		}
	
		clientConn, _, err := hij.Hijack()
		if err != nil {
			panic(err.Error())
		}
	
		println(clientConn.LocalAddr().String())

    }))
}

do you tried this?

Yes, it is missing some functionalities I needed. I found https://github.com/nadoo/glider to be much better…

1 Like

Nice, It seems to be an interesting library, I’ll take a look later.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.