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