client_ip_test.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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/http"
  6. "testing"
  7. )
  8. func TestFindClientIPWithoutHeaders(t *testing.T) {
  9. r := &http.Request{RemoteAddr: "192.168.0.1:4242"}
  10. if ip := FindClientIP(r, false); ip != "192.168.0.1" {
  11. t.Fatalf(`Unexpected result, got: %q`, ip)
  12. }
  13. r = &http.Request{RemoteAddr: "192.168.0.1"}
  14. if ip := FindClientIP(r, false); ip != "192.168.0.1" {
  15. t.Fatalf(`Unexpected result, got: %q`, ip)
  16. }
  17. r = &http.Request{RemoteAddr: "fe80::14c2:f039:edc7:edc7"}
  18. if ip := FindClientIP(r, false); ip != "fe80::14c2:f039:edc7:edc7" {
  19. t.Fatalf(`Unexpected result, got: %q`, ip)
  20. }
  21. r = &http.Request{RemoteAddr: "fe80::14c2:f039:edc7:edc7%eth0"}
  22. if ip := FindClientIP(r, false); ip != "fe80::14c2:f039:edc7:edc7" {
  23. t.Fatalf(`Unexpected result, got: %q`, ip)
  24. }
  25. r = &http.Request{RemoteAddr: "[fe80::14c2:f039:edc7:edc7%eth0]:4242"}
  26. if ip := FindClientIP(r, false); ip != "fe80::14c2:f039:edc7:edc7" {
  27. t.Fatalf(`Unexpected result, got: %q`, ip)
  28. }
  29. }
  30. func TestFindClientIPWithXFFHeader(t *testing.T) {
  31. // Test with multiple IPv4 addresses.
  32. headers := http.Header{}
  33. headers.Set("X-Forwarded-For", "203.0.113.195, 70.41.3.18, 150.172.238.178")
  34. r := &http.Request{RemoteAddr: "192.168.0.1:4242", Header: headers}
  35. if ip := FindClientIP(r, true); ip != "203.0.113.195" {
  36. t.Fatalf(`Unexpected result, got: %q`, ip)
  37. }
  38. // Test with single IPv6 address.
  39. headers = http.Header{}
  40. headers.Set("X-Forwarded-For", "2001:db8:85a3:8d3:1319:8a2e:370:7348")
  41. r = &http.Request{RemoteAddr: "192.168.0.1:4242", Header: headers}
  42. if ip := FindClientIP(r, true); ip != "2001:db8:85a3:8d3:1319:8a2e:370:7348" {
  43. t.Fatalf(`Unexpected result, got: %q`, ip)
  44. }
  45. // Test with single IPv6 address with zone
  46. headers = http.Header{}
  47. headers.Set("X-Forwarded-For", "fe80::14c2:f039:edc7:edc7%eth0")
  48. r = &http.Request{RemoteAddr: "192.168.0.1:4242", Header: headers}
  49. if ip := FindClientIP(r, true); ip != "fe80::14c2:f039:edc7:edc7" {
  50. t.Fatalf(`Unexpected result, got: %q`, ip)
  51. }
  52. // Test with single IPv4 address.
  53. headers = http.Header{}
  54. headers.Set("X-Forwarded-For", "70.41.3.18")
  55. r = &http.Request{RemoteAddr: "192.168.0.1:4242", Header: headers}
  56. if ip := FindClientIP(r, true); ip != "70.41.3.18" {
  57. t.Fatalf(`Unexpected result, got: %q`, ip)
  58. }
  59. // Test with invalid IP address.
  60. headers = http.Header{}
  61. headers.Set("X-Forwarded-For", "fake IP")
  62. r = &http.Request{RemoteAddr: "192.168.0.1:4242", Header: headers}
  63. if ip := FindClientIP(r, true); ip != "192.168.0.1" {
  64. t.Fatalf(`Unexpected result, got: %q`, ip)
  65. }
  66. }
  67. func TestClientIPWithXRealIPHeader(t *testing.T) {
  68. headers := http.Header{}
  69. headers.Set("X-Real-Ip", "192.168.122.1")
  70. r := &http.Request{RemoteAddr: "192.168.0.1:4242", Header: headers}
  71. if ip := FindClientIP(r, true); ip != "192.168.122.1" {
  72. t.Fatalf(`Unexpected result, got: %q`, ip)
  73. }
  74. }
  75. func TestClientIPWithBothHeaders(t *testing.T) {
  76. headers := http.Header{}
  77. headers.Set("X-Forwarded-For", "203.0.113.195, 70.41.3.18, 150.172.238.178")
  78. headers.Set("X-Real-Ip", "192.168.122.1")
  79. r := &http.Request{RemoteAddr: "192.168.0.1:4242", Header: headers}
  80. if ip := FindClientIP(r, true); ip != "203.0.113.195" {
  81. t.Fatalf(`Unexpected result, got: %q`, ip)
  82. }
  83. }
  84. func TestClientIPWithUnixSocketRemoteAddress(t *testing.T) {
  85. r := &http.Request{RemoteAddr: "@"}
  86. if ip := FindClientIP(r, false); ip != "@" {
  87. t.Fatalf(`Unexpected result, got: %q`, ip)
  88. }
  89. }
  90. func TestClientIPWithUnixSocketRemoteAddrAndBothHeaders(t *testing.T) {
  91. headers := http.Header{}
  92. headers.Set("X-Forwarded-For", "203.0.113.195, 70.41.3.18, 150.172.238.178")
  93. headers.Set("X-Real-Ip", "192.168.122.1")
  94. r := &http.Request{RemoteAddr: "@", Header: headers}
  95. if ip := FindClientIP(r, true); ip != "203.0.113.195" {
  96. t.Fatalf(`Unexpected result, got: %q`, ip)
  97. }
  98. }
  99. func TestIsTrustedIP(t *testing.T) {
  100. trustedNetworks := []string{"127.0.0.1/8", "10.0.0.0/8", "::1/128", "invalid"}
  101. scenarios := []struct {
  102. ip string
  103. expected bool
  104. }{
  105. {"127.0.0.1", true},
  106. {"10.0.0.1", true},
  107. {"::1", true},
  108. {"192.168.1.1", false},
  109. {"invalid", false},
  110. {"@", true},
  111. {"/tmp/miniflux.sock", true},
  112. }
  113. for _, scenario := range scenarios {
  114. result := IsTrustedIP(scenario.ip, trustedNetworks)
  115. if result != scenario.expected {
  116. t.Errorf("Expected %v for IP %s, got %v", scenario.expected, scenario.ip, result)
  117. }
  118. }
  119. if IsTrustedIP("127.0.0.1", nil) {
  120. t.Error("Expected false when no trusted networks are defined")
  121. }
  122. if IsTrustedIP("127.0.0.1", []string{}) {
  123. t.Error("Expected false when trusted networks list is empty")
  124. }
  125. }