1 // Copyright 2014 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.
5 #include "content/common/service_worker/service_worker_utils.h"
6 #include "testing/gtest/include/gtest/gtest.h"
12 bool IsPathRestrictionSatisfied(const GURL
& scope
, const GURL
& script_url
) {
13 std::string error_message
;
14 return ServiceWorkerUtils::IsPathRestrictionSatisfied(
15 scope
, script_url
, nullptr, &error_message
);
18 bool IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
20 const GURL
& script_url
,
21 const std::string
& service_worker_allowed
) {
22 std::string error_message
;
23 return ServiceWorkerUtils::IsPathRestrictionSatisfied(
24 scope
, script_url
, &service_worker_allowed
, &error_message
);
29 TEST(ServiceWorkerUtilsTest
, ScopeMatches
) {
30 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
31 GURL("http://www.example.com/"), GURL("http://www.example.com/")));
32 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
33 GURL("http://www.example.com/"),
34 GURL("http://www.example.com/page.html")));
36 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
37 GURL("http://www.example.com/"), GURL("https://www.example.com/")));
38 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
39 GURL("http://www.example.com/"),
40 GURL("https://www.example.com/page.html")));
42 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/"),
43 GURL("http://www.foo.com/")));
44 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
45 GURL("http://www.example.com/"), GURL("https://www.foo.com/page.html")));
47 // '*' is not a wildcard.
48 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
49 GURL("http://www.example.com/*"), GURL("http://www.example.com/x")));
50 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
51 GURL("http://www.example.com/*"), GURL("http://www.example.com/")));
52 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
53 GURL("http://www.example.com/*"), GURL("http://www.example.com/xx")));
54 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
55 GURL("http://www.example.com/*"), GURL("http://www.example.com/*")));
57 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
58 GURL("http://www.example.com/*/x"), GURL("http://www.example.com/*/x")));
59 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
60 GURL("http://www.example.com/*/x"), GURL("http://www.example.com/a/x")));
62 ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/*/x/*"),
63 GURL("http://www.example.com/a/x/b")));
65 ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/*/x/*"),
66 GURL("http://www.example.com/*/x/b")));
68 // '?' is not a wildcard.
69 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
70 GURL("http://www.example.com/?"), GURL("http://www.example.com/x")));
71 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
72 GURL("http://www.example.com/?"), GURL("http://www.example.com/")));
73 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
74 GURL("http://www.example.com/?"), GURL("http://www.example.com/xx")));
75 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
76 GURL("http://www.example.com/?"), GURL("http://www.example.com/?")));
78 // Query string is part of the resource.
80 ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/?a=b"),
81 GURL("http://www.example.com/?a=b")));
82 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
83 GURL("http://www.example.com/?a="), GURL("http://www.example.com/?a=b")));
84 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
85 GURL("http://www.example.com/"), GURL("http://www.example.com/?a=b")));
87 // URLs canonicalize \ to / so this is equivalent to "...//x"
88 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
89 GURL("http://www.example.com/\\x"), GURL("http://www.example.com//x")));
92 TEST(ServiceWorkerUtilsTest
, FindLongestScopeMatch
) {
93 LongestScopeMatcher
matcher(GURL("http://www.example.com/xxx"));
95 // "/xx" should be matched longest.
96 ASSERT_TRUE(matcher
.MatchLongest(GURL("http://www.example.com/x")));
97 ASSERT_FALSE(matcher
.MatchLongest(GURL("http://www.example.com/")));
98 ASSERT_TRUE(matcher
.MatchLongest(GURL("http://www.example.com/xx")));
100 // "/xxx" should be matched longer than "/xx".
101 ASSERT_TRUE(matcher
.MatchLongest(GURL("http://www.example.com/xxx")));
103 // The second call with the same URL should return false.
104 ASSERT_FALSE(matcher
.MatchLongest(GURL("http://www.example.com/xxx")));
106 ASSERT_FALSE(matcher
.MatchLongest(GURL("http://www.example.com/xxxx")));
109 TEST(ServiceWorkerUtilsTest
, PathRestriction_Basic
) {
110 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/"),
111 GURL("http://example.com/sw.js")));
112 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
113 GURL("http://example.com/sw.js")));
114 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
115 GURL("http://example.com/foo/sw.js")));
116 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar"),
117 GURL("http://example.com/foo/sw.js")));
118 EXPECT_FALSE(IsPathRestrictionSatisfied(
119 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js")));
120 EXPECT_FALSE(IsPathRestrictionSatisfied(
121 GURL("http://example.com/bar/"), GURL("http://example.com/foo/sw.js")));
123 // The scope is under the script directory, but that doesn't have the trailing
124 // slash. In this case, the check should be failed.
125 EXPECT_FALSE(IsPathRestrictionSatisfied(
126 GURL("http://example.com/foo"), GURL("http://example.com/foo/sw.js")));
128 // Query parameters should not affect the path restriction.
129 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/?query"),
130 GURL("http://example.com/sw.js")));
131 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo/?query"),
132 GURL("http://example.com/sw.js")));
133 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo/?query"),
134 GURL("http://example.com/foo/sw.js")));
135 EXPECT_FALSE(IsPathRestrictionSatisfied(
136 GURL("http://example.com/?query"), GURL("http://example.com/foo/sw.js")));
138 IsPathRestrictionSatisfied(GURL("http://example.com/bar/query?"),
139 GURL("http://example.com/foo/sw.js")));
141 EXPECT_TRUE(IsPathRestrictionSatisfied(
142 GURL("http://example.com/"), GURL("http://example.com/sw.js?query")));
143 EXPECT_TRUE(IsPathRestrictionSatisfied(
144 GURL("http://example.com/foo/"), GURL("http://example.com/sw.js?query")));
146 IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
147 GURL("http://example.com/foo/sw.js?query")));
148 EXPECT_FALSE(IsPathRestrictionSatisfied(
149 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js?query")));
151 IsPathRestrictionSatisfied(GURL("http://example.com/bar/"),
152 GURL("http://example.com/foo/sw.js?query")));
154 // Query parameter including a slash should not affect.
155 EXPECT_TRUE(IsPathRestrictionSatisfied(
156 GURL("http://example.com/foo/bar?key/value"),
157 GURL("http://example.com/foo/sw.js?key=value")));
158 EXPECT_TRUE(IsPathRestrictionSatisfied(
159 GURL("http://example.com/foo/bar?key=value"),
160 GURL("http://example.com/foo/sw.js?key/value")));
163 TEST(ServiceWorkerUtils
, PathRestriction_SelfReference
) {
164 // Self reference is canonicalized.
165 ASSERT_EQ(GURL("http://example.com/foo/bar"),
166 GURL("http://example.com/././foo/bar"));
168 IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
169 GURL("http://example.com/././foo/sw.js")));
170 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/././foo/"),
171 GURL("http://example.com/foo/sw.js")));
173 IsPathRestrictionSatisfied(GURL("http://example.com/foo/./"),
174 GURL("http://example.com/./foo/sw.js")));
176 // URL-encoded dot ('%2e') is also canonicalized.
177 ASSERT_EQ(GURL("http://example.com/foo/././bar"),
178 GURL("http://example.com/foo/%2e/%2e/bar"));
180 IsPathRestrictionSatisfied(GURL("http://example.com/foo/%2e/%2e/bar"),
181 GURL("http://example.com/foo/%2e/%2e/sw.js")));
183 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar"),
184 GURL("http://example.com/foo/%2e/%2e/sw.js")));
186 IsPathRestrictionSatisfied(GURL("http://example.com/foo/%2e/%2e/bar"),
187 GURL("http://example.com/foo/sw.js")));
189 IsPathRestrictionSatisfied(GURL("http://example.com/foo/%2e/bar"),
190 GURL("http://example.com/%2e/foo/sw.js")));
192 // URL-encoded dot ('%2E') is also canonicalized.
193 ASSERT_EQ(GURL("http://example.com/foo/././bar"),
194 GURL("http://example.com/foo/%2E/%2e/bar"));
197 TEST(ServiceWorkerUtilsTest
, PathRestriction_ParentReference
) {
198 // Parent reference is canonicalized.
199 ASSERT_EQ(GURL("http://example.com/foo/bar"),
200 GURL("http://example.com/foo/../foo/bar"));
202 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar"),
203 GURL("http://example.com/foo/../foo/sw.js")));
205 IsPathRestrictionSatisfied(GURL("http://example.com/foo/../foo/bar"),
206 GURL("http://example.com/foo/sw.js")));
208 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar/../bar"),
209 GURL("http://example.com/../foo/sw.js")));
210 EXPECT_TRUE(IsPathRestrictionSatisfied(
211 GURL("http://example.com/foo/../../../foo/bar"),
212 GURL("http://example.com/foo/sw.js")));
214 IsPathRestrictionSatisfied(GURL("http://example.com/foo/../bar"),
215 GURL("http://example.com/foo/sw.js")));
217 // URL-encoded dot ('%2e') is also canonicalized.
218 ASSERT_EQ(GURL("http://example.com/foo/../foo/bar"),
219 GURL("http://example.com/foo/%2e%2e/foo/bar"));
220 EXPECT_TRUE(IsPathRestrictionSatisfied(
221 GURL("http://example.com/foo/bar"),
222 GURL("http://example.com/foo/%2e%2e/foo/sw.js")));
224 IsPathRestrictionSatisfied(GURL("http://example.com/foo/%2e%2e/foo/bar"),
225 GURL("http://example.com/foo/sw.js")));
227 IsPathRestrictionSatisfied(GURL("http://example.com/foo/%2e%2e/foo/bar"),
228 GURL("http://example.com/%2e%2e/foo/sw.js")));
229 EXPECT_TRUE(IsPathRestrictionSatisfied(
230 GURL("http://example.com/foo/%2e%2e/%2e%2e/%2e%2e/foo/bar"),
231 GURL("http://example.com/foo/sw.js")));
233 IsPathRestrictionSatisfied(GURL("http://example.com/foo/%2e%2e/bar"),
234 GURL("http://example.com/foo/sw.js")));
236 // URL-encoded dot ('%2E') is also canonicalized.
237 ASSERT_EQ(GURL("http://example.com/foo/../foo/bar"),
238 GURL("http://example.com/foo/%2E%2E/foo/bar"));
241 TEST(ServiceWorkerUtilsTest
, PathRestriction_ConsecutiveSlashes
) {
242 // Consecutive slashes are not unified.
243 ASSERT_NE(GURL("http://example.com/foo/bar"),
244 GURL("http://example.com/foo///bar"));
246 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar"),
247 GURL("http://example.com/foo///sw.js")));
248 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo///bar"),
249 GURL("http://example.com/foo/sw.js")));
251 IsPathRestrictionSatisfied(GURL("http://example.com/foo///bar"),
252 GURL("http://example.com/foo///sw.js")));
255 TEST(ServiceWorkerUtilsTest
, PathRestriction_BackSlash
) {
256 // A backslash is converted to a slash.
257 ASSERT_EQ(GURL("http://example.com/foo/bar"),
258 GURL("http://example.com/foo\\bar"));
259 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo\\bar"),
260 GURL("http://example.com/foo/sw.js")));
262 // Consecutive back slashes should not unified.
263 ASSERT_NE(GURL("http://example.com/foo\\\\\\bar"),
264 GURL("http://example.com/foo\\bar"));
266 IsPathRestrictionSatisfied(GURL("http://example.com/foo\\bar"),
267 GURL("http://example.com/foo\\\\\\sw.js")));
269 IsPathRestrictionSatisfied(GURL("http://example.com/foo\\\\\\bar"),
270 GURL("http://example.com/foo\\sw.js")));
273 TEST(ServiceWorkerUtilsTest
, PathRestriction_DisallowedCharacter
) {
274 // URL-encoded slash ('%2f') is not canonicalized.
275 ASSERT_NE(GURL("http://example.com/foo///bar"),
276 GURL("http://example.com/foo/%2f/bar"));
278 IsPathRestrictionSatisfied(GURL("http://example.com/foo%2fbar/"),
279 GURL("http://example.com/foo/bar/sw.js")));
281 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar%2f"),
282 GURL("http://example.com/foo/bar/sw.js")));
284 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar/"),
285 GURL("http://example.com/foo/bar%2fsw.js")));
287 IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
288 GURL("http://example.com/foo/bar%2fsw.js")));
290 // URL-encoded slash ('%2F') is also not canonicalized.
291 ASSERT_NE(GURL("http://example.com/foo///bar"),
292 GURL("http://example.com/foo/%2F/bar"));
294 IsPathRestrictionSatisfied(GURL("http://example.com/foo%2Fbar/"),
295 GURL("http://example.com/foo/bar/sw.js")));
297 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar%2F"),
298 GURL("http://example.com/foo/bar/sw.js")));
300 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar/"),
301 GURL("http://example.com/foo/bar%2Fsw.js")));
303 IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
304 GURL("http://example.com/foo/bar%2Fsw.js")));
306 // URL-encoded backslash ('%5c') is not canonicalized.
307 ASSERT_NE(GURL("http://example.com/foo/\\/bar"),
308 GURL("http://example.com/foo/%5c/bar"));
310 IsPathRestrictionSatisfied(GURL("http://example.com/foo%5cbar/"),
311 GURL("http://example.com/foo/bar/sw.js")));
313 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar%5c"),
314 GURL("http://example.com/foo/bar/sw.js")));
316 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar/"),
317 GURL("http://example.com/foo/bar%5csw.js")));
319 IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
320 GURL("http://example.com/foo/bar%5csw.js")));
322 // URL-encoded backslash ('%5C') is also not canonicalized.
323 ASSERT_NE(GURL("http://example.com/foo/\\/bar"),
324 GURL("http://example.com/foo/%5C/bar"));
326 IsPathRestrictionSatisfied(GURL("http://example.com/foo%5Cbar/"),
327 GURL("http://example.com/foo/bar/sw.js")));
329 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar%5C"),
330 GURL("http://example.com/foo/bar/sw.js")));
332 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar/"),
333 GURL("http://example.com/foo/bar%5Csw.js")));
335 IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
336 GURL("http://example.com/foo/bar%5Csw.js")));
338 // Query parameter should be able to have escaped characters.
339 EXPECT_TRUE(IsPathRestrictionSatisfied(
340 GURL("http://example.com/foo/bar?key%2fvalue"),
341 GURL("http://example.com/foo/sw.js?key/value")));
342 EXPECT_TRUE(IsPathRestrictionSatisfied(
343 GURL("http://example.com/foo/bar?key/value"),
344 GURL("http://example.com/foo/sw.js?key%2fvalue")));
345 EXPECT_TRUE(IsPathRestrictionSatisfied(
346 GURL("http://example.com/foo/bar?key%5cvalue"),
347 GURL("http://example.com/foo/sw.js?key\\value")));
348 EXPECT_TRUE(IsPathRestrictionSatisfied(
349 GURL("http://example.com/foo/bar?key\\value"),
350 GURL("http://example.com/foo/sw.js?key%5cvalue")));
353 TEST(ServiceWorkerUtils
, PathRestriction_ServiceWorkerAllowed
) {
354 // Setting header to default max scope changes nothing.
355 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
356 GURL("http://example.com/"), GURL("http://example.com/sw.js"),
357 "http://example.com/"));
358 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
359 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js"),
360 "http://example.com/foo/"));
362 // Using the header to widen allowed scope.
363 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
364 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js"),
365 "http://example.com/"));
366 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
367 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js"), "/"));
368 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
369 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js"), ".."));
370 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
371 GURL("http://example.com/bar/"), GURL("http://example.com/foo/sw.js"),
373 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
374 GURL("http://example.com/bar/"), GURL("http://example.com/foo/sw.js"),
377 // Using the header to restrict allowed scope.
378 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
379 GURL("http://example.com/"), GURL("http://example.com/sw.js"),
380 "http://example.com/foo/"));
381 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
382 GURL("http://example.com/"), GURL("http://example.com/sw.js"), "foo"));
383 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
384 GURL("http://example.com/foo/"), GURL("http://example.com/sw.js"),
387 // Empty string resolves to max scope of "http://www.example.com/sw.js".
388 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
389 GURL("http://example.com/"), GURL("http://example.com/sw.js"), ""));
390 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
391 GURL("http://example.com/sw.js/hi"), GURL("http://example.com/sw.js"),
395 } // namespace content