From 116ff284c32e493cbc7ae57bf881df1c5d4b5020 Mon Sep 17 00:00:00 2001 From: dudaodong Date: Wed, 27 Jul 2022 15:18:20 +0800 Subject: [PATCH] feat: net.go, add IsInternalIP, GetRequestPublicIp, EncodeUrl --- netutil/http.go | 4 ++-- netutil/net.go | 48 +++++++++++++++++++++++++++++++++++++++++ netutil/net_internal.go | 15 ++++++++++--- 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/netutil/http.go b/netutil/http.go index cbb67a3..c693592 100644 --- a/netutil/http.go +++ b/netutil/http.go @@ -6,8 +6,8 @@ // HttpGet, HttpPost, HttpDelete, HttpPut, HttpPatch, function param `url` is required. // HttpGet, HttpPost, HttpDelete, HttpPut, HttpPatch, function param `params` is variable, the order is: // params[0] is header which type should be http.Header or map[string]string, -// params[1] is query param which type should be url.Values or map[string]interface{}, when content-type header is -// multipart/form-data or application/x-www-form-urlencoded must pass url.Values params +// params[1] is query string param which type should be url.Values or map[string]string, when content-type header is +// multipart/form-data or application/x-www-form-urlencoded // params[2] is post body which type should be []byte. // params[3] is http client which type should be http.Client. package netutil diff --git a/netutil/net.go b/netutil/net.go index fc735f3..9b4aa43 100644 --- a/netutil/net.go +++ b/netutil/net.go @@ -5,6 +5,8 @@ import ( "io/ioutil" "net" "net/http" + "net/url" + "strings" ) // GetInternalIp return internal ipv4 @@ -47,6 +49,26 @@ func GetPublicIpInfo() (*PublicIpInfo, error) { return &ip, nil } +// GetRequestPublicIp return the requested public ip +func GetRequestPublicIp(req *http.Request) string { + var ip string + for _, ip = range strings.Split(req.Header.Get("X-Forwarded-For"), ",") { + if ip = strings.TrimSpace(ip); ip != "" && !IsInternalIP(net.ParseIP(ip)) { + return ip + } + } + + if ip = strings.TrimSpace(req.Header.Get("X-Real-Ip")); ip != "" && !IsInternalIP(net.ParseIP(ip)) { + return ip + } + + if ip, _, _ = net.SplitHostPort(req.RemoteAddr); !IsInternalIP(net.ParseIP(ip)) { + return ip + } + + return ip +} + // GetIps return all ipv4 of system func GetIps() []string { var ips []string @@ -122,3 +144,29 @@ func IsPublicIP(IP net.IP) bool { } return false } + +// IsInternalIP verify an ip is intranet or not +func IsInternalIP(IP net.IP) bool { + if IP.IsLoopback() { + return true + } + if ip4 := IP.To4(); ip4 != nil { + return ip4[0] == 10 || + (ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31) || + (ip4[0] == 169 && ip4[1] == 254) || + (ip4[0] == 192 && ip4[1] == 168) + } + return false +} + +// EncodeUrl encode url +func EncodeUrl(urlStr string) (string, error) { + URL, err := url.Parse(urlStr) + if err != nil { + return "", err + } + + URL.RawQuery = URL.Query().Encode() + + return URL.String(), nil +} diff --git a/netutil/net_internal.go b/netutil/net_internal.go index 11f451a..4aeb869 100644 --- a/netutil/net_internal.go +++ b/netutil/net_internal.go @@ -82,9 +82,18 @@ func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryPar if err != nil { return err } - if req.Header.Get("Content-Type") == "multipart/form-data" || req.Header.Get("Content-Type") == "application/x-www-form-urlencoded" { - formData := queryParam.(url.Values) - err = setBodyByte(req, []byte(formData.Encode())) + if strings.Contains(req.Header.Get("Content-Type"), "multipart/form-data") || req.Header.Get("Content-Type") == "application/x-www-form-urlencoded" { + if formData, ok := queryParam.(url.Values); ok { + err = setBodyByte(req, []byte(formData.Encode())) + } + if formData, ok := queryParam.(map[string]string); ok { + postData := url.Values{} + for k, v := range formData { + postData.Set(k, v) + } + err = setBodyByte(req, []byte(postData.Encode())) + } + } else { err = setBodyByte(req, body) }