ipv6_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package upstream
  2. import (
  3. "testing"
  4. )
  5. func TestParseAddressOnly_IPv6Support(t *testing.T) {
  6. tests := []struct {
  7. name string
  8. input string
  9. expected ProxyTarget
  10. }{
  11. // IPv6 with brackets and port
  12. {
  13. name: "IPv6 with brackets and port",
  14. input: "[::1]:8080",
  15. expected: ProxyTarget{
  16. Host: "::1",
  17. Port: "8080",
  18. },
  19. },
  20. {
  21. name: "IPv6 full address with brackets and port",
  22. input: "[2001:db8::1]:9000",
  23. expected: ProxyTarget{
  24. Host: "2001:db8::1",
  25. Port: "9000",
  26. },
  27. },
  28. // IPv6 with brackets without port
  29. {
  30. name: "IPv6 with brackets without port",
  31. input: "[::1]",
  32. expected: ProxyTarget{
  33. Host: "::1",
  34. Port: "80",
  35. },
  36. },
  37. {
  38. name: "IPv6 full address with brackets without port",
  39. input: "[2001:db8::1]",
  40. expected: ProxyTarget{
  41. Host: "2001:db8::1",
  42. Port: "80",
  43. },
  44. },
  45. // IPv6 without brackets
  46. {
  47. name: "IPv6 localhost without brackets",
  48. input: "::1",
  49. expected: ProxyTarget{
  50. Host: "::1",
  51. Port: "80",
  52. },
  53. },
  54. {
  55. name: "IPv6 full address without brackets",
  56. input: "2001:db8::1",
  57. expected: ProxyTarget{
  58. Host: "2001:db8::1",
  59. Port: "80",
  60. },
  61. },
  62. {
  63. name: "IPv6 link-local with interface",
  64. input: "fe80::1%eth0",
  65. expected: ProxyTarget{
  66. Host: "fe80::1%eth0",
  67. Port: "80",
  68. },
  69. },
  70. // IPv4 tests
  71. {
  72. name: "IPv4 with port",
  73. input: "192.168.1.1:8080",
  74. expected: ProxyTarget{
  75. Host: "192.168.1.1",
  76. Port: "8080",
  77. },
  78. },
  79. {
  80. name: "IPv4 without port",
  81. input: "192.168.1.1",
  82. expected: ProxyTarget{
  83. Host: "192.168.1.1",
  84. Port: "80",
  85. },
  86. },
  87. // Hostname tests
  88. {
  89. name: "Hostname with port",
  90. input: "example.com:8080",
  91. expected: ProxyTarget{
  92. Host: "example.com",
  93. Port: "8080",
  94. },
  95. },
  96. {
  97. name: "Hostname without port",
  98. input: "example.com",
  99. expected: ProxyTarget{
  100. Host: "example.com",
  101. Port: "80",
  102. },
  103. },
  104. }
  105. for _, tt := range tests {
  106. t.Run(tt.name, func(t *testing.T) {
  107. result := parseAddressOnly(tt.input)
  108. if result.Host != tt.expected.Host {
  109. t.Errorf("parseAddressOnly(%q).Host = %q, want %q", tt.input, result.Host, tt.expected.Host)
  110. }
  111. if result.Port != tt.expected.Port {
  112. t.Errorf("parseAddressOnly(%q).Port = %q, want %q", tt.input, result.Port, tt.expected.Port)
  113. }
  114. })
  115. }
  116. }
  117. func TestParseProxyTargetsFromRawContent_IPv6Support(t *testing.T) {
  118. config := `
  119. upstream backend_ipv6 {
  120. server [::1]:8080;
  121. server [2001:db8::1]:9000;
  122. server 192.168.1.100:8080;
  123. }
  124. upstream backend_mixed {
  125. server [::1]:8080;
  126. server 192.168.1.100:8080;
  127. server example.com:9000;
  128. }
  129. server {
  130. listen 80;
  131. location / {
  132. proxy_pass http://[::1]:8080;
  133. }
  134. location /api {
  135. proxy_pass http://backend_ipv6;
  136. }
  137. }
  138. `
  139. targets := ParseProxyTargetsFromRawContent(config)
  140. // Expected targets (after deduplication):
  141. // - [::1]:8080 (appears in both upstreams and proxy_pass, but deduplicated)
  142. // - [2001:db8::1]:9000 (from backend_ipv6)
  143. // - 192.168.1.100:8080 (appears in both upstreams, but deduplicated)
  144. // - example.com:9000 (from backend_mixed)
  145. // - [::1]:8080 proxy_pass (different type, so not deduplicated)
  146. expectedCount := 5
  147. if len(targets) != expectedCount {
  148. t.Errorf("Expected %d targets, got %d", expectedCount, len(targets))
  149. for i, target := range targets {
  150. t.Logf("Target %d: Host=%s, Port=%s, Type=%s", i, target.Host, target.Port, target.Type)
  151. }
  152. }
  153. // Check for IPv6 targets
  154. hasIPv6Localhost := false
  155. hasIPv6Full := false
  156. hasIPv4 := false
  157. for _, target := range targets {
  158. if target.Host == "::1" && target.Port == "8080" {
  159. hasIPv6Localhost = true
  160. }
  161. if target.Host == "2001:db8::1" && target.Port == "9000" {
  162. hasIPv6Full = true
  163. }
  164. if target.Host == "192.168.1.100" && target.Port == "8080" {
  165. hasIPv4 = true
  166. }
  167. }
  168. if !hasIPv6Localhost {
  169. t.Error("Expected to find IPv6 localhost target [::1]:8080")
  170. }
  171. if !hasIPv6Full {
  172. t.Error("Expected to find IPv6 full address target [2001:db8::1]:9000")
  173. }
  174. if !hasIPv4 {
  175. t.Error("Expected to find IPv4 target 192.168.1.100:8080")
  176. }
  177. }