xff_test.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package internal
  2. import (
  3. "errors"
  4. "net/http"
  5. "net/http/httptest"
  6. "testing"
  7. )
  8. func TestXForwardedForUpdateIgnoreUnix(t *testing.T) {
  9. var remoteAddr = ""
  10. var xff = ""
  11. h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  12. remoteAddr = r.RemoteAddr
  13. xff = r.Header.Get("X-Forwarded-For")
  14. w.WriteHeader(http.StatusOK)
  15. })
  16. r := httptest.NewRequest(http.MethodGet, "/", nil)
  17. r.RemoteAddr = "@"
  18. w := httptest.NewRecorder()
  19. XForwardedForUpdate(true, h).ServeHTTP(w, r)
  20. if r.RemoteAddr != remoteAddr {
  21. t.Errorf("wanted remoteAddr to be %s, got: %s", r.RemoteAddr, remoteAddr)
  22. }
  23. if xff != "" {
  24. t.Error("handler added X-Forwarded-For when it should not have")
  25. }
  26. }
  27. func TestXForwardedForUpdateAddToChain(t *testing.T) {
  28. var xff = ""
  29. const expected = "1.1.1.1"
  30. h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  31. xff = r.Header.Get("X-Forwarded-For")
  32. w.WriteHeader(http.StatusOK)
  33. })
  34. srv := httptest.NewServer(XForwardedForUpdate(true, h))
  35. r, err := http.NewRequest(http.MethodGet, srv.URL, nil)
  36. if err != nil {
  37. t.Fatal(err)
  38. }
  39. r.Header.Set("X-Forwarded-For", "1.1.1.1,10.20.30.40")
  40. if _, err := srv.Client().Do(r); err != nil {
  41. t.Fatal(err)
  42. }
  43. if xff != expected {
  44. t.Logf("expected: %s", expected)
  45. t.Logf("got: %s", xff)
  46. t.Error("X-Forwarded-For header was not what was expected")
  47. }
  48. }
  49. func TestComputeXFFHeader(t *testing.T) {
  50. for _, tt := range []struct {
  51. err error
  52. name string
  53. remoteAddr string
  54. origXFFHeader string
  55. result string
  56. pref XFFComputePreferences
  57. }{
  58. {
  59. name: "StripPrivate",
  60. remoteAddr: "127.0.0.1:80",
  61. origXFFHeader: "1.1.1.1,10.0.0.1",
  62. pref: XFFComputePreferences{
  63. StripPrivate: true,
  64. },
  65. result: "1.1.1.1,127.0.0.1",
  66. },
  67. {
  68. name: "StripPrivate",
  69. remoteAddr: "127.0.0.1:80",
  70. origXFFHeader: "1.1.1.1,10.0.0.1",
  71. pref: XFFComputePreferences{
  72. StripPrivate: false,
  73. },
  74. result: "1.1.1.1,10.0.0.1,127.0.0.1",
  75. },
  76. {
  77. name: "StripLoopback",
  78. remoteAddr: "127.0.0.1:80",
  79. origXFFHeader: "1.1.1.1,10.0.0.1,127.0.0.1",
  80. pref: XFFComputePreferences{
  81. StripLoopback: true,
  82. },
  83. result: "1.1.1.1,10.0.0.1",
  84. },
  85. {
  86. name: "StripCGNAT",
  87. remoteAddr: "100.64.0.1:80",
  88. origXFFHeader: "1.1.1.1,10.0.0.1,100.64.0.1",
  89. pref: XFFComputePreferences{
  90. StripCGNAT: true,
  91. },
  92. result: "1.1.1.1,10.0.0.1",
  93. },
  94. {
  95. name: "StripLinkLocalUnicastIPv4",
  96. remoteAddr: "169.254.0.1:80",
  97. origXFFHeader: "1.1.1.1,10.0.0.1,169.254.0.1",
  98. pref: XFFComputePreferences{
  99. StripLLU: true,
  100. },
  101. result: "1.1.1.1,10.0.0.1",
  102. },
  103. {
  104. name: "StripLinkLocalUnicastIPv6",
  105. remoteAddr: "169.254.0.1:80",
  106. origXFFHeader: "1.1.1.1,10.0.0.1,fe80::",
  107. pref: XFFComputePreferences{
  108. StripLLU: true,
  109. },
  110. result: "1.1.1.1,10.0.0.1",
  111. },
  112. {
  113. name: "Flatten",
  114. remoteAddr: "127.0.0.1:80",
  115. origXFFHeader: "1.1.1.1,10.0.0.1,fe80::,100.64.0.1,169.254.0.1",
  116. pref: XFFComputePreferences{
  117. StripPrivate: true,
  118. StripLoopback: true,
  119. StripCGNAT: true,
  120. StripLLU: true,
  121. Flatten: true,
  122. },
  123. result: "1.1.1.1",
  124. },
  125. {
  126. name: "TrimSpaces",
  127. remoteAddr: "127.0.0.1:80",
  128. origXFFHeader: "1.1.1.1, 10.0.0.1, fe80::, 100.64.0.1, 169.254.0.1",
  129. pref: XFFComputePreferences{
  130. StripPrivate: true,
  131. StripLoopback: true,
  132. StripCGNAT: true,
  133. StripLLU: true,
  134. Flatten: true,
  135. },
  136. result: "1.1.1.1",
  137. },
  138. {
  139. name: "invalid-ip-port",
  140. remoteAddr: "fe80::",
  141. err: ErrCantSplitHostParse,
  142. },
  143. {
  144. name: "invalid-remote-ip",
  145. remoteAddr: "anubis:80",
  146. err: ErrCantParseRemoteIP,
  147. },
  148. {
  149. name: "no-xff-dont-panic",
  150. remoteAddr: "127.0.0.1:80",
  151. pref: XFFComputePreferences{
  152. StripPrivate: true,
  153. StripLoopback: true,
  154. StripCGNAT: true,
  155. StripLLU: true,
  156. Flatten: true,
  157. },
  158. },
  159. } {
  160. t.Run(tt.name, func(t *testing.T) {
  161. result, err := computeXFFHeader(tt.remoteAddr, tt.origXFFHeader, tt.pref)
  162. if err != nil && !errors.Is(err, tt.err) {
  163. t.Errorf("computeXFFHeader got the wrong error, wanted %v but got: %v", tt.err, err)
  164. }
  165. if result != tt.result {
  166. t.Errorf("computeXFFHeader returned the wrong result, wanted %q but got: %q", tt.result, result)
  167. }
  168. })
  169. }
  170. }