OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/declarative_webrequest/webrequest_condit
ion_attribute.h" | 5 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condit
ion_attribute.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 ~WebRequestConditionAttributeResourceType() {} | 131 ~WebRequestConditionAttributeResourceType() {} |
132 | 132 |
133 // static | 133 // static |
134 scoped_refptr<const WebRequestConditionAttribute> | 134 scoped_refptr<const WebRequestConditionAttribute> |
135 WebRequestConditionAttributeResourceType::Create( | 135 WebRequestConditionAttributeResourceType::Create( |
136 const std::string& instance_type, | 136 const std::string& instance_type, |
137 const base::Value* value, | 137 const base::Value* value, |
138 std::string* error, | 138 std::string* error, |
139 bool* bad_message) { | 139 bool* bad_message) { |
140 DCHECK(instance_type == keys::kResourceTypeKey); | 140 DCHECK(instance_type == keys::kResourceTypeKey); |
141 const ListValue* value_as_list = NULL; | 141 const base::ListValue* value_as_list = NULL; |
142 if (!value->GetAsList(&value_as_list)) { | 142 if (!value->GetAsList(&value_as_list)) { |
143 *error = ErrorUtils::FormatErrorMessage(kInvalidValue, | 143 *error = ErrorUtils::FormatErrorMessage(kInvalidValue, |
144 keys::kResourceTypeKey); | 144 keys::kResourceTypeKey); |
145 return scoped_refptr<const WebRequestConditionAttribute>(NULL); | 145 return scoped_refptr<const WebRequestConditionAttribute>(NULL); |
146 } | 146 } |
147 | 147 |
148 size_t number_types = value_as_list->GetSize(); | 148 size_t number_types = value_as_list->GetSize(); |
149 | 149 |
150 std::vector<ResourceType::Type> passed_types; | 150 std::vector<ResourceType::Type> passed_types; |
151 passed_types.reserve(number_types); | 151 passed_types.reserve(number_types); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 | 217 |
218 // static | 218 // static |
219 scoped_refptr<const WebRequestConditionAttribute> | 219 scoped_refptr<const WebRequestConditionAttribute> |
220 WebRequestConditionAttributeContentType::Create( | 220 WebRequestConditionAttributeContentType::Create( |
221 const std::string& name, | 221 const std::string& name, |
222 const base::Value* value, | 222 const base::Value* value, |
223 std::string* error, | 223 std::string* error, |
224 bool* bad_message) { | 224 bool* bad_message) { |
225 DCHECK(name == keys::kContentTypeKey || name == keys::kExcludeContentTypeKey); | 225 DCHECK(name == keys::kContentTypeKey || name == keys::kExcludeContentTypeKey); |
226 | 226 |
227 const ListValue* value_as_list = NULL; | 227 const base::ListValue* value_as_list = NULL; |
228 if (!value->GetAsList(&value_as_list)) { | 228 if (!value->GetAsList(&value_as_list)) { |
229 *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); | 229 *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); |
230 return scoped_refptr<const WebRequestConditionAttribute>(NULL); | 230 return scoped_refptr<const WebRequestConditionAttribute>(NULL); |
231 } | 231 } |
232 std::vector<std::string> content_types; | 232 std::vector<std::string> content_types; |
233 for (ListValue::const_iterator it = value_as_list->begin(); | 233 for (base::ListValue::const_iterator it = value_as_list->begin(); |
234 it != value_as_list->end(); ++it) { | 234 it != value_as_list->end(); ++it) { |
235 std::string content_type; | 235 std::string content_type; |
236 if (!(*it)->GetAsString(&content_type)) { | 236 if (!(*it)->GetAsString(&content_type)) { |
237 *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); | 237 *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); |
238 return scoped_refptr<const WebRequestConditionAttribute>(NULL); | 238 return scoped_refptr<const WebRequestConditionAttribute>(NULL); |
239 } | 239 } |
240 content_types.push_back(content_type); | 240 content_types.push_back(content_type); |
241 } | 241 } |
242 | 242 |
243 return scoped_refptr<const WebRequestConditionAttribute>( | 243 return scoped_refptr<const WebRequestConditionAttribute>( |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 bool TestNameValue(const std::string& name, const std::string& value) const; | 307 bool TestNameValue(const std::string& name, const std::string& value) const; |
308 | 308 |
309 private: | 309 private: |
310 // Represents a single string-matching test. | 310 // Represents a single string-matching test. |
311 class StringMatchTest { | 311 class StringMatchTest { |
312 public: | 312 public: |
313 enum MatchType { kPrefix, kSuffix, kEquals, kContains }; | 313 enum MatchType { kPrefix, kSuffix, kEquals, kContains }; |
314 | 314 |
315 // |data| is the pattern to be matched in the position given by |type|. | 315 // |data| is the pattern to be matched in the position given by |type|. |
316 // Note that |data| must point to a StringValue object. | 316 // Note that |data| must point to a StringValue object. |
317 static scoped_ptr<StringMatchTest> Create(const Value* data, | 317 static scoped_ptr<StringMatchTest> Create(const base::Value* data, |
318 MatchType type, | 318 MatchType type, |
319 bool case_sensitive); | 319 bool case_sensitive); |
320 ~StringMatchTest(); | 320 ~StringMatchTest(); |
321 | 321 |
322 // Does |str| pass |this| StringMatchTest? | 322 // Does |str| pass |this| StringMatchTest? |
323 bool Matches(const std::string& str) const; | 323 bool Matches(const std::string& str) const; |
324 | 324 |
325 private: | 325 private: |
326 StringMatchTest(const std::string& data, | 326 StringMatchTest(const std::string& data, |
327 MatchType type, | 327 MatchType type, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 }; | 367 }; |
368 | 368 |
369 // HeaderMatcher implementation. | 369 // HeaderMatcher implementation. |
370 | 370 |
371 HeaderMatcher::~HeaderMatcher() {} | 371 HeaderMatcher::~HeaderMatcher() {} |
372 | 372 |
373 // static | 373 // static |
374 scoped_ptr<const HeaderMatcher> HeaderMatcher::Create( | 374 scoped_ptr<const HeaderMatcher> HeaderMatcher::Create( |
375 const base::ListValue* tests) { | 375 const base::ListValue* tests) { |
376 ScopedVector<const HeaderMatchTest> header_tests; | 376 ScopedVector<const HeaderMatchTest> header_tests; |
377 for (ListValue::const_iterator it = tests->begin(); | 377 for (base::ListValue::const_iterator it = tests->begin(); |
378 it != tests->end(); ++it) { | 378 it != tests->end(); ++it) { |
379 const DictionaryValue* tests = NULL; | 379 const base::DictionaryValue* tests = NULL; |
380 if (!(*it)->GetAsDictionary(&tests)) | 380 if (!(*it)->GetAsDictionary(&tests)) |
381 return scoped_ptr<const HeaderMatcher>(); | 381 return scoped_ptr<const HeaderMatcher>(); |
382 | 382 |
383 scoped_ptr<const HeaderMatchTest> header_test( | 383 scoped_ptr<const HeaderMatchTest> header_test( |
384 HeaderMatchTest::Create(tests)); | 384 HeaderMatchTest::Create(tests)); |
385 if (header_test.get() == NULL) | 385 if (header_test.get() == NULL) |
386 return scoped_ptr<const HeaderMatcher>(); | 386 return scoped_ptr<const HeaderMatcher>(); |
387 header_tests.push_back(header_test.release()); | 387 header_tests.push_back(header_test.release()); |
388 } | 388 } |
389 | 389 |
390 return scoped_ptr<const HeaderMatcher>(new HeaderMatcher(&header_tests)); | 390 return scoped_ptr<const HeaderMatcher>(new HeaderMatcher(&header_tests)); |
391 } | 391 } |
392 | 392 |
393 bool HeaderMatcher::TestNameValue(const std::string& name, | 393 bool HeaderMatcher::TestNameValue(const std::string& name, |
394 const std::string& value) const { | 394 const std::string& value) const { |
395 for (size_t i = 0; i < tests_.size(); ++i) { | 395 for (size_t i = 0; i < tests_.size(); ++i) { |
396 if (tests_[i]->Matches(name, value)) | 396 if (tests_[i]->Matches(name, value)) |
397 return true; | 397 return true; |
398 } | 398 } |
399 return false; | 399 return false; |
400 } | 400 } |
401 | 401 |
402 HeaderMatcher::HeaderMatcher(ScopedVector<const HeaderMatchTest>* tests) | 402 HeaderMatcher::HeaderMatcher(ScopedVector<const HeaderMatchTest>* tests) |
403 : tests_(tests->Pass()) {} | 403 : tests_(tests->Pass()) {} |
404 | 404 |
405 // HeaderMatcher::StringMatchTest implementation. | 405 // HeaderMatcher::StringMatchTest implementation. |
406 | 406 |
407 // static | 407 // static |
408 scoped_ptr<HeaderMatcher::StringMatchTest> | 408 scoped_ptr<HeaderMatcher::StringMatchTest> |
409 HeaderMatcher::StringMatchTest::Create(const Value* data, | 409 HeaderMatcher::StringMatchTest::Create(const base::Value* data, |
410 MatchType type, | 410 MatchType type, |
411 bool case_sensitive) { | 411 bool case_sensitive) { |
412 std::string str; | 412 std::string str; |
413 CHECK(data->GetAsString(&str)); | 413 CHECK(data->GetAsString(&str)); |
414 return scoped_ptr<StringMatchTest>( | 414 return scoped_ptr<StringMatchTest>( |
415 new StringMatchTest(str, type, case_sensitive)); | 415 new StringMatchTest(str, type, case_sensitive)); |
416 } | 416 } |
417 | 417 |
418 HeaderMatcher::StringMatchTest::~StringMatchTest() {} | 418 HeaderMatcher::StringMatchTest::~StringMatchTest() {} |
419 | 419 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 value_match_(value_match->Pass()) {} | 456 value_match_(value_match->Pass()) {} |
457 | 457 |
458 HeaderMatcher::HeaderMatchTest::~HeaderMatchTest() {} | 458 HeaderMatcher::HeaderMatchTest::~HeaderMatchTest() {} |
459 | 459 |
460 // static | 460 // static |
461 scoped_ptr<const HeaderMatcher::HeaderMatchTest> | 461 scoped_ptr<const HeaderMatcher::HeaderMatchTest> |
462 HeaderMatcher::HeaderMatchTest::Create(const base::DictionaryValue* tests) { | 462 HeaderMatcher::HeaderMatchTest::Create(const base::DictionaryValue* tests) { |
463 ScopedVector<const StringMatchTest> name_match; | 463 ScopedVector<const StringMatchTest> name_match; |
464 ScopedVector<const StringMatchTest> value_match; | 464 ScopedVector<const StringMatchTest> value_match; |
465 | 465 |
466 for (DictionaryValue::Iterator it(*tests); !it.IsAtEnd(); it.Advance()) { | 466 for (base::DictionaryValue::Iterator it(*tests); |
| 467 !it.IsAtEnd(); it.Advance()) { |
467 bool is_name = false; // Is this test for header name? | 468 bool is_name = false; // Is this test for header name? |
468 StringMatchTest::MatchType match_type; | 469 StringMatchTest::MatchType match_type; |
469 if (it.key() == keys::kNamePrefixKey) { | 470 if (it.key() == keys::kNamePrefixKey) { |
470 is_name = true; | 471 is_name = true; |
471 match_type = StringMatchTest::kPrefix; | 472 match_type = StringMatchTest::kPrefix; |
472 } else if (it.key() == keys::kNameSuffixKey) { | 473 } else if (it.key() == keys::kNameSuffixKey) { |
473 is_name = true; | 474 is_name = true; |
474 match_type = StringMatchTest::kSuffix; | 475 match_type = StringMatchTest::kSuffix; |
475 } else if (it.key() == keys::kNameContainsKey) { | 476 } else if (it.key() == keys::kNameContainsKey) { |
476 is_name = true; | 477 is_name = true; |
477 match_type = StringMatchTest::kContains; | 478 match_type = StringMatchTest::kContains; |
478 } else if (it.key() == keys::kNameEqualsKey) { | 479 } else if (it.key() == keys::kNameEqualsKey) { |
479 is_name = true; | 480 is_name = true; |
480 match_type = StringMatchTest::kEquals; | 481 match_type = StringMatchTest::kEquals; |
481 } else if (it.key() == keys::kValuePrefixKey) { | 482 } else if (it.key() == keys::kValuePrefixKey) { |
482 match_type = StringMatchTest::kPrefix; | 483 match_type = StringMatchTest::kPrefix; |
483 } else if (it.key() == keys::kValueSuffixKey) { | 484 } else if (it.key() == keys::kValueSuffixKey) { |
484 match_type = StringMatchTest::kSuffix; | 485 match_type = StringMatchTest::kSuffix; |
485 } else if (it.key() == keys::kValueContainsKey) { | 486 } else if (it.key() == keys::kValueContainsKey) { |
486 match_type = StringMatchTest::kContains; | 487 match_type = StringMatchTest::kContains; |
487 } else if (it.key() == keys::kValueEqualsKey) { | 488 } else if (it.key() == keys::kValueEqualsKey) { |
488 match_type = StringMatchTest::kEquals; | 489 match_type = StringMatchTest::kEquals; |
489 } else { | 490 } else { |
490 NOTREACHED(); // JSON schema type checking should prevent this. | 491 NOTREACHED(); // JSON schema type checking should prevent this. |
491 return scoped_ptr<const HeaderMatchTest>(); | 492 return scoped_ptr<const HeaderMatchTest>(); |
492 } | 493 } |
493 const Value* content = &it.value(); | 494 const base::Value* content = &it.value(); |
494 | 495 |
495 ScopedVector<const StringMatchTest>* tests = | 496 ScopedVector<const StringMatchTest>* tests = |
496 is_name ? &name_match : &value_match; | 497 is_name ? &name_match : &value_match; |
497 switch (content->GetType()) { | 498 switch (content->GetType()) { |
498 case Value::TYPE_LIST: { | 499 case base::Value::TYPE_LIST: { |
499 const ListValue* list = NULL; | 500 const base::ListValue* list = NULL; |
500 CHECK(content->GetAsList(&list)); | 501 CHECK(content->GetAsList(&list)); |
501 for (ListValue::const_iterator it = list->begin(); | 502 for (base::ListValue::const_iterator it = list->begin(); |
502 it != list->end(); ++it) { | 503 it != list->end(); ++it) { |
503 tests->push_back( | 504 tests->push_back( |
504 StringMatchTest::Create(*it, match_type, !is_name).release()); | 505 StringMatchTest::Create(*it, match_type, !is_name).release()); |
505 } | 506 } |
506 break; | 507 break; |
507 } | 508 } |
508 case Value::TYPE_STRING: { | 509 case base::Value::TYPE_STRING: { |
509 tests->push_back( | 510 tests->push_back( |
510 StringMatchTest::Create(content, match_type, !is_name).release()); | 511 StringMatchTest::Create(content, match_type, !is_name).release()); |
511 break; | 512 break; |
512 } | 513 } |
513 default: { | 514 default: { |
514 NOTREACHED(); // JSON schema type checking should prevent this. | 515 NOTREACHED(); // JSON schema type checking should prevent this. |
515 return scoped_ptr<const HeaderMatchTest>(); | 516 return scoped_ptr<const HeaderMatchTest>(); |
516 } | 517 } |
517 } | 518 } |
518 } | 519 } |
(...skipping 30 matching lines...) Expand all Loading... |
549 | 550 |
550 WebRequestConditionAttributeRequestHeaders:: | 551 WebRequestConditionAttributeRequestHeaders:: |
551 ~WebRequestConditionAttributeRequestHeaders() {} | 552 ~WebRequestConditionAttributeRequestHeaders() {} |
552 | 553 |
553 namespace { | 554 namespace { |
554 | 555 |
555 scoped_ptr<const HeaderMatcher> PrepareHeaderMatcher( | 556 scoped_ptr<const HeaderMatcher> PrepareHeaderMatcher( |
556 const std::string& name, | 557 const std::string& name, |
557 const base::Value* value, | 558 const base::Value* value, |
558 std::string* error) { | 559 std::string* error) { |
559 const ListValue* value_as_list = NULL; | 560 const base::ListValue* value_as_list = NULL; |
560 if (!value->GetAsList(&value_as_list)) { | 561 if (!value->GetAsList(&value_as_list)) { |
561 *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); | 562 *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); |
562 return scoped_ptr<const HeaderMatcher>(); | 563 return scoped_ptr<const HeaderMatcher>(); |
563 } | 564 } |
564 | 565 |
565 scoped_ptr<const HeaderMatcher> header_matcher( | 566 scoped_ptr<const HeaderMatcher> header_matcher( |
566 HeaderMatcher::Create(value_as_list)); | 567 HeaderMatcher::Create(value_as_list)); |
567 if (header_matcher.get() == NULL) | 568 if (header_matcher.get() == NULL) |
568 *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); | 569 *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); |
569 return header_matcher.Pass(); | 570 return header_matcher.Pass(); |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 : allowed_stages_(allowed_stages) {} | 789 : allowed_stages_(allowed_stages) {} |
789 | 790 |
790 WebRequestConditionAttributeStages:: | 791 WebRequestConditionAttributeStages:: |
791 ~WebRequestConditionAttributeStages() {} | 792 ~WebRequestConditionAttributeStages() {} |
792 | 793 |
793 namespace { | 794 namespace { |
794 | 795 |
795 // Reads strings stored in |value|, which is expected to be a ListValue, and | 796 // Reads strings stored in |value|, which is expected to be a ListValue, and |
796 // sets corresponding bits (see RequestStage) in |out_stages|. Returns true on | 797 // sets corresponding bits (see RequestStage) in |out_stages|. Returns true on |
797 // success, false otherwise. | 798 // success, false otherwise. |
798 bool ParseListOfStages(const Value& value, int* out_stages) { | 799 bool ParseListOfStages(const base::Value& value, int* out_stages) { |
799 const ListValue* list = NULL; | 800 const base::ListValue* list = NULL; |
800 if (!value.GetAsList(&list)) | 801 if (!value.GetAsList(&list)) |
801 return false; | 802 return false; |
802 | 803 |
803 int stages = 0; | 804 int stages = 0; |
804 std::string stage_name; | 805 std::string stage_name; |
805 for (ListValue::const_iterator it = list->begin(); it != list->end(); ++it) { | 806 for (base::ListValue::const_iterator it = list->begin(); |
| 807 it != list->end(); ++it) { |
806 if (!((*it)->GetAsString(&stage_name))) | 808 if (!((*it)->GetAsString(&stage_name))) |
807 return false; | 809 return false; |
808 if (stage_name == keys::kOnBeforeRequestEnum) { | 810 if (stage_name == keys::kOnBeforeRequestEnum) { |
809 stages |= ON_BEFORE_REQUEST; | 811 stages |= ON_BEFORE_REQUEST; |
810 } else if (stage_name == keys::kOnBeforeSendHeadersEnum) { | 812 } else if (stage_name == keys::kOnBeforeSendHeadersEnum) { |
811 stages |= ON_BEFORE_SEND_HEADERS; | 813 stages |= ON_BEFORE_SEND_HEADERS; |
812 } else if (stage_name == keys::kOnHeadersReceivedEnum) { | 814 } else if (stage_name == keys::kOnHeadersReceivedEnum) { |
813 stages |= ON_HEADERS_RECEIVED; | 815 stages |= ON_HEADERS_RECEIVED; |
814 } else if (stage_name == keys::kOnAuthRequiredEnum) { | 816 } else if (stage_name == keys::kOnAuthRequiredEnum) { |
815 stages |= ON_AUTH_REQUIRED; | 817 stages |= ON_AUTH_REQUIRED; |
816 } else { | 818 } else { |
817 NOTREACHED(); // JSON schema checks prevent getting here. | 819 NOTREACHED(); // JSON schema checks prevent getting here. |
818 return false; | 820 return false; |
819 } | 821 } |
820 } | 822 } |
821 | 823 |
822 *out_stages = stages; | 824 *out_stages = stages; |
823 return true; | 825 return true; |
824 } | 826 } |
825 | 827 |
826 } // namespace | 828 } // namespace |
827 | 829 |
828 // static | 830 // static |
829 scoped_refptr<const WebRequestConditionAttribute> | 831 scoped_refptr<const WebRequestConditionAttribute> |
830 WebRequestConditionAttributeStages::Create(const std::string& name, | 832 WebRequestConditionAttributeStages::Create(const std::string& name, |
831 const Value* value, | 833 const base::Value* value, |
832 std::string* error, | 834 std::string* error, |
833 bool* bad_message) { | 835 bool* bad_message) { |
834 DCHECK(name == keys::kStagesKey); | 836 DCHECK(name == keys::kStagesKey); |
835 | 837 |
836 int allowed_stages = 0; | 838 int allowed_stages = 0; |
837 if (!ParseListOfStages(*value, &allowed_stages)) { | 839 if (!ParseListOfStages(*value, &allowed_stages)) { |
838 *error = ErrorUtils::FormatErrorMessage(kInvalidValue, | 840 *error = ErrorUtils::FormatErrorMessage(kInvalidValue, |
839 keys::kStagesKey); | 841 keys::kStagesKey); |
840 return scoped_refptr<const WebRequestConditionAttribute>(NULL); | 842 return scoped_refptr<const WebRequestConditionAttribute>(NULL); |
841 } | 843 } |
(...skipping 24 matching lines...) Expand all Loading... |
866 bool WebRequestConditionAttributeStages::Equals( | 868 bool WebRequestConditionAttributeStages::Equals( |
867 const WebRequestConditionAttribute* other) const { | 869 const WebRequestConditionAttribute* other) const { |
868 if (!WebRequestConditionAttribute::Equals(other)) | 870 if (!WebRequestConditionAttribute::Equals(other)) |
869 return false; | 871 return false; |
870 const WebRequestConditionAttributeStages* casted_other = | 872 const WebRequestConditionAttributeStages* casted_other = |
871 static_cast<const WebRequestConditionAttributeStages*>(other); | 873 static_cast<const WebRequestConditionAttributeStages*>(other); |
872 return allowed_stages_ == casted_other->allowed_stages_; | 874 return allowed_stages_ == casted_other->allowed_stages_; |
873 } | 875 } |
874 | 876 |
875 } // namespace extensions | 877 } // namespace extensions |
OLD | NEW |