package main import ( "fmt" "log" "net" "net/http" "os" "strings" ) var ( name string RemoteIPHeaders = []string{"X-Forwarded-For", "X-Real-IP"} ) func main() { hostname, err := os.Hostname() if err != nil { log.Println("got hostname error:", err) } name = hostname http.HandleFunc("/echo", echoHandler) fmt.Println("Starting server on :8080") if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal(err) } } func echoHandler(w http.ResponseWriter, r *http.Request) { clientIp := getRemoteIP(r) log.Printf("client %s connected\n\n", clientIp) fmt.Fprintf(w, "hello %s, Host %s provides services\n", clientIp, name) } func getRemoteIP(r *http.Request) string { for k, v := range r.Header { fmt.Printf("KEY=%s VALUE=%v\n", k, v) } for _, headerName := range RemoteIPHeaders { ip, valid := validateHeader(r.Header.Get(headerName)) if valid { return ip } } return RemoteIP(r) } func validateHeader(header string) (clientIP string, valid bool) { if header == "" { return "", false } items := strings.Split(header, ",") for i := len(items) - 1; i >= 0; i-- { ipStr := strings.TrimSpace(items[i]) ip := net.ParseIP(ipStr) if ip == nil { break } if i == 0 { return ipStr, true } // // X-Forwarded-For is appended by proxy // // Check IPs in reverse order and stop when find untrusted proxy // if (i == 0) || (!engine.isTrustedProxy(ip)) { // return ipStr, true // } } return "", false } func RemoteIP(r *http.Request) string { ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)) if err != nil { return "" } return ip }