uri_parser_test.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. //
  2. // Copyright 2015 gRPC authors.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. #include "src/core/lib/uri/uri_parser.h"
  17. #include <gmock/gmock.h>
  18. #include <gtest/gtest.h>
  19. #include "absl/strings/str_join.h"
  20. #include "absl/strings/str_split.h"
  21. #include <grpc/grpc.h>
  22. #include <grpc/support/log.h>
  23. #include "test/core/util/test_config.h"
  24. using ::testing::ContainerEq;
  25. using ::testing::Contains;
  26. using ::testing::ElementsAre;
  27. using ::testing::Pair;
  28. namespace grpc_core {
  29. class URIParserTest : public testing::Test {
  30. protected:
  31. static void TestSucceeds(
  32. absl::string_view uri_text, absl::string_view scheme,
  33. absl::string_view authority, absl::string_view path,
  34. const std::map<absl::string_view, absl::string_view>& query_param_map,
  35. const std::vector<URI::QueryParam>& query_param_pairs,
  36. absl::string_view fragment) {
  37. absl::StatusOr<URI> uri = URI::Parse(uri_text);
  38. ASSERT_TRUE(uri.ok()) << uri.status().ToString();
  39. EXPECT_EQ(scheme, uri->scheme());
  40. EXPECT_EQ(authority, uri->authority());
  41. EXPECT_EQ(path, uri->path());
  42. EXPECT_THAT(uri->query_parameter_map(), ContainerEq(query_param_map));
  43. EXPECT_THAT(uri->query_parameter_pairs(), ContainerEq(query_param_pairs));
  44. EXPECT_EQ(fragment, uri->fragment());
  45. }
  46. static void TestFails(absl::string_view uri_text) {
  47. absl::StatusOr<URI> uri = URI::Parse(uri_text);
  48. ASSERT_FALSE(uri.ok());
  49. }
  50. };
  51. TEST_F(URIParserTest, BasicExamplesAreParsedCorrectly) {
  52. TestSucceeds("http://www.google.com", "http", "www.google.com", "", {}, {},
  53. "");
  54. TestSucceeds("dns:///foo", "dns", "", "/foo", {}, {}, "");
  55. TestSucceeds("http://www.google.com:90", "http", "www.google.com:90", "", {},
  56. {}, "");
  57. TestSucceeds("a192.4-df:foo.coom", "a192.4-df", "", "foo.coom", {}, {}, "");
  58. TestSucceeds("a+b:foo.coom", "a+b", "", "foo.coom", {}, {}, "");
  59. TestSucceeds("zookeeper://127.0.0.1:2181/foo/bar", "zookeeper",
  60. "127.0.0.1:2181", "/foo/bar", {}, {}, "");
  61. TestSucceeds("dns:foo.com#fragment-all-the-things", "dns", "", "foo.com", {},
  62. {}, "fragment-all-the-things");
  63. TestSucceeds("http://localhost:8080/whatzit?mi_casa=su_casa", "http",
  64. "localhost:8080", "/whatzit", {{"mi_casa", "su_casa"}},
  65. {{"mi_casa", "su_casa"}}, "");
  66. TestSucceeds("http://localhost:8080/whatzit?1=2#buckle/my/shoe", "http",
  67. "localhost:8080", "/whatzit", {{"1", "2"}}, {{"1", "2"}},
  68. "buckle/my/shoe");
  69. }
  70. TEST_F(URIParserTest, UncommonValidExamplesAreParsedCorrectly) {
  71. TestSucceeds("scheme:path//is/ok", "scheme", "", "path//is/ok", {}, {}, "");
  72. TestSucceeds("http:?legit", "http", "", "", {{"legit", ""}}, {{"legit", ""}},
  73. "");
  74. TestSucceeds("unix:#this-is-ok-too", "unix", "", "", {}, {},
  75. "this-is-ok-too");
  76. TestSucceeds("http:?legit#twice", "http", "", "", {{"legit", ""}},
  77. {{"legit", ""}}, "twice");
  78. TestSucceeds("fake:///", "fake", "", "/", {}, {}, "");
  79. TestSucceeds("http://local%25host:8080/whatz%25it?1%25=2%25#fragment", "http",
  80. "local%host:8080", "/whatz%it", {{"1%", "2%"}}, {{"1%", "2%"}},
  81. "fragment");
  82. }
  83. TEST_F(URIParserTest, VariousKeyValueAndNonKVQueryParamsAreParsedCorrectly) {
  84. TestSucceeds("http://foo/path?a&b=B&c=&#frag", "http", "foo", "/path",
  85. {{"c", ""}, {"a", ""}, {"b", "B"}},
  86. {{"a", ""}, {"b", "B"}, {"c", ""}}, "frag");
  87. }
  88. TEST_F(URIParserTest, ParserTreatsFirstEqualSignAsKVDelimiterInQueryString) {
  89. TestSucceeds(
  90. "http://localhost:8080/?too=many=equals&are=present=here#fragged", "http",
  91. "localhost:8080", "/", {{"are", "present=here"}, {"too", "many=equals"}},
  92. {{"too", "many=equals"}, {"are", "present=here"}}, "fragged");
  93. TestSucceeds("http://auth/path?foo=bar=baz&foobar===", "http", "auth",
  94. "/path", {{"foo", "bar=baz"}, {"foobar", "=="}},
  95. {{"foo", "bar=baz"}, {"foobar", "=="}}, "");
  96. }
  97. TEST_F(URIParserTest,
  98. RepeatedQueryParamsAreSupportedInOrderedPairsButDeduplicatedInTheMap) {
  99. absl::StatusOr<URI> uri = URI::Parse("http://foo/path?a=2&a=1&a=3");
  100. ASSERT_TRUE(uri.ok()) << uri.status().ToString();
  101. // The map stores the last found value.
  102. ASSERT_THAT(uri->query_parameter_map(), ElementsAre(Pair("a", "3")));
  103. // Order matters for query parameter pairs
  104. ASSERT_THAT(uri->query_parameter_pairs(),
  105. ElementsAre(URI::QueryParam{"a", "2"}, URI::QueryParam{"a", "1"},
  106. URI::QueryParam{"a", "3"}));
  107. }
  108. TEST_F(URIParserTest, QueryParamMapRemainsValiditAfterMovingTheURI) {
  109. URI uri_copy;
  110. {
  111. absl::StatusOr<URI> uri = URI::Parse("http://foo/path?a=2&b=1&c=3");
  112. ASSERT_TRUE(uri.ok()) << uri.status().ToString();
  113. uri_copy = std::move(*uri);
  114. }
  115. // ASSERT_EQ(uri_copy.query_parameter_map().find("a")->second, "2");
  116. ASSERT_THAT(uri_copy.query_parameter_map(), Contains(Pair("a", "2")));
  117. }
  118. TEST_F(URIParserTest, QueryParamMapRemainsValidAfterCopyingTheURI) {
  119. // Since the query parameter map points to objects stored in the param pair
  120. // vector, this test checks that the param map pointers remain valid after
  121. // a copy. Ideally {a,m}san will catch this if there's a problem.
  122. // testing copy operator=:
  123. URI uri_copy;
  124. {
  125. absl::StatusOr<URI> del_uri = URI::Parse("http://foo/path?a=2&b=1&c=3");
  126. ASSERT_TRUE(del_uri.ok()) << del_uri.status().ToString();
  127. uri_copy = *del_uri;
  128. }
  129. ASSERT_THAT(uri_copy.query_parameter_map(), Contains(Pair("a", "2")));
  130. URI* del_uri2 = new URI(uri_copy);
  131. URI uri_copy2(*del_uri2);
  132. delete del_uri2;
  133. ASSERT_THAT(uri_copy2.query_parameter_map(), Contains(Pair("a", "2")));
  134. }
  135. TEST_F(URIParserTest, AWSExternalAccountRegressionTest) {
  136. TestSucceeds(
  137. "https://foo.com:5555/v1/"
  138. "token-exchange?subject_token=eyJhbGciO&subject_token_type=urn:ietf:"
  139. "params:oauth:token-type:id_token",
  140. "https", "foo.com:5555", "/v1/token-exchange",
  141. {{"subject_token", "eyJhbGciO"},
  142. {"subject_token_type", "urn:ietf:params:oauth:token-type:id_token"}},
  143. {{"subject_token", "eyJhbGciO"},
  144. {"subject_token_type", "urn:ietf:params:oauth:token-type:id_token"}},
  145. "");
  146. }
  147. TEST_F(URIParserTest, NonKeyValueQueryStringsWork) {
  148. TestSucceeds("http://www.google.com?yay-i'm-using-queries", "http",
  149. "www.google.com", "", {{"yay-i'm-using-queries", ""}},
  150. {{"yay-i'm-using-queries", ""}}, "");
  151. }
  152. TEST_F(URIParserTest, IPV6StringsAreParsedCorrectly) {
  153. TestSucceeds("ipv6:[2001:db8::1%252]:12345", "ipv6", "",
  154. "[2001:db8::1%2]:12345", {}, {}, "");
  155. TestSucceeds("ipv6:[fe80::90%eth1.sky1]:6010", "ipv6", "",
  156. "[fe80::90%eth1.sky1]:6010", {}, {}, "");
  157. }
  158. TEST_F(URIParserTest,
  159. PreviouslyReservedCharactersInUnrelatedURIPartsAreIgnored) {
  160. // The '?' and '/' characters are not reserved delimiter characters in the
  161. // fragment. See http://go/rfc/3986#section-3.5
  162. TestSucceeds("http://foo?bar#lol?", "http", "foo", "", {{"bar", ""}},
  163. {{"bar", ""}}, "lol?");
  164. TestSucceeds("http://foo?bar#lol?/", "http", "foo", "", {{"bar", ""}},
  165. {{"bar", ""}}, "lol?/");
  166. }
  167. TEST_F(URIParserTest, EncodedCharactersInQueryStringAreParsedCorrectly) {
  168. TestSucceeds("https://www.google.com/?a=1%26b%3D2&c=3", "https",
  169. "www.google.com", "/", {{"c", "3"}, {"a", "1&b=2"}},
  170. {{"a", "1&b=2"}, {"c", "3"}}, "");
  171. }
  172. TEST_F(URIParserTest, InvalidPercentEncodingsArePassedThrough) {
  173. TestSucceeds("x:y?%xx", "x", "", "y", {{"%xx", ""}}, {{"%xx", ""}}, "");
  174. TestSucceeds("http:?dangling-pct-%0", "http", "", "",
  175. {{"dangling-pct-%0", ""}}, {{"dangling-pct-%0", ""}}, "");
  176. }
  177. TEST_F(URIParserTest, NullCharactersInURIStringAreSupported) {
  178. // Artificial examples to show that embedded nulls are supported.
  179. TestSucceeds(std::string("unix-abstract:\0should-be-ok", 27), "unix-abstract",
  180. "", std::string("\0should-be-ok", 13), {}, {}, "");
  181. }
  182. TEST_F(URIParserTest, EncodedNullsInURIStringAreSupported) {
  183. TestSucceeds("unix-abstract:%00x", "unix-abstract", "", std::string("\0x", 2),
  184. {}, {}, "");
  185. }
  186. TEST_F(URIParserTest, InvalidURIsResultInFailureStatuses) {
  187. TestFails("xyz");
  188. TestFails("http://foo?[bar]");
  189. TestFails("http://foo?x[bar]");
  190. TestFails("http://foo?bar#lol#");
  191. TestFails("");
  192. TestFails(":no_scheme");
  193. TestFails("0invalid_scheme:must_start/with?alpha");
  194. }
  195. TEST(URITest, PercentEncodePath) {
  196. EXPECT_EQ(URI::PercentEncodePath(
  197. // These chars are allowed.
  198. "abcdefghijklmnopqrstuvwxyz"
  199. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  200. "0123456789"
  201. "/:@-._~!$&'()*+,;="
  202. // These chars will be escaped.
  203. "\\?%#[]^"),
  204. "abcdefghijklmnopqrstuvwxyz"
  205. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  206. "0123456789"
  207. "/:@-._~!$&'()*+,;="
  208. "%5C%3F%25%23%5B%5D%5E");
  209. }
  210. TEST(URITest, Basic) {
  211. auto uri =
  212. URI::Create("http", "server.example.com", "/path/to/file.html", {}, "");
  213. ASSERT_TRUE(uri.ok()) << uri.status().ToString();
  214. EXPECT_EQ(uri->scheme(), "http");
  215. EXPECT_EQ(uri->authority(), "server.example.com");
  216. EXPECT_EQ(uri->path(), "/path/to/file.html");
  217. EXPECT_THAT(uri->query_parameter_pairs(), testing::ElementsAre());
  218. EXPECT_THAT(uri->query_parameter_map(), testing::ElementsAre());
  219. EXPECT_EQ(uri->fragment(), "");
  220. EXPECT_EQ("http://server.example.com/path/to/file.html", uri->ToString());
  221. }
  222. TEST(URITest, NoAuthority) {
  223. auto uri = URI::Create("http", "", "/path/to/file.html", {}, "");
  224. ASSERT_TRUE(uri.ok()) << uri.status().ToString();
  225. EXPECT_EQ(uri->scheme(), "http");
  226. EXPECT_EQ(uri->authority(), "");
  227. EXPECT_EQ(uri->path(), "/path/to/file.html");
  228. EXPECT_THAT(uri->query_parameter_pairs(), testing::ElementsAre());
  229. EXPECT_THAT(uri->query_parameter_map(), testing::ElementsAre());
  230. EXPECT_EQ(uri->fragment(), "");
  231. EXPECT_EQ("http:/path/to/file.html", uri->ToString());
  232. }
  233. TEST(URITest, NoAuthorityRelativePath) {
  234. auto uri = URI::Create("http", "", "path/to/file.html", {}, "");
  235. ASSERT_TRUE(uri.ok()) << uri.status().ToString();
  236. EXPECT_EQ(uri->scheme(), "http");
  237. EXPECT_EQ(uri->authority(), "");
  238. EXPECT_EQ(uri->path(), "path/to/file.html");
  239. EXPECT_THAT(uri->query_parameter_pairs(), testing::ElementsAre());
  240. EXPECT_THAT(uri->query_parameter_map(), testing::ElementsAre());
  241. EXPECT_EQ(uri->fragment(), "");
  242. EXPECT_EQ("http:path/to/file.html", uri->ToString());
  243. }
  244. TEST(URITest, AuthorityRelativePath) {
  245. auto uri =
  246. URI::Create("http", "server.example.com", "path/to/file.html", {}, "");
  247. ASSERT_FALSE(uri.ok());
  248. EXPECT_EQ(uri.status().code(), absl::StatusCode::kInvalidArgument);
  249. EXPECT_EQ(uri.status().message(),
  250. "if authority is present, path must start with a '/'");
  251. }
  252. TEST(URITest, QueryParams) {
  253. auto uri = URI::Create("http", "server.example.com", "/path/to/file.html",
  254. {{"key", "value"}, {"key2", "value2"}}, "");
  255. ASSERT_TRUE(uri.ok()) << uri.status().ToString();
  256. EXPECT_EQ(uri->scheme(), "http");
  257. EXPECT_EQ(uri->authority(), "server.example.com");
  258. EXPECT_EQ(uri->path(), "/path/to/file.html");
  259. EXPECT_THAT(
  260. uri->query_parameter_pairs(),
  261. testing::ElementsAre(
  262. testing::AllOf(testing::Field(&URI::QueryParam::key, "key"),
  263. testing::Field(&URI::QueryParam::value, "value")),
  264. testing::AllOf(testing::Field(&URI::QueryParam::key, "key2"),
  265. testing::Field(&URI::QueryParam::value, "value2"))));
  266. EXPECT_THAT(uri->query_parameter_map(),
  267. testing::ElementsAre(testing::Pair("key", "value"),
  268. testing::Pair("key2", "value2")));
  269. EXPECT_EQ(uri->fragment(), "");
  270. EXPECT_EQ("http://server.example.com/path/to/file.html?key=value&key2=value2",
  271. uri->ToString());
  272. }
  273. TEST(URITest, DuplicateQueryParams) {
  274. auto uri = URI::Create(
  275. "http", "server.example.com", "/path/to/file.html",
  276. {{"key", "value"}, {"key2", "value2"}, {"key", "other_value"}}, "");
  277. ASSERT_TRUE(uri.ok()) << uri.status().ToString();
  278. EXPECT_EQ(uri->scheme(), "http");
  279. EXPECT_EQ(uri->authority(), "server.example.com");
  280. EXPECT_EQ(uri->path(), "/path/to/file.html");
  281. EXPECT_THAT(
  282. uri->query_parameter_pairs(),
  283. testing::ElementsAre(
  284. testing::AllOf(testing::Field(&URI::QueryParam::key, "key"),
  285. testing::Field(&URI::QueryParam::value, "value")),
  286. testing::AllOf(testing::Field(&URI::QueryParam::key, "key2"),
  287. testing::Field(&URI::QueryParam::value, "value2")),
  288. testing::AllOf(
  289. testing::Field(&URI::QueryParam::key, "key"),
  290. testing::Field(&URI::QueryParam::value, "other_value"))));
  291. EXPECT_THAT(uri->query_parameter_map(),
  292. testing::ElementsAre(testing::Pair("key", "other_value"),
  293. testing::Pair("key2", "value2")));
  294. EXPECT_EQ(uri->fragment(), "");
  295. EXPECT_EQ(
  296. "http://server.example.com/path/to/file.html"
  297. "?key=value&key2=value2&key=other_value",
  298. uri->ToString());
  299. }
  300. TEST(URITest, Fragment) {
  301. auto uri = URI::Create("http", "server.example.com", "/path/to/file.html", {},
  302. "fragment");
  303. ASSERT_TRUE(uri.ok()) << uri.status().ToString();
  304. EXPECT_EQ(uri->scheme(), "http");
  305. EXPECT_EQ(uri->authority(), "server.example.com");
  306. EXPECT_EQ(uri->path(), "/path/to/file.html");
  307. EXPECT_THAT(uri->query_parameter_pairs(), testing::ElementsAre());
  308. EXPECT_THAT(uri->query_parameter_map(), testing::ElementsAre());
  309. EXPECT_EQ(uri->fragment(), "fragment");
  310. EXPECT_EQ("http://server.example.com/path/to/file.html#fragment",
  311. uri->ToString());
  312. }
  313. TEST(URITest, QueryParamsAndFragment) {
  314. auto uri = URI::Create("http", "server.example.com", "/path/to/file.html",
  315. {{"key", "value"}, {"key2", "value2"}}, "fragment");
  316. ASSERT_TRUE(uri.ok()) << uri.status().ToString();
  317. EXPECT_EQ(uri->scheme(), "http");
  318. EXPECT_EQ(uri->authority(), "server.example.com");
  319. EXPECT_EQ(uri->path(), "/path/to/file.html");
  320. EXPECT_THAT(
  321. uri->query_parameter_pairs(),
  322. testing::ElementsAre(
  323. testing::AllOf(testing::Field(&URI::QueryParam::key, "key"),
  324. testing::Field(&URI::QueryParam::value, "value")),
  325. testing::AllOf(testing::Field(&URI::QueryParam::key, "key2"),
  326. testing::Field(&URI::QueryParam::value, "value2"))));
  327. EXPECT_THAT(uri->query_parameter_map(),
  328. testing::ElementsAre(testing::Pair("key", "value"),
  329. testing::Pair("key2", "value2")));
  330. EXPECT_EQ(uri->fragment(), "fragment");
  331. EXPECT_EQ(
  332. "http://server.example.com/path/to/"
  333. "file.html?key=value&key2=value2#fragment",
  334. uri->ToString());
  335. }
  336. TEST(URITest, ToStringPercentEncoding) {
  337. auto uri = URI::Create(
  338. // Scheme allowed chars.
  339. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-."
  340. // Scheme escaped chars.
  341. "%:/?#[]@!$&'()*,;=",
  342. // Authority allowed chars.
  343. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  344. "-.+~!$&'()*+,;=:[]@"
  345. // Authority escaped chars.
  346. "%/?#",
  347. // Path allowed chars.
  348. "/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  349. "-._~!$&'()*+,;=:@"
  350. // Path escaped chars.
  351. "%?#[]",
  352. {{// Query allowed chars.
  353. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  354. "-._~!$'()*+,;:@/?"
  355. // Query escaped chars.
  356. "%=&#[]",
  357. // Query allowed chars.
  358. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  359. "-._~!$'()*+,;:@/?"
  360. // Query escaped chars.
  361. "%=&#[]"}},
  362. // Fragment allowed chars.
  363. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  364. "-._~!$'()*+,;:@/?=&"
  365. // Fragment escaped chars.
  366. "%#[]");
  367. ASSERT_TRUE(uri.ok()) << uri.status().ToString();
  368. EXPECT_EQ(uri->scheme(),
  369. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-."
  370. "%:/?#[]@!$&'()*,;=");
  371. EXPECT_EQ(uri->authority(),
  372. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  373. "-.+~!$&'()*+,;=:[]@"
  374. "%/?#");
  375. EXPECT_EQ(uri->path(),
  376. "/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  377. "-._~!$&'()*+,;=:@"
  378. "%?#[]");
  379. EXPECT_THAT(
  380. uri->query_parameter_pairs(),
  381. testing::ElementsAre(testing::AllOf(
  382. testing::Field(
  383. &URI::QueryParam::key,
  384. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  385. "-._~!$'()*+,;:@/?"
  386. "%=&#[]"),
  387. testing::Field(
  388. &URI::QueryParam::value,
  389. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  390. "-._~!$'()*+,;:@/?"
  391. "%=&#[]"))));
  392. EXPECT_THAT(
  393. uri->query_parameter_map(),
  394. testing::ElementsAre(testing::Pair(
  395. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  396. "-._~!$'()*+,;:@/?"
  397. "%=&#[]",
  398. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  399. "-._~!$'()*+,;:@/?"
  400. "%=&#[]")));
  401. EXPECT_EQ(uri->fragment(),
  402. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  403. "-._~!$'()*+,;:@/?=&"
  404. "%#[]");
  405. EXPECT_EQ(
  406. // Scheme
  407. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-."
  408. "%25%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2C%3B%3D"
  409. // Authority
  410. "://abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  411. "-.+~!$&'()*+,;=:[]@"
  412. "%25%2F%3F%23"
  413. // Path
  414. "/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  415. "-._~!$&'()*+,;=:@"
  416. "%25%3F%23%5B%5D"
  417. // Query
  418. "?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  419. "-._~!$'()*+,;:@/?"
  420. "%25%3D%26%23%5B%5D"
  421. "=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  422. "-._~!$'()*+,;:@/?"
  423. "%25%3D%26%23%5B%5D"
  424. // Fragment
  425. "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  426. "-._~!$'()*+,;:@/?=&"
  427. "%25%23%5B%5D",
  428. uri->ToString());
  429. }
  430. } // namespace grpc_core
  431. int main(int argc, char** argv) {
  432. testing::InitGoogleTest(&argc, argv);
  433. grpc::testing::TestEnvironment env(argc, argv);
  434. grpc_init();
  435. auto result = RUN_ALL_TESTS();
  436. grpc_shutdown();
  437. return result;
  438. }