client_ip.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package request // import "miniflux.app/v2/internal/http/request"
  4. import (
  5. "net"
  6. "net/http"
  7. "strings"
  8. )
  9. // FindClientIP returns the client real IP address based on trusted Reverse-Proxy HTTP headers.
  10. func FindClientIP(r *http.Request) string {
  11. headers := []string{"X-Forwarded-For", "X-Real-Ip"}
  12. for _, header := range headers {
  13. value := r.Header.Get(header)
  14. if value != "" {
  15. addresses := strings.Split(value, ",")
  16. address := strings.TrimSpace(addresses[0])
  17. address = dropIPv6zone(address)
  18. if net.ParseIP(address) != nil {
  19. return address
  20. }
  21. }
  22. }
  23. // Fallback to TCP/IP source IP address.
  24. return FindRemoteIP(r)
  25. }
  26. // FindRemoteIP returns remote client IP address.
  27. func FindRemoteIP(r *http.Request) string {
  28. remoteIP, _, err := net.SplitHostPort(r.RemoteAddr)
  29. if err != nil {
  30. remoteIP = r.RemoteAddr
  31. }
  32. remoteIP = dropIPv6zone(remoteIP)
  33. // When listening on a Unix socket, RemoteAddr is empty.
  34. if remoteIP == "" {
  35. remoteIP = "127.0.0.1"
  36. }
  37. return remoteIP
  38. }
  39. func dropIPv6zone(address string) string {
  40. i := strings.IndexByte(address, '%')
  41. if i != -1 {
  42. address = address[:i]
  43. }
  44. return address
  45. }