2 * Copyright 2014 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <folly/Uri.h>
19 #include <boost/algorithm/string.hpp>
20 #include <glog/logging.h>
21 #include <gtest/gtest.h>
24 using namespace folly;
32 fbstring s("http://www.facebook.com/hello/world?query#fragment");
34 EXPECT_EQ("http", u.scheme());
35 EXPECT_EQ("", u.username());
36 EXPECT_EQ("", u.password());
37 EXPECT_EQ("www.facebook.com", u.host());
38 EXPECT_EQ(0, u.port());
39 EXPECT_EQ("www.facebook.com", u.authority());
40 EXPECT_EQ("/hello/world", u.path());
41 EXPECT_EQ("query", u.query());
42 EXPECT_EQ("fragment", u.fragment());
43 EXPECT_EQ(s, u.fbstr()); // canonical
47 fbstring s("http://www.facebook.com:8080/hello/world?query#fragment");
49 EXPECT_EQ("http", u.scheme());
50 EXPECT_EQ("", u.username());
51 EXPECT_EQ("", u.password());
52 EXPECT_EQ("www.facebook.com", u.host());
53 EXPECT_EQ(8080, u.port());
54 EXPECT_EQ("www.facebook.com:8080", u.authority());
55 EXPECT_EQ("/hello/world", u.path());
56 EXPECT_EQ("query", u.query());
57 EXPECT_EQ("fragment", u.fragment());
58 EXPECT_EQ(s, u.fbstr()); // canonical
62 fbstring s("http://127.0.0.1:8080/hello/world?query#fragment");
64 EXPECT_EQ("http", u.scheme());
65 EXPECT_EQ("", u.username());
66 EXPECT_EQ("", u.password());
67 EXPECT_EQ("127.0.0.1", u.host());
68 EXPECT_EQ(8080, u.port());
69 EXPECT_EQ("127.0.0.1:8080", u.authority());
70 EXPECT_EQ("/hello/world", u.path());
71 EXPECT_EQ("query", u.query());
72 EXPECT_EQ("fragment", u.fragment());
73 EXPECT_EQ(s, u.fbstr()); // canonical
77 fbstring s("http://[::1]:8080/hello/world?query#fragment");
79 EXPECT_EQ("http", u.scheme());
80 EXPECT_EQ("", u.username());
81 EXPECT_EQ("", u.password());
82 EXPECT_EQ("[::1]", u.host());
83 EXPECT_EQ("::1", u.hostname());
84 EXPECT_EQ(8080, u.port());
85 EXPECT_EQ("[::1]:8080", u.authority());
86 EXPECT_EQ("/hello/world", u.path());
87 EXPECT_EQ("query", u.query());
88 EXPECT_EQ("fragment", u.fragment());
89 EXPECT_EQ(s, u.fbstr()); // canonical
93 fbstring s("http://[2401:db00:20:7004:face:0:29:0]:8080/hello/world?query");
95 EXPECT_EQ("http", u.scheme());
96 EXPECT_EQ("", u.username());
97 EXPECT_EQ("", u.password());
98 EXPECT_EQ("[2401:db00:20:7004:face:0:29:0]", u.host());
99 EXPECT_EQ("2401:db00:20:7004:face:0:29:0", u.hostname());
100 EXPECT_EQ(8080, u.port());
101 EXPECT_EQ("[2401:db00:20:7004:face:0:29:0]:8080", u.authority());
102 EXPECT_EQ("/hello/world", u.path());
103 EXPECT_EQ("query", u.query());
104 EXPECT_EQ("", u.fragment());
105 EXPECT_EQ(s, u.fbstr()); // canonical
109 fbstring s("http://[2401:db00:20:7004:face:0:29:0]/hello/world?query");
111 EXPECT_EQ("http", u.scheme());
112 EXPECT_EQ("", u.username());
113 EXPECT_EQ("", u.password());
114 EXPECT_EQ("[2401:db00:20:7004:face:0:29:0]", u.host());
115 EXPECT_EQ("2401:db00:20:7004:face:0:29:0", u.hostname());
116 EXPECT_EQ(0, u.port());
117 EXPECT_EQ("[2401:db00:20:7004:face:0:29:0]", u.authority());
118 EXPECT_EQ("/hello/world", u.path());
119 EXPECT_EQ("query", u.query());
120 EXPECT_EQ("", u.fragment());
121 EXPECT_EQ(s, u.fbstr()); // canonical
125 fbstring s("http://user:pass@host.com/");
127 EXPECT_EQ("http", u.scheme());
128 EXPECT_EQ("user", u.username());
129 EXPECT_EQ("pass", u.password());
130 EXPECT_EQ("host.com", u.host());
131 EXPECT_EQ(0, u.port());
132 EXPECT_EQ("user:pass@host.com", u.authority());
133 EXPECT_EQ("/", u.path());
134 EXPECT_EQ("", u.query());
135 EXPECT_EQ("", u.fragment());
136 EXPECT_EQ(s, u.fbstr());
140 fbstring s("http://user@host.com/");
142 EXPECT_EQ("http", u.scheme());
143 EXPECT_EQ("user", u.username());
144 EXPECT_EQ("", u.password());
145 EXPECT_EQ("host.com", u.host());
146 EXPECT_EQ(0, u.port());
147 EXPECT_EQ("user@host.com", u.authority());
148 EXPECT_EQ("/", u.path());
149 EXPECT_EQ("", u.query());
150 EXPECT_EQ("", u.fragment());
151 EXPECT_EQ(s, u.fbstr());
155 fbstring s("http://user:@host.com/");
157 EXPECT_EQ("http", u.scheme());
158 EXPECT_EQ("user", u.username());
159 EXPECT_EQ("", u.password());
160 EXPECT_EQ("host.com", u.host());
161 EXPECT_EQ(0, u.port());
162 EXPECT_EQ("user@host.com", u.authority());
163 EXPECT_EQ("/", u.path());
164 EXPECT_EQ("", u.query());
165 EXPECT_EQ("", u.fragment());
166 EXPECT_EQ("http://user@host.com/", u.fbstr());
170 fbstring s("http://:pass@host.com/");
172 EXPECT_EQ("http", u.scheme());
173 EXPECT_EQ("", u.username());
174 EXPECT_EQ("pass", u.password());
175 EXPECT_EQ("host.com", u.host());
176 EXPECT_EQ(0, u.port());
177 EXPECT_EQ(":pass@host.com", u.authority());
178 EXPECT_EQ("/", u.path());
179 EXPECT_EQ("", u.query());
180 EXPECT_EQ("", u.fragment());
181 EXPECT_EQ(s, u.fbstr());
185 fbstring s("http://@host.com/");
187 EXPECT_EQ("http", u.scheme());
188 EXPECT_EQ("", u.username());
189 EXPECT_EQ("", u.password());
190 EXPECT_EQ("host.com", u.host());
191 EXPECT_EQ(0, u.port());
192 EXPECT_EQ("host.com", u.authority());
193 EXPECT_EQ("/", u.path());
194 EXPECT_EQ("", u.query());
195 EXPECT_EQ("", u.fragment());
196 EXPECT_EQ("http://host.com/", u.fbstr());
200 fbstring s("http://:@host.com/");
202 EXPECT_EQ("http", u.scheme());
203 EXPECT_EQ("", u.username());
204 EXPECT_EQ("", u.password());
205 EXPECT_EQ("host.com", u.host());
206 EXPECT_EQ(0, u.port());
207 EXPECT_EQ("host.com", u.authority());
208 EXPECT_EQ("/", u.path());
209 EXPECT_EQ("", u.query());
210 EXPECT_EQ("", u.fragment());
211 EXPECT_EQ("http://host.com/", u.fbstr());
215 fbstring s("file:///etc/motd");
217 EXPECT_EQ("file", u.scheme());
218 EXPECT_EQ("", u.username());
219 EXPECT_EQ("", u.password());
220 EXPECT_EQ("", u.host());
221 EXPECT_EQ(0, u.port());
222 EXPECT_EQ("", u.authority());
223 EXPECT_EQ("/etc/motd", u.path());
224 EXPECT_EQ("", u.query());
225 EXPECT_EQ("", u.fragment());
226 EXPECT_EQ(s, u.fbstr());
230 fbstring s("file:/etc/motd");
232 EXPECT_EQ("file", u.scheme());
233 EXPECT_EQ("", u.username());
234 EXPECT_EQ("", u.password());
235 EXPECT_EQ("", u.host());
236 EXPECT_EQ(0, u.port());
237 EXPECT_EQ("", u.authority());
238 EXPECT_EQ("/etc/motd", u.path());
239 EXPECT_EQ("", u.query());
240 EXPECT_EQ("", u.fragment());
241 EXPECT_EQ("file:///etc/motd", u.fbstr());
245 fbstring s("file://etc/motd");
247 EXPECT_EQ("file", u.scheme());
248 EXPECT_EQ("", u.username());
249 EXPECT_EQ("", u.password());
250 EXPECT_EQ("etc", u.host());
251 EXPECT_EQ(0, u.port());
252 EXPECT_EQ("etc", u.authority());
253 EXPECT_EQ("/motd", u.path());
254 EXPECT_EQ("", u.query());
255 EXPECT_EQ("", u.fragment());
256 EXPECT_EQ(s, u.fbstr());
260 // test query parameters
261 fbstring s("http://localhost?&key1=foo&key2=&key3&=bar&=bar=&");
263 auto paramsList = u.getQueryParams();
264 std::map<fbstring, fbstring> params;
265 for (auto& param : paramsList) {
266 params[param.first] = param.second;
268 EXPECT_EQ(3, params.size());
269 EXPECT_EQ("foo", params["key1"]);
270 EXPECT_NE(params.end(), params.find("key2"));
271 EXPECT_EQ("", params["key2"]);
272 EXPECT_NE(params.end(), params.find("key3"));
273 EXPECT_EQ("", params["key3"]);
277 // test query parameters
278 fbstring s("http://localhost?&&&&&&&&&&&&&&&");
280 auto params = u.getQueryParams();
281 EXPECT_TRUE(params.empty());
285 // test query parameters
286 fbstring s("http://localhost?&=invalid_key&key2&key3=foo");
288 auto paramsList = u.getQueryParams();
289 std::map<fbstring, fbstring> params;
290 for (auto& param : paramsList) {
291 params[param.first] = param.second;
293 EXPECT_EQ(2, params.size());
294 EXPECT_NE(params.end(), params.find("key2"));
295 EXPECT_EQ("", params["key2"]);
296 EXPECT_EQ("foo", params["key3"]);
300 // test query parameters
301 fbstring s("http://localhost?&key1=====&&=key2&key3=");
303 auto paramsList = u.getQueryParams();
304 std::map<fbstring, fbstring> params;
305 for (auto& param : paramsList) {
306 params[param.first] = param.second;
308 EXPECT_EQ(1, params.size());
309 EXPECT_NE(params.end(), params.find("key3"));
310 EXPECT_EQ("", params["key3"]);
314 // test query parameters
315 fbstring s("http://localhost?key1=foo=bar&key2=foobar&");
317 auto paramsList = u.getQueryParams();
318 std::map<fbstring, fbstring> params;
319 for (auto& param : paramsList) {
320 params[param.first] = param.second;
322 EXPECT_EQ(1, params.size());
323 EXPECT_EQ("foobar", params["key2"]);
327 fbstring s("2http://www.facebook.com");
331 CHECK(false) << "Control should not have reached here";
332 } catch (const std::invalid_argument& ex) {
333 EXPECT_TRUE(boost::algorithm::ends_with(ex.what(), s));
338 fbstring s("www[facebook]com");
341 Uri u("http://" + s);
342 CHECK(false) << "Control should not have reached here";
343 } catch (const std::invalid_argument& ex) {
344 EXPECT_TRUE(boost::algorithm::ends_with(ex.what(), s));
349 fbstring s("http://[::1:8080/hello/world?query#fragment");
353 CHECK(false) << "Control should not have reached here";
354 } catch (const std::invalid_argument& ex) {
360 fbstring s("http://::1]:8080/hello/world?query#fragment");
364 CHECK(false) << "Control should not have reached here";
365 } catch (const std::invalid_argument& ex) {
371 fbstring s("http://::1:8080/hello/world?query#fragment");
375 CHECK(false) << "Control should not have reached here";
376 } catch (const std::invalid_argument& ex) {
382 fbstring s("http://2401:db00:20:7004:face:0:29:0/hello/world?query");
386 CHECK(false) << "Control should not have reached here";
387 } catch (const std::invalid_argument& ex) {