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

Side by Side Diff: components/url_matcher/url_matcher.cc

Issue 219613002: Add support for matching query parameters in URLMatcher (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixes the review comments from Dominic and Joao Created 6 years, 8 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/url_matcher/url_matcher.h" 5 #include "components/url_matcher/url_matcher.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 return false; 189 return false;
190 } 190 }
191 191
192 bool URLMatcherCondition::IsFullURLCondition() const { 192 bool URLMatcherCondition::IsFullURLCondition() const {
193 // For these criteria the SubstringMatcher needs to be executed on the 193 // For these criteria the SubstringMatcher needs to be executed on the
194 // GURL that is canonicalized with 194 // GURL that is canonicalized with
195 // URLMatcherConditionFactory::CanonicalizeURLForFullSearches. 195 // URLMatcherConditionFactory::CanonicalizeURLForFullSearches.
196 switch (criterion_) { 196 switch (criterion_) {
197 case HOST_CONTAINS: 197 case HOST_CONTAINS:
198 case PATH_CONTAINS: 198 case PATH_CONTAINS:
199 case QUERY_CONTAINS:
200 case URL_PREFIX: 199 case URL_PREFIX:
201 case URL_SUFFIX: 200 case URL_SUFFIX:
202 case URL_CONTAINS: 201 case URL_CONTAINS:
203 case URL_EQUALS: 202 case URL_EQUALS:
204 return true; 203 return true;
205 default: 204 default:
206 break; 205 break;
207 } 206 }
208 return false; 207 return false;
209 } 208 }
210 209
211 bool URLMatcherCondition::IsRegexCondition() const { 210 bool URLMatcherCondition::IsRegexCondition() const {
212 return IsRegexCriterion(criterion_); 211 return IsRegexCriterion(criterion_);
213 } 212 }
214 213
215 bool URLMatcherCondition::IsOriginAndPathRegexCondition() const { 214 bool URLMatcherCondition::IsOriginAndPathRegexCondition() const {
216 return IsOriginAndPathRegexCriterion(criterion_); 215 return IsOriginAndPathRegexCriterion(criterion_);
217 } 216 }
218 217
219 bool URLMatcherCondition::IsMatch( 218 bool URLMatcherCondition::IsMatch(
220 const std::set<StringPattern::ID>& matching_patterns, 219 const std::set<StringPattern::ID>& matching_patterns,
221 const GURL& url) const { 220 const GURL& url) const {
222 DCHECK(string_pattern_); 221 DCHECK(string_pattern_);
223 if (!ContainsKey(matching_patterns, string_pattern_->id())) 222 if (!ContainsKey(matching_patterns, string_pattern_->id()))
224 return false; 223 return false;
225 // The criteria HOST_CONTAINS, PATH_CONTAINS, QUERY_CONTAINS are based on 224 // The criteria HOST_CONTAINS, PATH_CONTAINS are based on a substring match on
226 // a substring match on the raw URL. In case of a match, we need to verify 225 // the raw URL. In case of a match, we need to verify that the match was found
227 // that the match was found in the correct component of the URL. 226 // in the correct component of the URL.
228 switch (criterion_) { 227 switch (criterion_) {
229 case HOST_CONTAINS: 228 case HOST_CONTAINS:
230 return url.host().find(string_pattern_->pattern()) != 229 return url.host().find(string_pattern_->pattern()) !=
231 std::string::npos; 230 std::string::npos;
232 case PATH_CONTAINS: 231 case PATH_CONTAINS:
233 return url.path().find(string_pattern_->pattern()) != 232 return url.path().find(string_pattern_->pattern()) !=
234 std::string::npos; 233 std::string::npos;
235 case QUERY_CONTAINS:
236 return url.query().find(string_pattern_->pattern()) !=
237 std::string::npos;
238 default: 234 default:
239 break; 235 break;
240 } 236 }
241 return true; 237 return true;
242 } 238 }
243 239
244 // 240 //
245 // URLMatcherConditionFactory 241 // URLMatcherConditionFactory
246 // 242 //
247 243
248 namespace { 244 namespace {
249 // These are symbols that are not contained in 7-bit ASCII used in GURLs. 245 // These are symbols that are not contained in 7-bit ASCII used in GURLs.
250 const char kBeginningOfURL[] = {static_cast<char>(-1), 0}; 246 const char kBeginningOfURL[] = {static_cast<char>(-1), 0};
251 const char kEndOfDomain[] = {static_cast<char>(-2), 0}; 247 const char kEndOfDomain[] = {static_cast<char>(-2), 0};
252 const char kEndOfPath[] = {static_cast<char>(-3), 0}; 248 const char kEndOfPath[] = {static_cast<char>(-3), 0};
253 const char kEndOfURL[] = {static_cast<char>(-4), 0}; 249 const char kBeginningOfQueryComponent[] = {static_cast<char>(-4), 0};
250 const char kEndOfURL[] = {static_cast<char>(-5), 0};
251 const char kQuerySeperator = '&';
252
253 // This function prepares the query string by replacing query separator with a
254 // magic value (|kBeginningOfQueryComponent|). When the boolean
255 // |prepend_beginning_of_query_component| is true the function prepends the
256 // query with the same magic. This is done to locate the start of a key value
257 // pair in the query string. The parameter |query| is passed by value
258 // intentionally, since it is locally modified.
259 std::string PrepareQuery(std::string query,
260 bool prepend_beginning_of_query_component) {
261 for (std::string::iterator it = query.begin(); it != query.end(); ++it) {
262 if (*it == kQuerySeperator)
263 *it = kBeginningOfQueryComponent[0];
264 }
265 return prepend_beginning_of_query_component
266 ? kBeginningOfQueryComponent + query
267 : query;
268 }
254 } // namespace 269 } // namespace
255 270
256 URLMatcherConditionFactory::URLMatcherConditionFactory() : id_counter_(0) {} 271 URLMatcherConditionFactory::URLMatcherConditionFactory() : id_counter_(0) {}
257 272
258 URLMatcherConditionFactory::~URLMatcherConditionFactory() { 273 URLMatcherConditionFactory::~URLMatcherConditionFactory() {
259 STLDeleteElements(&substring_pattern_singletons_); 274 STLDeleteElements(&substring_pattern_singletons_);
260 STLDeleteElements(&regex_pattern_singletons_); 275 STLDeleteElements(&regex_pattern_singletons_);
261 STLDeleteElements(&origin_and_path_regex_pattern_singletons_); 276 STLDeleteElements(&origin_and_path_regex_pattern_singletons_);
262 } 277 }
263 278
264 std::string URLMatcherConditionFactory::CanonicalizeURLForComponentSearches( 279 std::string URLMatcherConditionFactory::CanonicalizeURLForComponentSearches(
265 const GURL& url) const { 280 const GURL& url) const {
266 return kBeginningOfURL + CanonicalizeHostname(url.host()) + kEndOfDomain + 281 return kBeginningOfURL + CanonicalizeHostname(url.host()) + kEndOfDomain +
267 url.path() + kEndOfPath + 282 url.path() + kEndOfPath +
268 (url.has_query() ? "?" + url.query() : std::string()) + kEndOfURL; 283 (url.has_query() ? PrepareQuery(url.query(), true) : std::string()) +
284 kEndOfURL;
269 } 285 }
270 286
271 URLMatcherCondition URLMatcherConditionFactory::CreateHostPrefixCondition( 287 URLMatcherCondition URLMatcherConditionFactory::CreateHostPrefixCondition(
272 const std::string& prefix) { 288 const std::string& prefix) {
273 return CreateCondition(URLMatcherCondition::HOST_PREFIX, 289 return CreateCondition(URLMatcherCondition::HOST_PREFIX,
274 kBeginningOfURL + CanonicalizeHostname(prefix)); 290 kBeginningOfURL + CanonicalizeHostname(prefix));
275 } 291 }
276 292
277 URLMatcherCondition URLMatcherConditionFactory::CreateHostSuffixCondition( 293 URLMatcherCondition URLMatcherConditionFactory::CreateHostSuffixCondition(
278 const std::string& suffix) { 294 const std::string& suffix) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 URLMatcherCondition URLMatcherConditionFactory::CreatePathEqualsCondition( 326 URLMatcherCondition URLMatcherConditionFactory::CreatePathEqualsCondition(
311 const std::string& str) { 327 const std::string& str) {
312 return CreateCondition(URLMatcherCondition::PATH_EQUALS, 328 return CreateCondition(URLMatcherCondition::PATH_EQUALS,
313 kEndOfDomain + str + kEndOfPath); 329 kEndOfDomain + str + kEndOfPath);
314 } 330 }
315 331
316 URLMatcherCondition URLMatcherConditionFactory::CreateQueryPrefixCondition( 332 URLMatcherCondition URLMatcherConditionFactory::CreateQueryPrefixCondition(
317 const std::string& prefix) { 333 const std::string& prefix) {
318 std::string pattern; 334 std::string pattern;
319 if (!prefix.empty() && prefix[0] == '?') 335 if (!prefix.empty() && prefix[0] == '?')
320 pattern = kEndOfPath + prefix; 336 pattern = kEndOfPath + PrepareQuery(prefix.substr(1), true);
321 else 337 else
322 pattern = kEndOfPath + ('?' + prefix); 338 pattern = kEndOfPath + PrepareQuery(prefix, true);
323 339
324 return CreateCondition(URLMatcherCondition::QUERY_PREFIX, pattern); 340 return CreateCondition(URLMatcherCondition::QUERY_PREFIX, pattern);
325 } 341 }
326 342
327 URLMatcherCondition URLMatcherConditionFactory::CreateQuerySuffixCondition( 343 URLMatcherCondition URLMatcherConditionFactory::CreateQuerySuffixCondition(
328 const std::string& suffix) { 344 const std::string& suffix) {
329 if (!suffix.empty() && suffix[0] == '?') { 345 if (!suffix.empty() && suffix[0] == '?') {
330 return CreateQueryEqualsCondition(suffix); 346 return CreateQueryEqualsCondition(suffix);
331 } else { 347 } else {
332 return CreateCondition(URLMatcherCondition::QUERY_SUFFIX, 348 return CreateCondition(URLMatcherCondition::QUERY_SUFFIX,
333 suffix + kEndOfURL); 349 PrepareQuery(suffix, false) + kEndOfURL);
334 } 350 }
335 } 351 }
336 352
337 URLMatcherCondition URLMatcherConditionFactory::CreateQueryContainsCondition( 353 URLMatcherCondition URLMatcherConditionFactory::CreateQueryContainsCondition(
338 const std::string& str) { 354 const std::string& str) {
355 std::string pattern;
339 if (!str.empty() && str[0] == '?') 356 if (!str.empty() && str[0] == '?')
340 return CreateQueryPrefixCondition(str); 357 pattern = str.substr(1);
341 else 358 else
342 return CreateCondition(URLMatcherCondition::QUERY_CONTAINS, str); 359 pattern = str;
360 return CreateCondition(URLMatcherCondition::QUERY_CONTAINS,
361 PrepareQuery(pattern, true));
343 } 362 }
344 363
345 URLMatcherCondition URLMatcherConditionFactory::CreateQueryEqualsCondition( 364 URLMatcherCondition URLMatcherConditionFactory::CreateQueryEqualsCondition(
346 const std::string& str) { 365 const std::string& str) {
347 std::string pattern; 366 std::string pattern;
348 if (!str.empty() && str[0] == '?') 367 if (!str.empty() && str[0] == '?')
349 pattern = kEndOfPath + str + kEndOfURL; 368 pattern = kEndOfPath + PrepareQuery(str.substr(1), true) + kEndOfURL;
350 else 369 else
351 pattern = kEndOfPath + ('?' + str) + kEndOfURL; 370 pattern = kEndOfPath + PrepareQuery(str, true) + kEndOfURL;
352 371
353 return CreateCondition(URLMatcherCondition::QUERY_EQUALS, pattern); 372 return CreateCondition(URLMatcherCondition::QUERY_EQUALS, pattern);
354 } 373 }
355 374
356 URLMatcherCondition 375 URLMatcherCondition
357 URLMatcherConditionFactory::CreateHostSuffixPathPrefixCondition( 376 URLMatcherConditionFactory::CreateHostSuffixPathPrefixCondition(
358 const std::string& host_suffix, 377 const std::string& host_suffix,
359 const std::string& path_prefix) { 378 const std::string& path_prefix) {
360 return CreateCondition(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX, 379 return CreateCondition(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX,
361 host_suffix + kEndOfDomain + path_prefix); 380 host_suffix + kEndOfDomain + path_prefix);
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 890
872 void URLMatcher::UpdateInternalDatastructures() { 891 void URLMatcher::UpdateInternalDatastructures() {
873 UpdateSubstringSetMatcher(false); 892 UpdateSubstringSetMatcher(false);
874 UpdateSubstringSetMatcher(true); 893 UpdateSubstringSetMatcher(true);
875 UpdateRegexSetMatcher(); 894 UpdateRegexSetMatcher();
876 UpdateTriggers(); 895 UpdateTriggers();
877 UpdateConditionFactory(); 896 UpdateConditionFactory();
878 } 897 }
879 898
880 } // namespace url_matcher 899 } // namespace url_matcher
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698