| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "content/browser/service_worker/service_worker_utils.h" | |
| 6 | |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "base/strings/string_util.h" | |
| 11 | |
| 12 namespace content { | |
| 13 | |
| 14 namespace { | |
| 15 | |
| 16 bool PathContainsDisallowedCharacter(const GURL& url) { | |
| 17 std::string path = url.path(); | |
| 18 DCHECK(base::IsStringUTF8(path)); | |
| 19 | |
| 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) { | |
| 24 return true; | |
| 25 } | |
| 26 if (path.find("%5c") != std::string::npos || | |
| 27 path.find("%5C") != std::string::npos) { | |
| 28 return true; | |
| 29 } | |
| 30 return false; | |
| 31 } | |
| 32 | |
| 33 } // namespace | |
| 34 | |
| 35 // static | |
| 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); | |
| 41 } | |
| 42 | |
| 43 // static | |
| 44 bool ServiceWorkerUtils::IsPathRestrictionSatisfied( | |
| 45 const GURL& scope, | |
| 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); | |
| 54 | |
| 55 if (ContainsDisallowedCharacter(scope, script_url, error_message)) | |
| 56 return false; | |
| 57 | |
| 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."); | |
| 65 return false; | |
| 66 } | |
| 67 max_scope_string = max_scope.path(); | |
| 68 } else { | |
| 69 max_scope_string = script_url.Resolve(".").path(); | |
| 70 } | |
| 71 | |
| 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."); | |
| 85 return false; | |
| 86 } | |
| 87 return true; | |
| 88 } | |
| 89 | |
| 90 // static | |
| 91 bool ServiceWorkerUtils::ContainsDisallowedCharacter( | |
| 92 const GURL& scope, | |
| 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."); | |
| 102 return true; | |
| 103 } | |
| 104 return false; | |
| 105 } | |
| 106 | |
| 107 bool LongestScopeMatcher::MatchLongest(const GURL& scope) { | |
| 108 if (!ServiceWorkerUtils::ScopeMatches(scope, url_)) | |
| 109 return false; | |
| 110 if (match_.is_empty() || match_.spec().size() < scope.spec().size()) { | |
| 111 match_ = scope; | |
| 112 return true; | |
| 113 } | |
| 114 return false; | |
| 115 } | |
| 116 | |
| 117 } // namespace content | |
| OLD | NEW |