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/browser/service_worker/service_worker_utils.h"
6 #include "testing/gtest/include/gtest/gtest.h"
12 bool IsPathRestrictionSatisfied(
13 const GURL
& scope
, const GURL
& script_url
) {
14 std::string error_message
;
15 return ServiceWorkerUtils::IsPathRestrictionSatisfied(
16 scope
, script_url
, nullptr, &error_message
);
19 bool IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
21 const GURL
& script_url
,
22 const std::string
& service_worker_allowed
) {
23 std::string error_message
;
24 return ServiceWorkerUtils::IsPathRestrictionSatisfied(
25 scope
, script_url
, &service_worker_allowed
, &error_message
);
30 TEST(ServiceWorkerUtilsTest
, ScopeMatches
) {
31 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
32 GURL("http://www.example.com/"), GURL("http://www.example.com/")));
33 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
34 GURL("http://www.example.com/"),
35 GURL("http://www.example.com/page.html")));
37 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
38 GURL("http://www.example.com/"), GURL("https://www.example.com/")));
39 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
40 GURL("http://www.example.com/"),
41 GURL("https://www.example.com/page.html")));
43 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
44 GURL("http://www.example.com/"), GURL("http://www.foo.com/")));
45 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
46 GURL("http://www.example.com/"), GURL("https://www.foo.com/page.html")));
48 // '*' is not a wildcard.
49 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
50 GURL("http://www.example.com/*"), GURL("http://www.example.com/x")));
51 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
52 GURL("http://www.example.com/*"), GURL("http://www.example.com/")));
53 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
54 GURL("http://www.example.com/*"), GURL("http://www.example.com/xx")));
55 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
56 GURL("http://www.example.com/*"), GURL("http://www.example.com/*")));
58 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
59 GURL("http://www.example.com/*/x"), GURL("http://www.example.com/*/x")));
60 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
61 GURL("http://www.example.com/*/x"), GURL("http://www.example.com/a/x")));
63 ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/*/x/*"),
64 GURL("http://www.example.com/a/x/b")));
66 ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/*/x/*"),
67 GURL("http://www.example.com/*/x/b")));
69 // '?' is not a wildcard.
70 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
71 GURL("http://www.example.com/?"), GURL("http://www.example.com/x")));
72 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
73 GURL("http://www.example.com/?"), GURL("http://www.example.com/")));
74 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
75 GURL("http://www.example.com/?"), GURL("http://www.example.com/xx")));
76 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
77 GURL("http://www.example.com/?"), GURL("http://www.example.com/?")));
79 // Query string is part of the resource.
81 ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/?a=b"),
82 GURL("http://www.example.com/?a=b")));
84 ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/?a="),
85 GURL("http://www.example.com/?a=b")));
86 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
87 GURL("http://www.example.com/"), GURL("http://www.example.com/?a=b")));
89 // URLs canonicalize \ to / so this is equivalent to "...//x"
90 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
91 GURL("http://www.example.com/\\x"), GURL("http://www.example.com//x")));
94 TEST(ServiceWorkerUtilsTest
, FindLongestScopeMatch
) {
95 LongestScopeMatcher
matcher(GURL("http://www.example.com/xxx"));
97 // "/xx" should be matched longest.
98 ASSERT_TRUE(matcher
.MatchLongest(GURL("http://www.example.com/x")));
99 ASSERT_FALSE(matcher
.MatchLongest(GURL("http://www.example.com/")));
100 ASSERT_TRUE(matcher
.MatchLongest(GURL("http://www.example.com/xx")));
102 // "/xxx" should be matched longer than "/xx".
103 ASSERT_TRUE(matcher
.MatchLongest(GURL("http://www.example.com/xxx")));
105 // The second call with the same URL should return false.
106 ASSERT_FALSE(matcher
.MatchLongest(GURL("http://www.example.com/xxx")));
108 ASSERT_FALSE(matcher
.MatchLongest(GURL("http://www.example.com/xxxx")));
111 TEST(ServiceWorkerUtilsTest
, PathRestriction_Basic
) {
112 EXPECT_TRUE(IsPathRestrictionSatisfied(
113 GURL("http://example.com/"),
114 GURL("http://example.com/sw.js")));
115 EXPECT_TRUE(IsPathRestrictionSatisfied(
116 GURL("http://example.com/foo/"),
117 GURL("http://example.com/sw.js")));
118 EXPECT_TRUE(IsPathRestrictionSatisfied(
119 GURL("http://example.com/foo/"),
120 GURL("http://example.com/foo/sw.js")));
121 EXPECT_TRUE(IsPathRestrictionSatisfied(
122 GURL("http://example.com/foo/bar"),
123 GURL("http://example.com/foo/sw.js")));
124 EXPECT_FALSE(IsPathRestrictionSatisfied(
125 GURL("http://example.com/"),
126 GURL("http://example.com/foo/sw.js")));
127 EXPECT_FALSE(IsPathRestrictionSatisfied(
128 GURL("http://example.com/bar/"),
129 GURL("http://example.com/foo/sw.js")));
131 // The scope is under the script directory, but that doesn't have the trailing
132 // slash. In this case, the check should be failed.
133 EXPECT_FALSE(IsPathRestrictionSatisfied(
134 GURL("http://example.com/foo"),
135 GURL("http://example.com/foo/sw.js")));
137 // Query parameters should not affect the path restriction.
138 EXPECT_TRUE(IsPathRestrictionSatisfied(
139 GURL("http://example.com/?query"),
140 GURL("http://example.com/sw.js")));
141 EXPECT_TRUE(IsPathRestrictionSatisfied(
142 GURL("http://example.com/foo/?query"),
143 GURL("http://example.com/sw.js")));
144 EXPECT_TRUE(IsPathRestrictionSatisfied(
145 GURL("http://example.com/foo/?query"),
146 GURL("http://example.com/foo/sw.js")));
147 EXPECT_FALSE(IsPathRestrictionSatisfied(
148 GURL("http://example.com/?query"),
149 GURL("http://example.com/foo/sw.js")));
150 EXPECT_FALSE(IsPathRestrictionSatisfied(
151 GURL("http://example.com/bar/query?"),
152 GURL("http://example.com/foo/sw.js")));
154 EXPECT_TRUE(IsPathRestrictionSatisfied(
155 GURL("http://example.com/"),
156 GURL("http://example.com/sw.js?query")));
157 EXPECT_TRUE(IsPathRestrictionSatisfied(
158 GURL("http://example.com/foo/"),
159 GURL("http://example.com/sw.js?query")));
160 EXPECT_TRUE(IsPathRestrictionSatisfied(
161 GURL("http://example.com/foo/"),
162 GURL("http://example.com/foo/sw.js?query")));
163 EXPECT_FALSE(IsPathRestrictionSatisfied(
164 GURL("http://example.com/"),
165 GURL("http://example.com/foo/sw.js?query")));
166 EXPECT_FALSE(IsPathRestrictionSatisfied(
167 GURL("http://example.com/bar/"),
168 GURL("http://example.com/foo/sw.js?query")));
170 // Query parameter including a slash should not affect.
171 EXPECT_TRUE(IsPathRestrictionSatisfied(
172 GURL("http://example.com/foo/bar?key/value"),
173 GURL("http://example.com/foo/sw.js?key=value")));
174 EXPECT_TRUE(IsPathRestrictionSatisfied(
175 GURL("http://example.com/foo/bar?key=value"),
176 GURL("http://example.com/foo/sw.js?key/value")));
179 TEST(ServiceWorkerUtils
, PathRestriction_SelfReference
) {
180 // Self reference is canonicalized.
181 ASSERT_EQ(GURL("http://example.com/foo/bar"),
182 GURL("http://example.com/././foo/bar"));
183 EXPECT_TRUE(IsPathRestrictionSatisfied(
184 GURL("http://example.com/foo/"),
185 GURL("http://example.com/././foo/sw.js")));
186 EXPECT_TRUE(IsPathRestrictionSatisfied(
187 GURL("http://example.com/././foo/"),
188 GURL("http://example.com/foo/sw.js")));
189 EXPECT_TRUE(IsPathRestrictionSatisfied(
190 GURL("http://example.com/foo/./"),
191 GURL("http://example.com/./foo/sw.js")));
193 // URL-encoded dot ('%2e') is also canonicalized.
194 ASSERT_EQ(GURL("http://example.com/foo/././bar"),
195 GURL("http://example.com/foo/%2e/%2e/bar"));
196 EXPECT_TRUE(IsPathRestrictionSatisfied(
197 GURL("http://example.com/foo/%2e/%2e/bar"),
198 GURL("http://example.com/foo/%2e/%2e/sw.js")));
199 EXPECT_TRUE(IsPathRestrictionSatisfied(
200 GURL("http://example.com/foo/bar"),
201 GURL("http://example.com/foo/%2e/%2e/sw.js")));
202 EXPECT_TRUE(IsPathRestrictionSatisfied(
203 GURL("http://example.com/foo/%2e/%2e/bar"),
204 GURL("http://example.com/foo/sw.js")));
205 EXPECT_TRUE(IsPathRestrictionSatisfied(
206 GURL("http://example.com/foo/%2e/bar"),
207 GURL("http://example.com/%2e/foo/sw.js")));
209 // URL-encoded dot ('%2E') is also canonicalized.
210 ASSERT_EQ(GURL("http://example.com/foo/././bar"),
211 GURL("http://example.com/foo/%2E/%2e/bar"));
214 TEST(ServiceWorkerUtilsTest
, PathRestriction_ParentReference
) {
215 // Parent reference is canonicalized.
216 ASSERT_EQ(GURL("http://example.com/foo/bar"),
217 GURL("http://example.com/foo/../foo/bar"));
218 EXPECT_TRUE(IsPathRestrictionSatisfied(
219 GURL("http://example.com/foo/bar"),
220 GURL("http://example.com/foo/../foo/sw.js")));
221 EXPECT_TRUE(IsPathRestrictionSatisfied(
222 GURL("http://example.com/foo/../foo/bar"),
223 GURL("http://example.com/foo/sw.js")));
224 EXPECT_TRUE(IsPathRestrictionSatisfied(
225 GURL("http://example.com/foo/bar/../bar"),
226 GURL("http://example.com/../foo/sw.js")));
227 EXPECT_TRUE(IsPathRestrictionSatisfied(
228 GURL("http://example.com/foo/../../../foo/bar"),
229 GURL("http://example.com/foo/sw.js")));
230 EXPECT_FALSE(IsPathRestrictionSatisfied(
231 GURL("http://example.com/foo/../bar"),
232 GURL("http://example.com/foo/sw.js")));
234 // URL-encoded dot ('%2e') is also canonicalized.
235 ASSERT_EQ(GURL("http://example.com/foo/../foo/bar"),
236 GURL("http://example.com/foo/%2e%2e/foo/bar"));
237 EXPECT_TRUE(IsPathRestrictionSatisfied(
238 GURL("http://example.com/foo/bar"),
239 GURL("http://example.com/foo/%2e%2e/foo/sw.js")));
240 EXPECT_TRUE(IsPathRestrictionSatisfied(
241 GURL("http://example.com/foo/%2e%2e/foo/bar"),
242 GURL("http://example.com/foo/sw.js")));
243 EXPECT_TRUE(IsPathRestrictionSatisfied(
244 GURL("http://example.com/foo/%2e%2e/foo/bar"),
245 GURL("http://example.com/%2e%2e/foo/sw.js")));
246 EXPECT_TRUE(IsPathRestrictionSatisfied(
247 GURL("http://example.com/foo/%2e%2e/%2e%2e/%2e%2e/foo/bar"),
248 GURL("http://example.com/foo/sw.js")));
249 EXPECT_FALSE(IsPathRestrictionSatisfied(
250 GURL("http://example.com/foo/%2e%2e/bar"),
251 GURL("http://example.com/foo/sw.js")));
253 // URL-encoded dot ('%2E') is also canonicalized.
254 ASSERT_EQ(GURL("http://example.com/foo/../foo/bar"),
255 GURL("http://example.com/foo/%2E%2E/foo/bar"));
258 TEST(ServiceWorkerUtilsTest
, PathRestriction_ConsecutiveSlashes
) {
259 // Consecutive slashes are not unified.
260 ASSERT_NE(GURL("http://example.com/foo/bar"),
261 GURL("http://example.com/foo///bar"));
262 EXPECT_FALSE(IsPathRestrictionSatisfied(
263 GURL("http://example.com/foo/bar"),
264 GURL("http://example.com/foo///sw.js")));
265 EXPECT_TRUE(IsPathRestrictionSatisfied(
266 GURL("http://example.com/foo///bar"),
267 GURL("http://example.com/foo/sw.js")));
268 EXPECT_TRUE(IsPathRestrictionSatisfied(
269 GURL("http://example.com/foo///bar"),
270 GURL("http://example.com/foo///sw.js")));
273 TEST(ServiceWorkerUtilsTest
, PathRestriction_BackSlash
) {
274 // A backslash is converted to a slash.
275 ASSERT_EQ(GURL("http://example.com/foo/bar"),
276 GURL("http://example.com/foo\\bar"));
277 EXPECT_TRUE(IsPathRestrictionSatisfied(
278 GURL("http://example.com/foo\\bar"),
279 GURL("http://example.com/foo/sw.js")));
281 // Consecutive back slashes should not unified.
282 ASSERT_NE(GURL("http://example.com/foo\\\\\\bar"),
283 GURL("http://example.com/foo\\bar"));
284 EXPECT_FALSE(IsPathRestrictionSatisfied(
285 GURL("http://example.com/foo\\bar"),
286 GURL("http://example.com/foo\\\\\\sw.js")));
287 EXPECT_TRUE(IsPathRestrictionSatisfied(
288 GURL("http://example.com/foo\\\\\\bar"),
289 GURL("http://example.com/foo\\sw.js")));
292 TEST(ServiceWorkerUtilsTest
, PathRestriction_DisallowedCharacter
) {
293 // URL-encoded slash ('%2f') is not canonicalized.
294 ASSERT_NE(GURL("http://example.com/foo///bar"),
295 GURL("http://example.com/foo/%2f/bar"));
296 EXPECT_FALSE(IsPathRestrictionSatisfied(
297 GURL("http://example.com/foo%2fbar/"),
298 GURL("http://example.com/foo/bar/sw.js")));
299 EXPECT_FALSE(IsPathRestrictionSatisfied(
300 GURL("http://example.com/foo/bar%2f"),
301 GURL("http://example.com/foo/bar/sw.js")));
302 EXPECT_FALSE(IsPathRestrictionSatisfied(
303 GURL("http://example.com/foo/bar/"),
304 GURL("http://example.com/foo/bar%2fsw.js")));
305 EXPECT_FALSE(IsPathRestrictionSatisfied(
306 GURL("http://example.com/foo/"),
307 GURL("http://example.com/foo/bar%2fsw.js")));
309 // URL-encoded slash ('%2F') is also not canonicalized.
310 ASSERT_NE(GURL("http://example.com/foo///bar"),
311 GURL("http://example.com/foo/%2F/bar"));
312 EXPECT_FALSE(IsPathRestrictionSatisfied(
313 GURL("http://example.com/foo%2Fbar/"),
314 GURL("http://example.com/foo/bar/sw.js")));
315 EXPECT_FALSE(IsPathRestrictionSatisfied(
316 GURL("http://example.com/foo/bar%2F"),
317 GURL("http://example.com/foo/bar/sw.js")));
318 EXPECT_FALSE(IsPathRestrictionSatisfied(
319 GURL("http://example.com/foo/bar/"),
320 GURL("http://example.com/foo/bar%2Fsw.js")));
321 EXPECT_FALSE(IsPathRestrictionSatisfied(
322 GURL("http://example.com/foo/"),
323 GURL("http://example.com/foo/bar%2Fsw.js")));
325 // URL-encoded backslash ('%5c') is not canonicalized.
326 ASSERT_NE(GURL("http://example.com/foo/\\/bar"),
327 GURL("http://example.com/foo/%5c/bar"));
328 EXPECT_FALSE(IsPathRestrictionSatisfied(
329 GURL("http://example.com/foo%5cbar/"),
330 GURL("http://example.com/foo/bar/sw.js")));
331 EXPECT_FALSE(IsPathRestrictionSatisfied(
332 GURL("http://example.com/foo/bar%5c"),
333 GURL("http://example.com/foo/bar/sw.js")));
334 EXPECT_FALSE(IsPathRestrictionSatisfied(
335 GURL("http://example.com/foo/bar/"),
336 GURL("http://example.com/foo/bar%5csw.js")));
337 EXPECT_FALSE(IsPathRestrictionSatisfied(
338 GURL("http://example.com/foo/"),
339 GURL("http://example.com/foo/bar%5csw.js")));
341 // URL-encoded backslash ('%5C') is also not canonicalized.
342 ASSERT_NE(GURL("http://example.com/foo/\\/bar"),
343 GURL("http://example.com/foo/%5C/bar"));
344 EXPECT_FALSE(IsPathRestrictionSatisfied(
345 GURL("http://example.com/foo%5Cbar/"),
346 GURL("http://example.com/foo/bar/sw.js")));
347 EXPECT_FALSE(IsPathRestrictionSatisfied(
348 GURL("http://example.com/foo/bar%5C"),
349 GURL("http://example.com/foo/bar/sw.js")));
350 EXPECT_FALSE(IsPathRestrictionSatisfied(
351 GURL("http://example.com/foo/bar/"),
352 GURL("http://example.com/foo/bar%5Csw.js")));
353 EXPECT_FALSE(IsPathRestrictionSatisfied(
354 GURL("http://example.com/foo/"),
355 GURL("http://example.com/foo/bar%5Csw.js")));
357 // Query parameter should be able to have escaped characters.
358 EXPECT_TRUE(IsPathRestrictionSatisfied(
359 GURL("http://example.com/foo/bar?key%2fvalue"),
360 GURL("http://example.com/foo/sw.js?key/value")));
361 EXPECT_TRUE(IsPathRestrictionSatisfied(
362 GURL("http://example.com/foo/bar?key/value"),
363 GURL("http://example.com/foo/sw.js?key%2fvalue")));
364 EXPECT_TRUE(IsPathRestrictionSatisfied(
365 GURL("http://example.com/foo/bar?key%5cvalue"),
366 GURL("http://example.com/foo/sw.js?key\\value")));
367 EXPECT_TRUE(IsPathRestrictionSatisfied(
368 GURL("http://example.com/foo/bar?key\\value"),
369 GURL("http://example.com/foo/sw.js?key%5cvalue")));
372 TEST(ServiceWorkerUtils
, PathRestriction_ServiceWorkerAllowed
) {
373 // Setting header to default max scope changes nothing.
374 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
375 GURL("http://example.com/"), GURL("http://example.com/sw.js"),
376 "http://example.com/"));
377 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
378 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js"),
379 "http://example.com/foo/"));
381 // Using the header to widen allowed scope.
382 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
383 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js"),
384 "http://example.com/"));
385 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
386 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js"), "/"));
387 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
388 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js"), ".."));
389 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
390 GURL("http://example.com/bar/"), GURL("http://example.com/foo/sw.js"),
392 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
393 GURL("http://example.com/bar/"), GURL("http://example.com/foo/sw.js"),
396 // Using the header to restrict allowed scope.
397 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
398 GURL("http://example.com/"), GURL("http://example.com/sw.js"),
399 "http://example.com/foo/"));
400 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
401 GURL("http://example.com/"), GURL("http://example.com/sw.js"), "foo"));
402 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
403 GURL("http://example.com/foo/"), GURL("http://example.com/sw.js"),
406 // Empty string resolves to max scope of "http://www.example.com/sw.js".
407 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
408 GURL("http://example.com/"), GURL("http://example.com/sw.js"), ""));
409 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
410 GURL("http://example.com/sw.js/hi"), GURL("http://example.com/sw.js"),
414 } // namespace content