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"
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::StartsWithASCII(url
.spec(), scope
.spec(), true);
43 bool ServiceWorkerUtils::IsPathRestrictionSatisfied(
45 const GURL
& script_url
,
46 const std::string
* service_worker_allowed_header_value
,
47 std::string
* error_message
) {
48 DCHECK(scope
.is_valid());
49 DCHECK(!scope
.has_ref());
50 DCHECK(script_url
.is_valid());
51 DCHECK(!script_url
.has_ref());
52 DCHECK(error_message
);
54 if (ContainsDisallowedCharacter(scope
, script_url
, error_message
))
57 std::string max_scope_string
;
58 if (service_worker_allowed_header_value
) {
59 GURL max_scope
= script_url
.Resolve(*service_worker_allowed_header_value
);
60 if (!max_scope
.is_valid()) {
61 *error_message
= "An invalid Service-Worker-Allowed header value ('";
62 error_message
->append(*service_worker_allowed_header_value
);
63 error_message
->append("') was received when fetching the script.");
66 max_scope_string
= max_scope
.path();
68 max_scope_string
= script_url
.Resolve(".").path();
71 std::string scope_string
= scope
.path();
72 if (!base::StartsWithASCII(scope_string
, max_scope_string
, true)) {
73 *error_message
= "The path of the provided scope ('";
74 error_message
->append(scope_string
);
75 error_message
->append("') is not under the max scope allowed (");
76 if (service_worker_allowed_header_value
)
77 error_message
->append("set by Service-Worker-Allowed: ");
78 error_message
->append("'");
79 error_message
->append(max_scope_string
);
80 error_message
->append(
81 "'). Adjust the scope, move the Service Worker script, or use the "
82 "Service-Worker-Allowed HTTP header to allow the scope.");
89 bool ServiceWorkerUtils::ContainsDisallowedCharacter(
91 const GURL
& script_url
,
92 std::string
* error_message
) {
93 if (PathContainsDisallowedCharacter(scope
) ||
94 PathContainsDisallowedCharacter(script_url
)) {
95 *error_message
= "The provided scope ('";
96 error_message
->append(scope
.spec());
97 error_message
->append("') or scriptURL ('");
98 error_message
->append(script_url
.spec());
99 error_message
->append("') includes a disallowed escape character.");
105 bool LongestScopeMatcher::MatchLongest(const GURL
& scope
) {
106 if (!ServiceWorkerUtils::ScopeMatches(scope
, url_
))
108 if (match_
.is_empty() || match_
.spec().size() < scope
.spec().size()) {
115 } // namespace content