client_ip.go 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  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 without considering HTTP headers.
  27. func FindRemoteIP(r *http.Request) string {
  28. remoteIP, _, err := net.SplitHostPort(r.RemoteAddr)
  29. if err != nil {
  30. remoteIP = r.RemoteAddr
  31. }
  32. return dropIPv6zone(remoteIP)
  33. }
  34. func dropIPv6zone(address string) string {
  35. i := strings.IndexByte(address, '%')
  36. if i != -1 {
  37. address = address[:i]
  38. }
  39. return address
  40. }