89 lines
1.6 KiB
Go
89 lines
1.6 KiB
Go
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
|
|
}
|