Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1497)

Unified Diff: chrome/common/extensions/url_pattern.cc

Issue 19704: Introduce UrlPattern. (Closed)
Patch Set: more feedback Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/url_pattern.cc
diff --git a/chrome/common/extensions/url_pattern.cc b/chrome/common/extensions/url_pattern.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bb32cb57f41e0d751dc25de4e01f19da47b721d9
--- /dev/null
+++ b/chrome/common/extensions/url_pattern.cc
@@ -0,0 +1,128 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/string_piece.h"
+#include "base/string_util.h"
+#include "chrome/common/extensions/url_pattern.h"
+
+// TODO(aa): Consider adding chrome-extension? What about more obscure ones
+// like data: and javascript: ?
+static const char* kValidSchemes[] = {
+ "http",
+ "https",
+ "file",
+ "ftp",
+ "chrome-ui"
+};
+
+static const char kSchemeSeparator[] = "://";
+static const char kPathSeparator[] = "/";
+
+static bool IsValidScheme(const std::string& scheme) {
+ for (size_t i = 0; i < arraysize(kValidSchemes); ++i) {
+ if (scheme == kValidSchemes[i])
+ return true;
+ }
+
+ return false;
+}
+
+bool URLPattern::Parse(const std::string& pattern) {
+ size_t scheme_end_pos = pattern.find(kSchemeSeparator);
+ if (scheme_end_pos == std::string::npos)
+ return false;
+
+ scheme_ = pattern.substr(0, scheme_end_pos);
+ if (!IsValidScheme(scheme_))
+ return false;
+
+ size_t host_start_pos = scheme_end_pos + strlen(kSchemeSeparator);
+ if (host_start_pos >= pattern.length())
+ return false;
+
+ // Parse out the host and path.
+ size_t path_start_pos = 0;
+
+ // File URLs are special because they have no host. There are other schemes
+ // with the same structure, but we don't support them (yet).
+ if (scheme_ == "file") {
+ path_start_pos = host_start_pos;
+ } else {
+ size_t host_end_pos = pattern.find(kPathSeparator, host_start_pos);
+ if (host_end_pos == std::string::npos)
+ return false;
+
+ host_ = pattern.substr(host_start_pos, host_end_pos - host_start_pos);
+
+ // The first component can optionally be '*' to match all subdomains.
+ std::vector<std::string> host_components;
+ SplitString(host_, '.', &host_components);
+ if (host_components[0] == "*") {
+ match_subdomains_ = true;
+ host_components.erase(host_components.begin(),
+ host_components.begin() + 1);
+ }
+ host_ = JoinString(host_components, '.');
+
+ // No other '*' can occur in the host, though. This isn't necessary, but is
+ // done as a convenience to developers who might otherwise be confused and
+ // think '*' works as a glob in the host.
+ if (host_.find('*') != std::string::npos)
+ return false;
+
+ path_start_pos = host_end_pos;
+ }
+
+ path_ = pattern.substr(path_start_pos);
+ return true;
+}
+
+bool URLPattern::MatchesUrl(const GURL &test) {
+ if (test.scheme() != scheme_)
+ return false;
+
+ if (!MatchesHost(test))
+ return false;
+
+ if (!MatchesPath(test))
+ return false;
+
+ return true;
+}
+
+bool URLPattern::MatchesHost(const GURL& test) {
+ if (test.host() == host_)
+ return true;
+
+ if (!match_subdomains_ || test.HostIsIPAddress())
+ return false;
+
+ // If we're matching subdomains, and we have no host, that means the pattern
+ // was <scheme>://*/<whatever>, so we match anything.
+ if (host_.empty())
+ return true;
+
+ // Check if the test host is a subdomain of our host.
+ if (test.host().length() <= (host_.length() + 1))
+ return false;
+
+ if (test.host().compare(test.host().length() - host_.length(),
+ host_.length(), host_) != 0)
+ return false;
+
+ return test.host()[test.host().length() - host_.length() - 1] == '.';
+}
+
+bool URLPattern::MatchesPath(const GURL& test) {
+ if (path_escaped_.empty()) {
+ path_escaped_ = path_;
+ ReplaceSubstringsAfterOffset(&path_escaped_, 0, "\\", "\\\\");
+ ReplaceSubstringsAfterOffset(&path_escaped_, 0, "?", "\\?");
+ }
+
+ if (!MatchPattern(test.PathForRequest(), path_escaped_))
+ return false;
+
+ return true;
+}

Powered by Google App Engine
This is Rietveld 408576698