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"
9 #include "base/logging.h"
10 #include "base/strings/string_util.h"
16 bool PathContainsDisallowedCharacter(const GURL
& url
) {
17 std::string path
= url
.path();
18 DCHECK(base::IsStringUTF8(path
));
20 // We should avoid these escaped characters in the path component because
21 // these can be handled differently depending on server implementation.
22 if (path
.find("%2f") != std::string::npos
||
23 path
.find("%2F") != std::string::npos
) {
26 if (path
.find("%5c") != std::string::npos
||
27 path
.find("%5C") != std::string::npos
) {
36 bool ServiceWorkerUtils::ScopeMatches(const GURL
& scope
, const GURL
& url
) {
37 DCHECK(!scope
.has_ref());
38 DCHECK(!url
.has_ref());
39 return base::StartsWith(url
.spec(), scope
.spec(),
40 base::CompareCase::SENSITIVE
);
44 bool ServiceWorkerUtils::IsPathRestrictionSatisfied(
46 const GURL
& script_url
,
47 const std::string
* service_worker_allowed_header_value
,
48 std::string
* error_message
) {
49 DCHECK(scope
.is_valid());
50 DCHECK(!scope
.has_ref());
51 DCHECK(script_url
.is_valid());
52 DCHECK(!script_url
.has_ref());
53 DCHECK(error_message
);
55 if (ContainsDisallowedCharacter(scope
, script_url
, error_message
))
58 std::string max_scope_string
;
59 if (service_worker_allowed_header_value
) {
60 GURL max_scope
= script_url
.Resolve(*service_worker_allowed_header_value
);
61 if (!max_scope
.is_valid()) {
62 *error_message
= "An invalid Service-Worker-Allowed header value ('";
63 error_message
->append(*service_worker_allowed_header_value
);
64 error_message
->append("') was received when fetching the script.");
67 max_scope_string
= max_scope
.path();
69 max_scope_string
= script_url
.Resolve(".").path();
72 std::string scope_string
= scope
.path();
73 if (!base::StartsWith(scope_string
, max_scope_string
,
74 base::CompareCase::SENSITIVE
)) {
75 *error_message
= "The path of the provided scope ('";
76 error_message
->append(scope_string
);
77 error_message
->append("') is not under the max scope allowed (");
78 if (service_worker_allowed_header_value
)
79 error_message
->append("set by Service-Worker-Allowed: ");
80 error_message
->append("'");
81 error_message
->append(max_scope_string
);
82 error_message
->append(
83 "'). Adjust the scope, move the Service Worker script, or use the "
84 "Service-Worker-Allowed HTTP header to allow the scope.");
91 bool ServiceWorkerUtils::ContainsDisallowedCharacter(
93 const GURL
& script_url
,
94 std::string
* error_message
) {
95 if (PathContainsDisallowedCharacter(scope
) ||
96 PathContainsDisallowedCharacter(script_url
)) {
97 *error_message
= "The provided scope ('";
98 error_message
->append(scope
.spec());
99 error_message
->append("') or scriptURL ('");
100 error_message
->append(script_url
.spec());
101 error_message
->append("') includes a disallowed escape character.");
107 bool LongestScopeMatcher::MatchLongest(const GURL
& scope
) {
108 if (!ServiceWorkerUtils::ScopeMatches(scope
, url_
))
110 if (match_
.is_empty() || match_
.spec().size() < scope
.spec().size()) {
117 } // namespace content