| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package util |
| |
| import ( |
| "context" |
| "net" |
| "net/http" |
| "net/url" |
| "strconv" |
| "strings" |
| ) |
| |
| type IPPort struct { |
| IP string |
| Port uint16 |
| } |
| |
| func GetIPFromContext(ctx context.Context) string { |
| v, ok := FromContext(ctx, "x-remote-ip").(string) |
| if !ok { |
| return "UNKNOWN" |
| } |
| return v |
| } |
| |
| func ParseEndpoint(ep string) (string, error) { |
| u, err := url.Parse(ep) |
| if err != nil { |
| return "", err |
| } |
| return u.Host, nil |
| } |
| |
| func ParseIPPort(addr string) IPPort { |
| idx := strings.LastIndex(addr, ":") |
| if idx == -1 { |
| return IPPort{addr, 0} |
| } |
| p, _ := strconv.Atoi(addr[idx+1:]) |
| return IPPort{addr[:idx], uint16(p)} |
| } |
| |
| func GetRealIP(r *http.Request) string { |
| for _, h := range [2]string{"X-Forwarded-For", "X-Real-Ip"} { |
| addresses := strings.Split(r.Header.Get(h), ",") |
| for _, ip := range addresses { |
| ip = strings.TrimSpace(ip) |
| realIP := net.ParseIP(ip) |
| if !realIP.IsGlobalUnicast() { |
| continue |
| } |
| return ip |
| } |
| } |
| return strings.Split(r.RemoteAddr, ":")[0] |
| } |
| |
| func InetNtoIP(ipnr uint32) net.IP { |
| return net.IPv4(byte(ipnr>>24), byte(ipnr>>16), byte(ipnr>>8), byte(ipnr)) |
| } |
| |
| func InetNtoa(ipnr uint32) string { |
| return InetNtoIP(ipnr).String() |
| } |
| |
| func InetAton(ip string) (ipnr uint32) { |
| bytes := net.ParseIP(ip).To4() |
| for i := 0; i < len(bytes); i++ { |
| ipnr |= uint32(bytes[i]) |
| if i < 3 { |
| ipnr <<= 8 |
| } |
| } |
| return |
| } |
| |
| func ParseRequestURL(r *http.Request) string { |
| if len(r.URL.Scheme) > 0 { |
| return r.URL.String() |
| } |
| |
| scheme := "https://" |
| if r.TLS == nil { |
| scheme = "http://" |
| } |
| return scheme + r.Host + r.RequestURI |
| } |