Index: chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc |
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc |
deleted file mode 100644 |
index efdddc7b96ff576ab2e85436d158d4358b5952c9..0000000000000000000000000000000000000000 |
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc |
+++ /dev/null |
@@ -1,878 +0,0 @@ |
-// Copyright (c) 2012 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 "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h" |
- |
-#include <algorithm> |
- |
-#include "base/lazy_instance.h" |
-#include "base/logging.h" |
-#include "base/strings/string_util.h" |
-#include "base/strings/stringprintf.h" |
-#include "base/values.h" |
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h" |
-#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" |
-#include "content/public/browser/resource_request_info.h" |
-#include "extensions/browser/api/declarative/deduping_factory.h" |
-#include "extensions/browser/api/declarative_webrequest/request_stage.h" |
-#include "extensions/browser/api/declarative_webrequest/webrequest_constants.h" |
-#include "extensions/common/error_utils.h" |
-#include "net/base/net_errors.h" |
-#include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
-#include "net/base/static_cookie_policy.h" |
-#include "net/http/http_request_headers.h" |
-#include "net/http/http_util.h" |
-#include "net/url_request/url_request.h" |
- |
-using base::CaseInsensitiveCompareASCII; |
-using base::DictionaryValue; |
-using base::ListValue; |
-using base::StringValue; |
-using base::Value; |
-using content::ResourceType; |
- |
-namespace helpers = extension_web_request_api_helpers; |
-namespace keys = extensions::declarative_webrequest_constants; |
- |
-namespace extensions { |
- |
-namespace { |
-// Error messages. |
-const char kInvalidValue[] = "Condition '*' has an invalid value"; |
- |
-struct WebRequestConditionAttributeFactory { |
- DedupingFactory<WebRequestConditionAttribute> factory; |
- |
- WebRequestConditionAttributeFactory() : factory(5) { |
- factory.RegisterFactoryMethod( |
- keys::kResourceTypeKey, |
- DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, |
- &WebRequestConditionAttributeResourceType::Create); |
- |
- factory.RegisterFactoryMethod( |
- keys::kContentTypeKey, |
- DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, |
- &WebRequestConditionAttributeContentType::Create); |
- factory.RegisterFactoryMethod( |
- keys::kExcludeContentTypeKey, |
- DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, |
- &WebRequestConditionAttributeContentType::Create); |
- |
- factory.RegisterFactoryMethod( |
- keys::kRequestHeadersKey, |
- DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, |
- &WebRequestConditionAttributeRequestHeaders::Create); |
- factory.RegisterFactoryMethod( |
- keys::kExcludeRequestHeadersKey, |
- DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, |
- &WebRequestConditionAttributeRequestHeaders::Create); |
- |
- factory.RegisterFactoryMethod( |
- keys::kResponseHeadersKey, |
- DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, |
- &WebRequestConditionAttributeResponseHeaders::Create); |
- factory.RegisterFactoryMethod( |
- keys::kExcludeResponseHeadersKey, |
- DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, |
- &WebRequestConditionAttributeResponseHeaders::Create); |
- |
- factory.RegisterFactoryMethod( |
- keys::kThirdPartyKey, |
- DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, |
- &WebRequestConditionAttributeThirdParty::Create); |
- |
- factory.RegisterFactoryMethod( |
- keys::kStagesKey, |
- DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, |
- &WebRequestConditionAttributeStages::Create); |
- } |
-}; |
- |
-base::LazyInstance<WebRequestConditionAttributeFactory>::Leaky |
- g_web_request_condition_attribute_factory = LAZY_INSTANCE_INITIALIZER; |
- |
-} // namespace |
- |
-// |
-// WebRequestConditionAttribute |
-// |
- |
-WebRequestConditionAttribute::WebRequestConditionAttribute() {} |
- |
-WebRequestConditionAttribute::~WebRequestConditionAttribute() {} |
- |
-bool WebRequestConditionAttribute::Equals( |
- const WebRequestConditionAttribute* other) const { |
- return GetType() == other->GetType(); |
-} |
- |
-// static |
-scoped_refptr<const WebRequestConditionAttribute> |
-WebRequestConditionAttribute::Create( |
- const std::string& name, |
- const base::Value* value, |
- std::string* error) { |
- CHECK(value != NULL && error != NULL); |
- bool bad_message = false; |
- return g_web_request_condition_attribute_factory.Get().factory.Instantiate( |
- name, value, error, &bad_message); |
-} |
- |
-// |
-// WebRequestConditionAttributeResourceType |
-// |
- |
-WebRequestConditionAttributeResourceType:: |
-WebRequestConditionAttributeResourceType( |
- const std::vector<ResourceType>& types) |
- : types_(types) {} |
- |
-WebRequestConditionAttributeResourceType:: |
-~WebRequestConditionAttributeResourceType() {} |
- |
-// static |
-scoped_refptr<const WebRequestConditionAttribute> |
-WebRequestConditionAttributeResourceType::Create( |
- const std::string& instance_type, |
- const base::Value* value, |
- std::string* error, |
- bool* bad_message) { |
- DCHECK(instance_type == keys::kResourceTypeKey); |
- const base::ListValue* value_as_list = NULL; |
- if (!value->GetAsList(&value_as_list)) { |
- *error = ErrorUtils::FormatErrorMessage(kInvalidValue, |
- keys::kResourceTypeKey); |
- return scoped_refptr<const WebRequestConditionAttribute>(NULL); |
- } |
- |
- size_t number_types = value_as_list->GetSize(); |
- |
- std::vector<ResourceType> passed_types; |
- passed_types.reserve(number_types); |
- for (size_t i = 0; i < number_types; ++i) { |
- std::string resource_type_string; |
- ResourceType type = content::RESOURCE_TYPE_LAST_TYPE; |
- if (!value_as_list->GetString(i, &resource_type_string) || |
- !helpers::ParseResourceType(resource_type_string, &type)) { |
- *error = ErrorUtils::FormatErrorMessage(kInvalidValue, |
- keys::kResourceTypeKey); |
- return scoped_refptr<const WebRequestConditionAttribute>(NULL); |
- } |
- passed_types.push_back(type); |
- } |
- |
- return scoped_refptr<const WebRequestConditionAttribute>( |
- new WebRequestConditionAttributeResourceType(passed_types)); |
-} |
- |
-int WebRequestConditionAttributeResourceType::GetStages() const { |
- return ON_BEFORE_REQUEST | ON_BEFORE_SEND_HEADERS | ON_SEND_HEADERS | |
- ON_HEADERS_RECEIVED | ON_AUTH_REQUIRED | ON_BEFORE_REDIRECT | |
- ON_RESPONSE_STARTED | ON_COMPLETED | ON_ERROR; |
-} |
- |
-bool WebRequestConditionAttributeResourceType::IsFulfilled( |
- const WebRequestData& request_data) const { |
- if (!(request_data.stage & GetStages())) |
- return false; |
- const content::ResourceRequestInfo* info = |
- content::ResourceRequestInfo::ForRequest(request_data.request); |
- if (!info) |
- return false; |
- return std::find(types_.begin(), types_.end(), info->GetResourceType()) != |
- types_.end(); |
-} |
- |
-WebRequestConditionAttribute::Type |
-WebRequestConditionAttributeResourceType::GetType() const { |
- return CONDITION_RESOURCE_TYPE; |
-} |
- |
-std::string WebRequestConditionAttributeResourceType::GetName() const { |
- return keys::kResourceTypeKey; |
-} |
- |
-bool WebRequestConditionAttributeResourceType::Equals( |
- const WebRequestConditionAttribute* other) const { |
- if (!WebRequestConditionAttribute::Equals(other)) |
- return false; |
- const WebRequestConditionAttributeResourceType* casted_other = |
- static_cast<const WebRequestConditionAttributeResourceType*>(other); |
- return types_ == casted_other->types_; |
-} |
- |
-// |
-// WebRequestConditionAttributeContentType |
-// |
- |
-WebRequestConditionAttributeContentType:: |
-WebRequestConditionAttributeContentType( |
- const std::vector<std::string>& content_types, |
- bool inclusive) |
- : content_types_(content_types), |
- inclusive_(inclusive) {} |
- |
-WebRequestConditionAttributeContentType:: |
-~WebRequestConditionAttributeContentType() {} |
- |
-// static |
-scoped_refptr<const WebRequestConditionAttribute> |
-WebRequestConditionAttributeContentType::Create( |
- const std::string& name, |
- const base::Value* value, |
- std::string* error, |
- bool* bad_message) { |
- DCHECK(name == keys::kContentTypeKey || name == keys::kExcludeContentTypeKey); |
- |
- const base::ListValue* value_as_list = NULL; |
- if (!value->GetAsList(&value_as_list)) { |
- *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); |
- return scoped_refptr<const WebRequestConditionAttribute>(NULL); |
- } |
- std::vector<std::string> content_types; |
- for (base::ListValue::const_iterator it = value_as_list->begin(); |
- it != value_as_list->end(); ++it) { |
- std::string content_type; |
- if (!(*it)->GetAsString(&content_type)) { |
- *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); |
- return scoped_refptr<const WebRequestConditionAttribute>(NULL); |
- } |
- content_types.push_back(content_type); |
- } |
- |
- return scoped_refptr<const WebRequestConditionAttribute>( |
- new WebRequestConditionAttributeContentType( |
- content_types, name == keys::kContentTypeKey)); |
-} |
- |
-int WebRequestConditionAttributeContentType::GetStages() const { |
- return ON_HEADERS_RECEIVED; |
-} |
- |
-bool WebRequestConditionAttributeContentType::IsFulfilled( |
- const WebRequestData& request_data) const { |
- if (!(request_data.stage & GetStages())) |
- return false; |
- std::string content_type; |
- request_data.original_response_headers->GetNormalizedHeader( |
- net::HttpRequestHeaders::kContentType, &content_type); |
- std::string mime_type; |
- std::string charset; |
- bool had_charset = false; |
- net::HttpUtil::ParseContentType( |
- content_type, &mime_type, &charset, &had_charset, NULL); |
- |
- if (inclusive_) { |
- return std::find(content_types_.begin(), content_types_.end(), |
- mime_type) != content_types_.end(); |
- } else { |
- return std::find(content_types_.begin(), content_types_.end(), |
- mime_type) == content_types_.end(); |
- } |
-} |
- |
-WebRequestConditionAttribute::Type |
-WebRequestConditionAttributeContentType::GetType() const { |
- return CONDITION_CONTENT_TYPE; |
-} |
- |
-std::string WebRequestConditionAttributeContentType::GetName() const { |
- return (inclusive_ ? keys::kContentTypeKey : keys::kExcludeContentTypeKey); |
-} |
- |
-bool WebRequestConditionAttributeContentType::Equals( |
- const WebRequestConditionAttribute* other) const { |
- if (!WebRequestConditionAttribute::Equals(other)) |
- return false; |
- const WebRequestConditionAttributeContentType* casted_other = |
- static_cast<const WebRequestConditionAttributeContentType*>(other); |
- return content_types_ == casted_other->content_types_ && |
- inclusive_ == casted_other->inclusive_; |
-} |
- |
-// Manages a set of tests to be applied to name-value pairs representing |
-// headers. This is a helper class to header-related condition attributes. |
-// It contains a set of test groups. A name-value pair satisfies the whole |
-// set of test groups iff it passes at least one test group. |
-class HeaderMatcher { |
- public: |
- ~HeaderMatcher(); |
- |
- // Creates an instance based on a list |tests| of test groups, encoded as |
- // dictionaries of the type declarativeWebRequest.HeaderFilter (see |
- // declarative_web_request.json). |
- static scoped_ptr<const HeaderMatcher> Create(const base::ListValue* tests); |
- |
- // Does |this| match the header "|name|: |value|"? |
- bool TestNameValue(const std::string& name, const std::string& value) const; |
- |
- private: |
- // Represents a single string-matching test. |
- class StringMatchTest { |
- public: |
- enum MatchType { kPrefix, kSuffix, kEquals, kContains }; |
- |
- // |data| is the pattern to be matched in the position given by |type|. |
- // Note that |data| must point to a StringValue object. |
- static scoped_ptr<StringMatchTest> Create(const base::Value* data, |
- MatchType type, |
- bool case_sensitive); |
- ~StringMatchTest(); |
- |
- // Does |str| pass |this| StringMatchTest? |
- bool Matches(const std::string& str) const; |
- |
- private: |
- StringMatchTest(const std::string& data, |
- MatchType type, |
- bool case_sensitive); |
- |
- const std::string data_; |
- const MatchType type_; |
- const bool case_sensitive_; |
- DISALLOW_COPY_AND_ASSIGN(StringMatchTest); |
- }; |
- |
- // Represents a test group -- a set of string matching tests to be applied to |
- // both the header name and value. |
- class HeaderMatchTest { |
- public: |
- ~HeaderMatchTest(); |
- |
- // Gets the test group description in |tests| and creates the corresponding |
- // HeaderMatchTest. On failure returns NULL. |
- static scoped_ptr<const HeaderMatchTest> Create( |
- const base::DictionaryValue* tests); |
- |
- // Does the header "|name|: |value|" match all tests in |this|? |
- bool Matches(const std::string& name, const std::string& value) const; |
- |
- private: |
- // Takes ownership of the content of both |name_match| and |value_match|. |
- HeaderMatchTest(ScopedVector<const StringMatchTest>* name_match, |
- ScopedVector<const StringMatchTest>* value_match); |
- |
- // Tests to be passed by a header's name. |
- const ScopedVector<const StringMatchTest> name_match_; |
- // Tests to be passed by a header's value. |
- const ScopedVector<const StringMatchTest> value_match_; |
- DISALLOW_COPY_AND_ASSIGN(HeaderMatchTest); |
- }; |
- |
- explicit HeaderMatcher(ScopedVector<const HeaderMatchTest>* tests); |
- |
- const ScopedVector<const HeaderMatchTest> tests_; |
- |
- DISALLOW_COPY_AND_ASSIGN(HeaderMatcher); |
-}; |
- |
-// HeaderMatcher implementation. |
- |
-HeaderMatcher::~HeaderMatcher() {} |
- |
-// static |
-scoped_ptr<const HeaderMatcher> HeaderMatcher::Create( |
- const base::ListValue* tests) { |
- ScopedVector<const HeaderMatchTest> header_tests; |
- for (base::ListValue::const_iterator it = tests->begin(); |
- it != tests->end(); ++it) { |
- const base::DictionaryValue* tests = NULL; |
- if (!(*it)->GetAsDictionary(&tests)) |
- return scoped_ptr<const HeaderMatcher>(); |
- |
- scoped_ptr<const HeaderMatchTest> header_test( |
- HeaderMatchTest::Create(tests)); |
- if (header_test.get() == NULL) |
- return scoped_ptr<const HeaderMatcher>(); |
- header_tests.push_back(header_test.release()); |
- } |
- |
- return scoped_ptr<const HeaderMatcher>(new HeaderMatcher(&header_tests)); |
-} |
- |
-bool HeaderMatcher::TestNameValue(const std::string& name, |
- const std::string& value) const { |
- for (size_t i = 0; i < tests_.size(); ++i) { |
- if (tests_[i]->Matches(name, value)) |
- return true; |
- } |
- return false; |
-} |
- |
-HeaderMatcher::HeaderMatcher(ScopedVector<const HeaderMatchTest>* tests) |
- : tests_(tests->Pass()) {} |
- |
-// HeaderMatcher::StringMatchTest implementation. |
- |
-// static |
-scoped_ptr<HeaderMatcher::StringMatchTest> |
-HeaderMatcher::StringMatchTest::Create(const base::Value* data, |
- MatchType type, |
- bool case_sensitive) { |
- std::string str; |
- CHECK(data->GetAsString(&str)); |
- return scoped_ptr<StringMatchTest>( |
- new StringMatchTest(str, type, case_sensitive)); |
-} |
- |
-HeaderMatcher::StringMatchTest::~StringMatchTest() {} |
- |
-bool HeaderMatcher::StringMatchTest::Matches( |
- const std::string& str) const { |
- switch (type_) { |
- case kPrefix: |
- return StartsWithASCII(str, data_, case_sensitive_); |
- case kSuffix: |
- return EndsWith(str, data_, case_sensitive_); |
- case kEquals: |
- return str.size() == data_.size() && |
- StartsWithASCII(str, data_, case_sensitive_); |
- case kContains: |
- if (!case_sensitive_) { |
- return std::search(str.begin(), str.end(), data_.begin(), data_.end(), |
- CaseInsensitiveCompareASCII<char>()) != str.end(); |
- } else { |
- return str.find(data_) != std::string::npos; |
- } |
- } |
- // We never get past the "switch", but the compiler worries about no return. |
- NOTREACHED(); |
- return false; |
-} |
- |
-HeaderMatcher::StringMatchTest::StringMatchTest(const std::string& data, |
- MatchType type, |
- bool case_sensitive) |
- : data_(data), |
- type_(type), |
- case_sensitive_(case_sensitive) {} |
- |
-// HeaderMatcher::HeaderMatchTest implementation. |
- |
-HeaderMatcher::HeaderMatchTest::HeaderMatchTest( |
- ScopedVector<const StringMatchTest>* name_match, |
- ScopedVector<const StringMatchTest>* value_match) |
- : name_match_(name_match->Pass()), |
- value_match_(value_match->Pass()) {} |
- |
-HeaderMatcher::HeaderMatchTest::~HeaderMatchTest() {} |
- |
-// static |
-scoped_ptr<const HeaderMatcher::HeaderMatchTest> |
-HeaderMatcher::HeaderMatchTest::Create(const base::DictionaryValue* tests) { |
- ScopedVector<const StringMatchTest> name_match; |
- ScopedVector<const StringMatchTest> value_match; |
- |
- for (base::DictionaryValue::Iterator it(*tests); |
- !it.IsAtEnd(); it.Advance()) { |
- bool is_name = false; // Is this test for header name? |
- StringMatchTest::MatchType match_type; |
- if (it.key() == keys::kNamePrefixKey) { |
- is_name = true; |
- match_type = StringMatchTest::kPrefix; |
- } else if (it.key() == keys::kNameSuffixKey) { |
- is_name = true; |
- match_type = StringMatchTest::kSuffix; |
- } else if (it.key() == keys::kNameContainsKey) { |
- is_name = true; |
- match_type = StringMatchTest::kContains; |
- } else if (it.key() == keys::kNameEqualsKey) { |
- is_name = true; |
- match_type = StringMatchTest::kEquals; |
- } else if (it.key() == keys::kValuePrefixKey) { |
- match_type = StringMatchTest::kPrefix; |
- } else if (it.key() == keys::kValueSuffixKey) { |
- match_type = StringMatchTest::kSuffix; |
- } else if (it.key() == keys::kValueContainsKey) { |
- match_type = StringMatchTest::kContains; |
- } else if (it.key() == keys::kValueEqualsKey) { |
- match_type = StringMatchTest::kEquals; |
- } else { |
- NOTREACHED(); // JSON schema type checking should prevent this. |
- return scoped_ptr<const HeaderMatchTest>(); |
- } |
- const base::Value* content = &it.value(); |
- |
- ScopedVector<const StringMatchTest>* tests = |
- is_name ? &name_match : &value_match; |
- switch (content->GetType()) { |
- case base::Value::TYPE_LIST: { |
- const base::ListValue* list = NULL; |
- CHECK(content->GetAsList(&list)); |
- for (base::ListValue::const_iterator it = list->begin(); |
- it != list->end(); ++it) { |
- tests->push_back( |
- StringMatchTest::Create(*it, match_type, !is_name).release()); |
- } |
- break; |
- } |
- case base::Value::TYPE_STRING: { |
- tests->push_back( |
- StringMatchTest::Create(content, match_type, !is_name).release()); |
- break; |
- } |
- default: { |
- NOTREACHED(); // JSON schema type checking should prevent this. |
- return scoped_ptr<const HeaderMatchTest>(); |
- } |
- } |
- } |
- |
- return scoped_ptr<const HeaderMatchTest>( |
- new HeaderMatchTest(&name_match, &value_match)); |
-} |
- |
-bool HeaderMatcher::HeaderMatchTest::Matches(const std::string& name, |
- const std::string& value) const { |
- for (size_t i = 0; i < name_match_.size(); ++i) { |
- if (!name_match_[i]->Matches(name)) |
- return false; |
- } |
- |
- for (size_t i = 0; i < value_match_.size(); ++i) { |
- if (!value_match_[i]->Matches(value)) |
- return false; |
- } |
- |
- return true; |
-} |
- |
-// |
-// WebRequestConditionAttributeRequestHeaders |
-// |
- |
-WebRequestConditionAttributeRequestHeaders:: |
-WebRequestConditionAttributeRequestHeaders( |
- scoped_ptr<const HeaderMatcher> header_matcher, |
- bool positive) |
- : header_matcher_(header_matcher.Pass()), |
- positive_(positive) {} |
- |
-WebRequestConditionAttributeRequestHeaders:: |
-~WebRequestConditionAttributeRequestHeaders() {} |
- |
-namespace { |
- |
-scoped_ptr<const HeaderMatcher> PrepareHeaderMatcher( |
- const std::string& name, |
- const base::Value* value, |
- std::string* error) { |
- const base::ListValue* value_as_list = NULL; |
- if (!value->GetAsList(&value_as_list)) { |
- *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); |
- return scoped_ptr<const HeaderMatcher>(); |
- } |
- |
- scoped_ptr<const HeaderMatcher> header_matcher( |
- HeaderMatcher::Create(value_as_list)); |
- if (header_matcher.get() == NULL) |
- *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); |
- return header_matcher.Pass(); |
-} |
- |
-} // namespace |
- |
-// static |
-scoped_refptr<const WebRequestConditionAttribute> |
-WebRequestConditionAttributeRequestHeaders::Create( |
- const std::string& name, |
- const base::Value* value, |
- std::string* error, |
- bool* bad_message) { |
- DCHECK(name == keys::kRequestHeadersKey || |
- name == keys::kExcludeRequestHeadersKey); |
- |
- scoped_ptr<const HeaderMatcher> header_matcher( |
- PrepareHeaderMatcher(name, value, error)); |
- if (header_matcher.get() == NULL) |
- return scoped_refptr<const WebRequestConditionAttribute>(NULL); |
- |
- return scoped_refptr<const WebRequestConditionAttribute>( |
- new WebRequestConditionAttributeRequestHeaders( |
- header_matcher.Pass(), name == keys::kRequestHeadersKey)); |
-} |
- |
-int WebRequestConditionAttributeRequestHeaders::GetStages() const { |
- // Currently we only allow matching against headers in the before-send-headers |
- // stage. The headers are accessible in other stages as well, but before |
- // allowing to match against them in further stages, we should consider |
- // caching the match result. |
- return ON_BEFORE_SEND_HEADERS; |
-} |
- |
-bool WebRequestConditionAttributeRequestHeaders::IsFulfilled( |
- const WebRequestData& request_data) const { |
- if (!(request_data.stage & GetStages())) |
- return false; |
- |
- const net::HttpRequestHeaders& headers = |
- request_data.request->extra_request_headers(); |
- |
- bool passed = false; // Did some header pass TestNameValue? |
- net::HttpRequestHeaders::Iterator it(headers); |
- while (!passed && it.GetNext()) |
- passed |= header_matcher_->TestNameValue(it.name(), it.value()); |
- |
- return (positive_ ? passed : !passed); |
-} |
- |
-WebRequestConditionAttribute::Type |
-WebRequestConditionAttributeRequestHeaders::GetType() const { |
- return CONDITION_REQUEST_HEADERS; |
-} |
- |
-std::string WebRequestConditionAttributeRequestHeaders::GetName() const { |
- return (positive_ ? keys::kRequestHeadersKey |
- : keys::kExcludeRequestHeadersKey); |
-} |
- |
-bool WebRequestConditionAttributeRequestHeaders::Equals( |
- const WebRequestConditionAttribute* other) const { |
- // Comparing headers is too heavy, so we skip it entirely. |
- return false; |
-} |
- |
-// |
-// WebRequestConditionAttributeResponseHeaders |
-// |
- |
-WebRequestConditionAttributeResponseHeaders:: |
-WebRequestConditionAttributeResponseHeaders( |
- scoped_ptr<const HeaderMatcher> header_matcher, |
- bool positive) |
- : header_matcher_(header_matcher.Pass()), |
- positive_(positive) {} |
- |
-WebRequestConditionAttributeResponseHeaders:: |
-~WebRequestConditionAttributeResponseHeaders() {} |
- |
-// static |
-scoped_refptr<const WebRequestConditionAttribute> |
-WebRequestConditionAttributeResponseHeaders::Create( |
- const std::string& name, |
- const base::Value* value, |
- std::string* error, |
- bool* bad_message) { |
- DCHECK(name == keys::kResponseHeadersKey || |
- name == keys::kExcludeResponseHeadersKey); |
- |
- scoped_ptr<const HeaderMatcher> header_matcher( |
- PrepareHeaderMatcher(name, value, error)); |
- if (header_matcher.get() == NULL) |
- return scoped_refptr<const WebRequestConditionAttribute>(NULL); |
- |
- return scoped_refptr<const WebRequestConditionAttribute>( |
- new WebRequestConditionAttributeResponseHeaders( |
- header_matcher.Pass(), name == keys::kResponseHeadersKey)); |
-} |
- |
-int WebRequestConditionAttributeResponseHeaders::GetStages() const { |
- return ON_HEADERS_RECEIVED; |
-} |
- |
-bool WebRequestConditionAttributeResponseHeaders::IsFulfilled( |
- const WebRequestData& request_data) const { |
- if (!(request_data.stage & GetStages())) |
- return false; |
- |
- const net::HttpResponseHeaders* headers = |
- request_data.original_response_headers; |
- if (headers == NULL) { |
- // Each header of an empty set satisfies (the negation of) everything; |
- // OTOH, there is no header to satisfy even the most permissive test. |
- return !positive_; |
- } |
- |
- bool passed = false; // Did some header pass TestNameValue? |
- std::string name; |
- std::string value; |
- void* iter = NULL; |
- while (!passed && headers->EnumerateHeaderLines(&iter, &name, &value)) { |
- passed |= header_matcher_->TestNameValue(name, value); |
- } |
- |
- return (positive_ ? passed : !passed); |
-} |
- |
-WebRequestConditionAttribute::Type |
-WebRequestConditionAttributeResponseHeaders::GetType() const { |
- return CONDITION_RESPONSE_HEADERS; |
-} |
- |
-std::string WebRequestConditionAttributeResponseHeaders::GetName() const { |
- return (positive_ ? keys::kResponseHeadersKey |
- : keys::kExcludeResponseHeadersKey); |
-} |
- |
-bool WebRequestConditionAttributeResponseHeaders::Equals( |
- const WebRequestConditionAttribute* other) const { |
- return false; |
-} |
- |
-// |
-// WebRequestConditionAttributeThirdParty |
-// |
- |
-WebRequestConditionAttributeThirdParty:: |
-WebRequestConditionAttributeThirdParty(bool match_third_party) |
- : match_third_party_(match_third_party) {} |
- |
-WebRequestConditionAttributeThirdParty:: |
-~WebRequestConditionAttributeThirdParty() {} |
- |
-// static |
-scoped_refptr<const WebRequestConditionAttribute> |
-WebRequestConditionAttributeThirdParty::Create( |
- const std::string& name, |
- const base::Value* value, |
- std::string* error, |
- bool* bad_message) { |
- DCHECK(name == keys::kThirdPartyKey); |
- |
- bool third_party = false; // Dummy value, gets overwritten. |
- if (!value->GetAsBoolean(&third_party)) { |
- *error = ErrorUtils::FormatErrorMessage(kInvalidValue, |
- keys::kThirdPartyKey); |
- return scoped_refptr<const WebRequestConditionAttribute>(NULL); |
- } |
- |
- return scoped_refptr<const WebRequestConditionAttribute>( |
- new WebRequestConditionAttributeThirdParty(third_party)); |
-} |
- |
-int WebRequestConditionAttributeThirdParty::GetStages() const { |
- return ON_BEFORE_REQUEST | ON_BEFORE_SEND_HEADERS | ON_SEND_HEADERS | |
- ON_HEADERS_RECEIVED | ON_AUTH_REQUIRED | ON_BEFORE_REDIRECT | |
- ON_RESPONSE_STARTED | ON_COMPLETED | ON_ERROR; |
-} |
- |
-bool WebRequestConditionAttributeThirdParty::IsFulfilled( |
- const WebRequestData& request_data) const { |
- if (!(request_data.stage & GetStages())) |
- return false; |
- |
- // Request is "1st party" if it gets cookies under 3rd party-blocking policy. |
- const net::StaticCookiePolicy block_third_party_policy( |
- net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES); |
- const int can_get_cookies = block_third_party_policy.CanGetCookies( |
- request_data.request->url(), |
- request_data.request->first_party_for_cookies()); |
- const bool is_first_party = (can_get_cookies == net::OK); |
- |
- return match_third_party_ ? !is_first_party : is_first_party; |
-} |
- |
-WebRequestConditionAttribute::Type |
-WebRequestConditionAttributeThirdParty::GetType() const { |
- return CONDITION_THIRD_PARTY; |
-} |
- |
-std::string WebRequestConditionAttributeThirdParty::GetName() const { |
- return keys::kThirdPartyKey; |
-} |
- |
-bool WebRequestConditionAttributeThirdParty::Equals( |
- const WebRequestConditionAttribute* other) const { |
- if (!WebRequestConditionAttribute::Equals(other)) |
- return false; |
- const WebRequestConditionAttributeThirdParty* casted_other = |
- static_cast<const WebRequestConditionAttributeThirdParty*>(other); |
- return match_third_party_ == casted_other->match_third_party_; |
-} |
- |
-// |
-// WebRequestConditionAttributeStages |
-// |
- |
-WebRequestConditionAttributeStages:: |
-WebRequestConditionAttributeStages(int allowed_stages) |
- : allowed_stages_(allowed_stages) {} |
- |
-WebRequestConditionAttributeStages:: |
-~WebRequestConditionAttributeStages() {} |
- |
-namespace { |
- |
-// Reads strings stored in |value|, which is expected to be a ListValue, and |
-// sets corresponding bits (see RequestStage) in |out_stages|. Returns true on |
-// success, false otherwise. |
-bool ParseListOfStages(const base::Value& value, int* out_stages) { |
- const base::ListValue* list = NULL; |
- if (!value.GetAsList(&list)) |
- return false; |
- |
- int stages = 0; |
- std::string stage_name; |
- for (base::ListValue::const_iterator it = list->begin(); |
- it != list->end(); ++it) { |
- if (!((*it)->GetAsString(&stage_name))) |
- return false; |
- if (stage_name == keys::kOnBeforeRequestEnum) { |
- stages |= ON_BEFORE_REQUEST; |
- } else if (stage_name == keys::kOnBeforeSendHeadersEnum) { |
- stages |= ON_BEFORE_SEND_HEADERS; |
- } else if (stage_name == keys::kOnHeadersReceivedEnum) { |
- stages |= ON_HEADERS_RECEIVED; |
- } else if (stage_name == keys::kOnAuthRequiredEnum) { |
- stages |= ON_AUTH_REQUIRED; |
- } else { |
- NOTREACHED(); // JSON schema checks prevent getting here. |
- return false; |
- } |
- } |
- |
- *out_stages = stages; |
- return true; |
-} |
- |
-} // namespace |
- |
-// static |
-scoped_refptr<const WebRequestConditionAttribute> |
-WebRequestConditionAttributeStages::Create(const std::string& name, |
- const base::Value* value, |
- std::string* error, |
- bool* bad_message) { |
- DCHECK(name == keys::kStagesKey); |
- |
- int allowed_stages = 0; |
- if (!ParseListOfStages(*value, &allowed_stages)) { |
- *error = ErrorUtils::FormatErrorMessage(kInvalidValue, |
- keys::kStagesKey); |
- return scoped_refptr<const WebRequestConditionAttribute>(NULL); |
- } |
- |
- return scoped_refptr<const WebRequestConditionAttribute>( |
- new WebRequestConditionAttributeStages(allowed_stages)); |
-} |
- |
-int WebRequestConditionAttributeStages::GetStages() const { |
- return allowed_stages_; |
-} |
- |
-bool WebRequestConditionAttributeStages::IsFulfilled( |
- const WebRequestData& request_data) const { |
- // Note: removing '!=' triggers warning C4800 on the VS compiler. |
- return (request_data.stage & GetStages()) != 0; |
-} |
- |
-WebRequestConditionAttribute::Type |
-WebRequestConditionAttributeStages::GetType() const { |
- return CONDITION_STAGES; |
-} |
- |
-std::string WebRequestConditionAttributeStages::GetName() const { |
- return keys::kStagesKey; |
-} |
- |
-bool WebRequestConditionAttributeStages::Equals( |
- const WebRequestConditionAttribute* other) const { |
- if (!WebRequestConditionAttribute::Equals(other)) |
- return false; |
- const WebRequestConditionAttributeStages* casted_other = |
- static_cast<const WebRequestConditionAttributeStages*>(other); |
- return allowed_stages_ == casted_other->allowed_stages_; |
-} |
- |
-} // namespace extensions |