ipFromRequest detects the IP address for this transaction. * `headers` - the specific HTTP headers to trust * `r` - the incoming HTTP request * `customIP` - whether to allow the IP to be pulled from query parameters
(headers []string, r *http.Request, customIP bool)
| 81 | // * `r` - the incoming HTTP request |
| 82 | // * `customIP` - whether to allow the IP to be pulled from query parameters |
| 83 | func ipFromRequest(headers []string, r *http.Request, customIP bool) (net.IP, error) { |
| 84 | remoteIP := "" |
| 85 | if customIP && r.URL != nil { |
| 86 | if v, ok := r.URL.Query()["ip"]; ok { |
| 87 | remoteIP = v[0] |
| 88 | } |
| 89 | } |
| 90 | if remoteIP == "" { |
| 91 | for _, header := range headers { |
| 92 | remoteIP = r.Header.Get(header) |
| 93 | if http.CanonicalHeaderKey(header) == "X-Forwarded-For" { |
| 94 | remoteIP = ipFromForwardedForHeader(remoteIP) |
| 95 | } |
| 96 | if remoteIP != "" { |
| 97 | break |
| 98 | } |
| 99 | } |
| 100 | } |
| 101 | if remoteIP == "" { |
| 102 | remoteIP = r.RemoteAddr |
| 103 | } |
| 104 | ip := net.ParseIP(remoteIP) |
| 105 | if ip == nil { |
| 106 | if strings.Contains(remoteIP, ":") { |
| 107 | host, _, err := net.SplitHostPort(remoteIP) |
| 108 | if err != nil { |
| 109 | return nil, err |
| 110 | } |
| 111 | remoteIP = host |
| 112 | ip = net.ParseIP(remoteIP) |
| 113 | } |
| 114 | if ip == nil { |
| 115 | return nil, fmt.Errorf("could not parse IP: %s", remoteIP) |
| 116 | } |
| 117 | } |
| 118 | return ip, nil |
| 119 | } |
| 120 | |
| 121 | func userAgentFromRequest(r *http.Request) *useragent.UserAgent { |
| 122 | var userAgent *useragent.UserAgent |