-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Open
Labels
Description
The Go documentation states the following on http.Request.RemoteAddr
:
The HTTP server in this package sets RemoteAddr to an "IP:port" address before invoking a handler.
Therefore, you could expect that a code like this is correct:
package main
import (
"fmt"
"net"
"net/http"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
)
func main() {
r := chi.NewMux()
r.Use(middleware.RealIP)
r.Get("/test", func(rw http.ResponseWriter, r *http.Request) {
host, port, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
fmt.Fprintf(rw, "Error: %v\n", err)
} else {
fmt.Fprintf(rw, "Host: %s\nPort: %s\n", host, port)
}
})
http.ListenAndServe(":8000", r)
}
However, the RealIP middleware is just copying the X-Forwarded-For
value into r.RemoteAddr
, which usually does not contain a port, making the code fail:
[dirbaio@mars]$ curl localhost:8000/test
Host: ::1
Port: 40188
[dirbaio@mars]$ curl localhost:8000/test -H 'X-Forwarded-For: 1.2.3.4'
Error: address 1.2.3.4: missing port in address
[dirbaio@mars]$ curl localhost:8000/test -H 'X-Forwarded-For: ::1'
Error: address ::1: too many colons in address
Perhaps RealIP should try to parse X-Forwarded-For
for a host:port
, and if it isn't, add a port? Maybe 0
to denote the port is unknown, like 1.2.3.4
-> 1.2.3.4:0
?
This is particularly frustrating with IPv6 addresses because they have colons but they're not the host:port
colon, making it hard to parse the RemoteAddr in user code.
gucki