proxy_string_util_unittest.cc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/base/proxy_string_util.h"
  5. #include "net/base/proxy_server.h"
  6. #include "testing/gtest/include/gtest/gtest.h"
  7. namespace net {
  8. namespace {
  9. // Test the creation of ProxyServer using ProxyUriToProxyServer, which parses
  10. // inputs of the form [<scheme>"://"]<host>[":"<port>]. Verify that each part
  11. // was labelled correctly, and the accessors all give the right data.
  12. TEST(ProxySpecificationUtilTest, ProxyUriToProxyServer) {
  13. const struct {
  14. const char* const input_uri;
  15. const char* const expected_uri;
  16. ProxyServer::Scheme expected_scheme;
  17. const char* const expected_host;
  18. int expected_port;
  19. const char* const expected_pac_string;
  20. } tests[] = {
  21. // HTTP proxy URIs:
  22. {"foopy:10", // No scheme.
  23. "foopy:10", ProxyServer::SCHEME_HTTP, "foopy", 10, "PROXY foopy:10"},
  24. {"http://foopy", // No port.
  25. "foopy:80", ProxyServer::SCHEME_HTTP, "foopy", 80, "PROXY foopy:80"},
  26. {"http://foopy:10", "foopy:10", ProxyServer::SCHEME_HTTP, "foopy", 10,
  27. "PROXY foopy:10"},
  28. // IPv6 HTTP proxy URIs:
  29. {"[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:10", // No scheme.
  30. "[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:10", ProxyServer::SCHEME_HTTP,
  31. "fedc:ba98:7654:3210:fedc:ba98:7654:3210", 10,
  32. "PROXY [fedc:ba98:7654:3210:fedc:ba98:7654:3210]:10"},
  33. {"http://[3ffe:2a00:100:7031::1]", // No port.
  34. "[3ffe:2a00:100:7031::1]:80", ProxyServer::SCHEME_HTTP,
  35. "3ffe:2a00:100:7031::1", 80, "PROXY [3ffe:2a00:100:7031::1]:80"},
  36. // SOCKS4 proxy URIs:
  37. {"socks4://foopy", // No port.
  38. "socks4://foopy:1080", ProxyServer::SCHEME_SOCKS4, "foopy", 1080,
  39. "SOCKS foopy:1080"},
  40. {"socks4://foopy:10", "socks4://foopy:10", ProxyServer::SCHEME_SOCKS4,
  41. "foopy", 10, "SOCKS foopy:10"},
  42. // SOCKS5 proxy URIs:
  43. {"socks5://foopy", // No port.
  44. "socks5://foopy:1080", ProxyServer::SCHEME_SOCKS5, "foopy", 1080,
  45. "SOCKS5 foopy:1080"},
  46. {"socks5://foopy:10", "socks5://foopy:10", ProxyServer::SCHEME_SOCKS5,
  47. "foopy", 10, "SOCKS5 foopy:10"},
  48. // SOCKS proxy URIs (should default to SOCKS5)
  49. {"socks://foopy", // No port.
  50. "socks5://foopy:1080", ProxyServer::SCHEME_SOCKS5, "foopy", 1080,
  51. "SOCKS5 foopy:1080"},
  52. {"socks://foopy:10", "socks5://foopy:10", ProxyServer::SCHEME_SOCKS5,
  53. "foopy", 10, "SOCKS5 foopy:10"},
  54. // HTTPS proxy URIs:
  55. {"https://foopy", // No port
  56. "https://foopy:443", ProxyServer::SCHEME_HTTPS, "foopy", 443,
  57. "HTTPS foopy:443"},
  58. {"https://foopy:10", // Non-standard port
  59. "https://foopy:10", ProxyServer::SCHEME_HTTPS, "foopy", 10,
  60. "HTTPS foopy:10"},
  61. {"https://1.2.3.4:10", // IP Address
  62. "https://1.2.3.4:10", ProxyServer::SCHEME_HTTPS, "1.2.3.4", 10,
  63. "HTTPS 1.2.3.4:10"},
  64. // Hostname canonicalization:
  65. {"[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:10", // No scheme.
  66. "[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:10", ProxyServer::SCHEME_HTTP,
  67. "fedc:ba98:7654:3210:fedc:ba98:7654:3210", 10,
  68. "PROXY [fedc:ba98:7654:3210:fedc:ba98:7654:3210]:10"},
  69. {"http://[::192.9.5.5]", "[::c009:505]:80", ProxyServer::SCHEME_HTTP,
  70. "::c009:505", 80, "PROXY [::c009:505]:80"},
  71. {"http://[::FFFF:129.144.52.38]:80", "[::ffff:8190:3426]:80",
  72. ProxyServer::SCHEME_HTTP, "::ffff:8190:3426", 80,
  73. "PROXY [::ffff:8190:3426]:80"},
  74. {"http://f\u00fcpy:85", "xn--fpy-hoa:85", ProxyServer::SCHEME_HTTP,
  75. "xn--fpy-hoa", 85, "PROXY xn--fpy-hoa:85"},
  76. {"https://0xA.020.3.4:443", "https://10.16.3.4:443",
  77. ProxyServer::SCHEME_HTTPS, "10.16.3.4", 443, "HTTPS 10.16.3.4:443"},
  78. {"http://FoO.tEsT:80", "foo.test:80", ProxyServer::SCHEME_HTTP,
  79. "foo.test", 80, "PROXY foo.test:80"},
  80. };
  81. for (const auto& test : tests) {
  82. ProxyServer uri =
  83. ProxyUriToProxyServer(test.input_uri, ProxyServer::SCHEME_HTTP);
  84. EXPECT_TRUE(uri.is_valid());
  85. EXPECT_FALSE(uri.is_direct());
  86. EXPECT_EQ(test.expected_uri, ProxyServerToProxyUri(uri));
  87. EXPECT_EQ(test.expected_scheme, uri.scheme());
  88. EXPECT_EQ(test.expected_host, uri.host_port_pair().host());
  89. EXPECT_EQ(test.expected_port, uri.host_port_pair().port());
  90. EXPECT_EQ(test.expected_pac_string, ProxyServerToPacResultElement(uri));
  91. }
  92. }
  93. // Test parsing of the special URI form "direct://". analogous to the "DIRECT"
  94. // element in a PAC result.
  95. TEST(ProxySpecificationUtilTest, DirectProxyUriToProxyServer) {
  96. ProxyServer uri =
  97. ProxyUriToProxyServer("direct://", ProxyServer::SCHEME_HTTP);
  98. EXPECT_TRUE(uri.is_valid());
  99. EXPECT_TRUE(uri.is_direct());
  100. EXPECT_EQ("direct://", ProxyServerToProxyUri(uri));
  101. EXPECT_EQ("DIRECT", ProxyServerToPacResultElement(uri));
  102. }
  103. // Test parsing some invalid inputs.
  104. TEST(ProxySpecificationUtilTest, InvalidProxyUriToProxyServer) {
  105. const char* const tests[] = {
  106. "",
  107. " ",
  108. "dddf:", // not a valid port
  109. "dddd:d", // not a valid port
  110. "http://", // not a valid host/port.
  111. "direct://xyz", // direct is not allowed a host/port.
  112. "http:/", // ambiguous, but will fail because of bad port.
  113. "http:", // ambiguous, but will fail because of bad port.
  114. "foopy.111", // Interpreted as invalid IPv4 address.
  115. "foo.test/" // Paths disallowed.
  116. "foo.test:123/" // Paths disallowed.
  117. "foo.test/foo" // Paths disallowed.
  118. };
  119. for (const char* test : tests) {
  120. SCOPED_TRACE(test);
  121. ProxyServer uri = ProxyUriToProxyServer(test, ProxyServer::SCHEME_HTTP);
  122. EXPECT_FALSE(uri.is_valid());
  123. EXPECT_FALSE(uri.is_direct());
  124. EXPECT_FALSE(uri.is_http());
  125. EXPECT_FALSE(uri.is_socks());
  126. }
  127. }
  128. // Test that LWS (SP | HT) is disregarded from the ends.
  129. TEST(ProxySpecificationUtilTest, WhitespaceProxyUriToProxyServer) {
  130. const char* const tests[] = {
  131. " foopy:80",
  132. "foopy:80 \t",
  133. " \tfoopy:80 ",
  134. };
  135. for (const char* test : tests) {
  136. ProxyServer uri = ProxyUriToProxyServer(test, ProxyServer::SCHEME_HTTP);
  137. EXPECT_EQ("foopy:80", ProxyServerToProxyUri(uri));
  138. }
  139. }
  140. // Test parsing a ProxyServer from a PAC representation.
  141. TEST(ProxySpecificationUtilTest, PacResultElementToProxyServer) {
  142. const struct {
  143. const char* const input_pac;
  144. const char* const expected_uri;
  145. } tests[] = {
  146. {
  147. "PROXY foopy:10",
  148. "foopy:10",
  149. },
  150. {
  151. " PROXY foopy:10 ",
  152. "foopy:10",
  153. },
  154. {
  155. "pRoXy foopy:10",
  156. "foopy:10",
  157. },
  158. {
  159. "PROXY foopy", // No port.
  160. "foopy:80",
  161. },
  162. {
  163. "socks foopy",
  164. "socks4://foopy:1080",
  165. },
  166. {
  167. "socks4 foopy",
  168. "socks4://foopy:1080",
  169. },
  170. {
  171. "socks5 foopy",
  172. "socks5://foopy:1080",
  173. },
  174. {
  175. "socks5 foopy:11",
  176. "socks5://foopy:11",
  177. },
  178. {
  179. " direct ",
  180. "direct://",
  181. },
  182. {
  183. "https foopy",
  184. "https://foopy:443",
  185. },
  186. {
  187. "https foopy:10",
  188. "https://foopy:10",
  189. },
  190. {"PROXY [FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:10",
  191. "[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:10"},
  192. {"PROXY f\u00fcpy:85", "xn--fpy-hoa:85"},
  193. };
  194. for (const auto& test : tests) {
  195. ProxyServer uri = PacResultElementToProxyServer(test.input_pac);
  196. EXPECT_TRUE(uri.is_valid());
  197. EXPECT_EQ(test.expected_uri, ProxyServerToProxyUri(uri));
  198. }
  199. }
  200. // Test parsing a ProxyServer from an invalid PAC representation.
  201. TEST(ProxySpecificationUtilTest, InvalidPacResultElementToProxyServer) {
  202. const char* const tests[] = {
  203. "PROXY", // missing host/port.
  204. "HTTPS", // missing host/port.
  205. "SOCKS", // missing host/port.
  206. "DIRECT foopy:10", // direct cannot have host/port.
  207. "INVALIDSCHEME", // unrecognized scheme.
  208. "INVALIDSCHEME foopy:10", // unrecognized scheme.
  209. "HTTP foopy:10", // http scheme should be "PROXY"
  210. };
  211. for (const char* test : tests) {
  212. ProxyServer uri = PacResultElementToProxyServer(test);
  213. EXPECT_FALSE(uri.is_valid());
  214. }
  215. }
  216. } // namespace
  217. } // namespace net