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

Side by Side Diff: chrome/common/extensions/url_pattern.cc

Issue 19704: Introduce UrlPattern. (Closed)
Patch Set: more feedback Created 11 years, 10 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2006-2009 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 "base/string_piece.h"
6 #include "base/string_util.h"
7 #include "chrome/common/extensions/url_pattern.h"
8
9 // TODO(aa): Consider adding chrome-extension? What about more obscure ones
10 // like data: and javascript: ?
11 static const char* kValidSchemes[] = {
12 "http",
13 "https",
14 "file",
15 "ftp",
16 "chrome-ui"
17 };
18
19 static const char kSchemeSeparator[] = "://";
20 static const char kPathSeparator[] = "/";
21
22 static bool IsValidScheme(const std::string& scheme) {
23 for (size_t i = 0; i < arraysize(kValidSchemes); ++i) {
24 if (scheme == kValidSchemes[i])
25 return true;
26 }
27
28 return false;
29 }
30
31 bool URLPattern::Parse(const std::string& pattern) {
32 size_t scheme_end_pos = pattern.find(kSchemeSeparator);
33 if (scheme_end_pos == std::string::npos)
34 return false;
35
36 scheme_ = pattern.substr(0, scheme_end_pos);
37 if (!IsValidScheme(scheme_))
38 return false;
39
40 size_t host_start_pos = scheme_end_pos + strlen(kSchemeSeparator);
41 if (host_start_pos >= pattern.length())
42 return false;
43
44 // Parse out the host and path.
45 size_t path_start_pos = 0;
46
47 // File URLs are special because they have no host. There are other schemes
48 // with the same structure, but we don't support them (yet).
49 if (scheme_ == "file") {
50 path_start_pos = host_start_pos;
51 } else {
52 size_t host_end_pos = pattern.find(kPathSeparator, host_start_pos);
53 if (host_end_pos == std::string::npos)
54 return false;
55
56 host_ = pattern.substr(host_start_pos, host_end_pos - host_start_pos);
57
58 // The first component can optionally be '*' to match all subdomains.
59 std::vector<std::string> host_components;
60 SplitString(host_, '.', &host_components);
61 if (host_components[0] == "*") {
62 match_subdomains_ = true;
63 host_components.erase(host_components.begin(),
64 host_components.begin() + 1);
65 }
66 host_ = JoinString(host_components, '.');
67
68 // No other '*' can occur in the host, though. This isn't necessary, but is
69 // done as a convenience to developers who might otherwise be confused and
70 // think '*' works as a glob in the host.
71 if (host_.find('*') != std::string::npos)
72 return false;
73
74 path_start_pos = host_end_pos;
75 }
76
77 path_ = pattern.substr(path_start_pos);
78 return true;
79 }
80
81 bool URLPattern::MatchesUrl(const GURL &test) {
82 if (test.scheme() != scheme_)
83 return false;
84
85 if (!MatchesHost(test))
86 return false;
87
88 if (!MatchesPath(test))
89 return false;
90
91 return true;
92 }
93
94 bool URLPattern::MatchesHost(const GURL& test) {
95 if (test.host() == host_)
96 return true;
97
98 if (!match_subdomains_ || test.HostIsIPAddress())
99 return false;
100
101 // If we're matching subdomains, and we have no host, that means the pattern
102 // was <scheme>://*/<whatever>, so we match anything.
103 if (host_.empty())
104 return true;
105
106 // Check if the test host is a subdomain of our host.
107 if (test.host().length() <= (host_.length() + 1))
108 return false;
109
110 if (test.host().compare(test.host().length() - host_.length(),
111 host_.length(), host_) != 0)
112 return false;
113
114 return test.host()[test.host().length() - host_.length() - 1] == '.';
115 }
116
117 bool URLPattern::MatchesPath(const GURL& test) {
118 if (path_escaped_.empty()) {
119 path_escaped_ = path_;
120 ReplaceSubstringsAfterOffset(&path_escaped_, 0, "\\", "\\\\");
121 ReplaceSubstringsAfterOffset(&path_escaped_, 0, "?", "\\?");
122 }
123
124 if (!MatchPattern(test.PathForRequest(), path_escaped_))
125 return false;
126
127 return true;
128 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698