mirror of
https://github.com/schollz/hostyoself.git
synced 2026-01-23 02:15:14 +00:00
90 lines
2.5 KiB
Go
90 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
)
|
|
|
|
// GetClientIPHelper gets the client IP using a mixture of techniques.
|
|
// This is how it is with golang at the moment.
|
|
func GetClientIPHelper(req *http.Request) (ipResult string, errResult error) {
|
|
|
|
// Try lots of ways :) Order is important.
|
|
// Try Request Headers (X-Forwarder). Client could be behind a Proxy
|
|
ip, err := getClientIPByHeaders(req)
|
|
if err == nil {
|
|
// log.Printf("debug: Found IP using Request Headers sniffing. ip: %v", ip)
|
|
return ip, nil
|
|
}
|
|
|
|
// Try by Request
|
|
ip, err = getClientIPByRequestRemoteAddr(req)
|
|
if err == nil {
|
|
// log.Printf("debug: Found IP using Request sniffing. ip: %v", ip)
|
|
return ip, nil
|
|
}
|
|
|
|
// Try Request Header ("Origin")
|
|
url, err := url.Parse(req.Header.Get("Origin"))
|
|
if err == nil {
|
|
host := url.Host
|
|
ip, _, err := net.SplitHostPort(host)
|
|
if err == nil {
|
|
// log.Printf("debug: Found IP using Header (Origin) sniffing. ip: %v", ip)
|
|
return ip, nil
|
|
}
|
|
}
|
|
|
|
err = errors.New("error: Could not find clients IP address")
|
|
return "", err
|
|
}
|
|
|
|
// getClientIPByRequest tries to get directly from the Request.
|
|
// https://blog.golang.org/context/userip/userip.go
|
|
func getClientIPByRequestRemoteAddr(req *http.Request) (ip string, err error) {
|
|
|
|
// Try via request
|
|
ip, _, err = net.SplitHostPort(req.RemoteAddr)
|
|
if err != nil {
|
|
// log.Printf("debug: Getting req.RemoteAddr %v", err)
|
|
return "", err
|
|
} else {
|
|
// log.Printf("debug: With req.RemoteAddr found IP:%v; Port: %v", ip, port)
|
|
}
|
|
|
|
userIP := net.ParseIP(ip)
|
|
if userIP == nil {
|
|
message := fmt.Sprintf("debug: Parsing IP from Request.RemoteAddr got nothing.")
|
|
// log.Printf(message)
|
|
return "", fmt.Errorf(message)
|
|
|
|
}
|
|
// log.Printf("debug: Found IP: %v", userIP)
|
|
return userIP.String(), nil
|
|
|
|
}
|
|
|
|
// getClientIPByHeaders tries to get directly from the Request Headers.
|
|
// This is only way when the client is behind a Proxy.
|
|
func getClientIPByHeaders(req *http.Request) (ip string, err error) {
|
|
|
|
// Client could be behid a Proxy, so Try Request Headers (X-Forwarder)
|
|
ipSlice := []string{}
|
|
|
|
ipSlice = append(ipSlice, req.Header.Get("X-Forwarded-For"))
|
|
ipSlice = append(ipSlice, req.Header.Get("x-forwarded-for"))
|
|
ipSlice = append(ipSlice, req.Header.Get("X-FORWARDED-FOR"))
|
|
|
|
for _, v := range ipSlice {
|
|
// log.Printf("debug: client request header check gives ip: %v", v)
|
|
if v != "" {
|
|
return v, nil
|
|
}
|
|
}
|
|
err = errors.New("error: Could not find clients IP address from the Request Headers")
|
|
return "", err
|
|
|
|
}
|