mirror of
				https://github.com/gravitl/netmaker.git
				synced 2025-10-31 20:22:44 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			81 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			81 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package controller
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"net"
 | |
| 	"net/http"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/gorilla/mux"
 | |
| 
 | |
| 	"github.com/gravitl/netmaker/netclient/ncutils"
 | |
| )
 | |
| 
 | |
| func ipHandlers(r *mux.Router) {
 | |
| 	r.HandleFunc("/api/getip", http.HandlerFunc(getPublicIP)).Methods(http.MethodGet)
 | |
| }
 | |
| 
 | |
| // swagger:route GET /api/getip ipservice getPublicIP
 | |
| //
 | |
| // Get the current public IP address.
 | |
| //
 | |
| //			Schemes: https
 | |
| //
 | |
| //			Security:
 | |
| //	  		oauth
 | |
| //
 | |
| //			Responses:
 | |
| //				200: byteArrayResponse
 | |
| func getPublicIP(w http.ResponseWriter, r *http.Request) {
 | |
| 	r.Header.Set("Connection", "close")
 | |
| 	ip, err := parseIP(r)
 | |
| 	if err != nil {
 | |
| 		w.WriteHeader(400)
 | |
| 		switch {
 | |
| 		case ip != "":
 | |
| 			_, _ = w.Write([]byte("ip is invalid: " + ip))
 | |
| 		case ip == "":
 | |
| 			_, _ = w.Write([]byte("no ip found"))
 | |
| 		default:
 | |
| 			fmt.Println(err)
 | |
| 		}
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	w.WriteHeader(200)
 | |
| 	_, _ = w.Write([]byte(ip))
 | |
| }
 | |
| 
 | |
| func parseIP(r *http.Request) (string, error) {
 | |
| 	// Get Public IP from header
 | |
| 	ip := r.Header.Get("X-REAL-IP")
 | |
| 	ipnet := net.ParseIP(ip)
 | |
| 	if ipnet != nil && !ncutils.IpIsPrivate(ipnet) {
 | |
| 		return ip, nil
 | |
| 	}
 | |
| 
 | |
| 	// If above fails, get Public IP from other header instead
 | |
| 	forwardips := r.Header.Get("X-FORWARDED-FOR")
 | |
| 	iplist := strings.Split(forwardips, ",")
 | |
| 	for _, ip := range iplist {
 | |
| 		ipnet := net.ParseIP(ip)
 | |
| 		if ipnet != nil && !ncutils.IpIsPrivate(ipnet) {
 | |
| 			return ip, nil
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// If above also fails, get Public IP from Remote Address of request
 | |
| 	ip, _, err := net.SplitHostPort(r.RemoteAddr)
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 	ipnet = net.ParseIP(ip)
 | |
| 	if ipnet != nil {
 | |
| 		if ncutils.IpIsPrivate(ipnet) {
 | |
| 			return ip, fmt.Errorf("ip is a private address")
 | |
| 		}
 | |
| 		return ip, nil
 | |
| 	}
 | |
| 	return "", fmt.Errorf("no ip found")
 | |
| }
 | 
