Commit 5fd4a562 authored by yoz@chromium.org's avatar yoz@chromium.org

Support also excluding content types in declarative webrequest conditions.

BUG=112155

Review URL: https://chromiumcodereview.appspot.com/10825212

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150421 0039d316-1c4b-4281-b951-d872f2087c98
parent 52dc056c
...@@ -144,8 +144,10 @@ WebRequestConditionAttributeResourceType::GetType() const { ...@@ -144,8 +144,10 @@ WebRequestConditionAttributeResourceType::GetType() const {
WebRequestConditionAttributeContentType:: WebRequestConditionAttributeContentType::
WebRequestConditionAttributeContentType( WebRequestConditionAttributeContentType(
const std::vector<std::string>& content_types) const std::vector<std::string>& content_types,
: content_types_(content_types) {} bool inclusive)
: content_types_(content_types),
inclusive_(inclusive) {}
WebRequestConditionAttributeContentType:: WebRequestConditionAttributeContentType::
~WebRequestConditionAttributeContentType() {} ~WebRequestConditionAttributeContentType() {}
...@@ -153,7 +155,8 @@ WebRequestConditionAttributeContentType:: ...@@ -153,7 +155,8 @@ WebRequestConditionAttributeContentType::
// static // static
bool WebRequestConditionAttributeContentType::IsMatchingType( bool WebRequestConditionAttributeContentType::IsMatchingType(
const std::string& instance_type) { const std::string& instance_type) {
return instance_type == keys::kContentTypeKey; return instance_type == keys::kContentTypeKey ||
instance_type == keys::kExcludeContentTypeKey;
} }
// static // static
...@@ -162,27 +165,27 @@ WebRequestConditionAttributeContentType::Create( ...@@ -162,27 +165,27 @@ WebRequestConditionAttributeContentType::Create(
const std::string& name, const std::string& name,
const base::Value* value, const base::Value* value,
std::string* error) { std::string* error) {
std::vector<std::string> content_types; DCHECK(IsMatchingType(name));
const ListValue* value_as_list = NULL; const ListValue* value_as_list = NULL;
if (!value->GetAsList(&value_as_list)) { if (!value->GetAsList(&value_as_list)) {
*error = ExtensionErrorUtils::FormatErrorMessage(kInvalidValue, *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidValue, name);
keys::kContentTypeKey);
return scoped_ptr<WebRequestConditionAttribute>(NULL); return scoped_ptr<WebRequestConditionAttribute>(NULL);
} }
std::vector<std::string> content_types;
for (ListValue::const_iterator it = value_as_list->begin(); for (ListValue::const_iterator it = value_as_list->begin();
it != value_as_list->end(); ++it) { it != value_as_list->end(); ++it) {
std::string content_type; std::string content_type;
if (!(*it)->GetAsString(&content_type)) { if (!(*it)->GetAsString(&content_type)) {
*error = ExtensionErrorUtils::FormatErrorMessage(kInvalidValue, *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidValue, name);
keys::kContentTypeKey);
return scoped_ptr<WebRequestConditionAttribute>(NULL); return scoped_ptr<WebRequestConditionAttribute>(NULL);
} }
content_types.push_back(content_type); content_types.push_back(content_type);
} }
return scoped_ptr<WebRequestConditionAttribute>( return scoped_ptr<WebRequestConditionAttribute>(
new WebRequestConditionAttributeContentType(content_types)); new WebRequestConditionAttributeContentType(
content_types, name == keys::kContentTypeKey));
} }
int WebRequestConditionAttributeContentType::GetStages() const { int WebRequestConditionAttributeContentType::GetStages() const {
...@@ -202,8 +205,13 @@ bool WebRequestConditionAttributeContentType::IsFulfilled( ...@@ -202,8 +205,13 @@ bool WebRequestConditionAttributeContentType::IsFulfilled(
net::HttpUtil::ParseContentType( net::HttpUtil::ParseContentType(
content_type, &mime_type, &charset, &had_charset, NULL); content_type, &mime_type, &charset, &had_charset, NULL);
return std::find(content_types_.begin(), content_types_.end(), if (inclusive_) {
mime_type) != content_types_.end(); 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 WebRequestConditionAttribute::Type
......
...@@ -124,9 +124,11 @@ class WebRequestConditionAttributeContentType ...@@ -124,9 +124,11 @@ class WebRequestConditionAttributeContentType
private: private:
explicit WebRequestConditionAttributeContentType( explicit WebRequestConditionAttributeContentType(
const std::vector<std::string>& content_types); const std::vector<std::string>& include_content_types,
bool inclusive);
std::vector<std::string> content_types_; std::vector<std::string> content_types_;
bool inclusive_;
DISALLOW_COPY_AND_ASSIGN(WebRequestConditionAttributeContentType); DISALLOW_COPY_AND_ASSIGN(WebRequestConditionAttributeContentType);
}; };
......
...@@ -62,7 +62,7 @@ TEST(WebRequestConditionAttributeTest, CreateConditionAttribute) { ...@@ -62,7 +62,7 @@ TEST(WebRequestConditionAttributeTest, CreateConditionAttribute) {
result->GetType()); result->GetType());
} }
TEST(WebRequestConditionAttributeTest, TestResourceType) { TEST(WebRequestConditionAttributeTest, ResourceType) {
// Necessary for TestURLRequest. // Necessary for TestURLRequest.
MessageLoop message_loop(MessageLoop::TYPE_IO); MessageLoop message_loop(MessageLoop::TYPE_IO);
...@@ -91,7 +91,7 @@ TEST(WebRequestConditionAttributeTest, TestResourceType) { ...@@ -91,7 +91,7 @@ TEST(WebRequestConditionAttributeTest, TestResourceType) {
WebRequestRule::RequestData(&url_request_fail, ON_BEFORE_REQUEST))); WebRequestRule::RequestData(&url_request_fail, ON_BEFORE_REQUEST)));
} }
TEST(WebRequestConditionAttributeTest, TestContentType) { TEST(WebRequestConditionAttributeTest, ContentType) {
// Necessary for TestURLRequest. // Necessary for TestURLRequest.
MessageLoop message_loop(MessageLoop::TYPE_IO); MessageLoop message_loop(MessageLoop::TYPE_IO);
...@@ -114,28 +114,44 @@ TEST(WebRequestConditionAttributeTest, TestContentType) { ...@@ -114,28 +114,44 @@ TEST(WebRequestConditionAttributeTest, TestContentType) {
ListValue content_types; ListValue content_types;
content_types.Append(Value::CreateStringValue("text/html")); content_types.Append(Value::CreateStringValue("text/html"));
scoped_ptr<WebRequestConditionAttribute> attribute_ok = scoped_ptr<WebRequestConditionAttribute> attribute_include =
WebRequestConditionAttribute::Create( WebRequestConditionAttribute::Create(
keys::kContentTypeKey, &content_types, &error); keys::kContentTypeKey, &content_types, &error);
EXPECT_EQ("", error); EXPECT_EQ("", error);
ASSERT_TRUE(attribute_ok.get()); ASSERT_TRUE(attribute_include.get());
EXPECT_FALSE(attribute_include->IsFulfilled(
EXPECT_FALSE(attribute_ok->IsFulfilled(
WebRequestRule::RequestData(&url_request, ON_BEFORE_REQUEST, WebRequestRule::RequestData(&url_request, ON_BEFORE_REQUEST,
url_request.response_headers()))); url_request.response_headers())));
EXPECT_TRUE(attribute_ok->IsFulfilled( EXPECT_TRUE(attribute_include->IsFulfilled(
WebRequestRule::RequestData(&url_request, ON_HEADERS_RECEIVED,
url_request.response_headers())));
scoped_ptr<WebRequestConditionAttribute> attribute_exclude =
WebRequestConditionAttribute::Create(
keys::kExcludeContentTypeKey, &content_types, &error);
EXPECT_EQ("", error);
ASSERT_TRUE(attribute_exclude.get());
EXPECT_FALSE(attribute_exclude->IsFulfilled(
WebRequestRule::RequestData(&url_request, ON_HEADERS_RECEIVED, WebRequestRule::RequestData(&url_request, ON_HEADERS_RECEIVED,
url_request.response_headers()))); url_request.response_headers())));
content_types.Clear(); content_types.Clear();
content_types.Append(Value::CreateStringValue("something/invalid")); content_types.Append(Value::CreateStringValue("something/invalid"));
scoped_ptr<WebRequestConditionAttribute> attribute_fail = scoped_ptr<WebRequestConditionAttribute> attribute_unincluded =
WebRequestConditionAttribute::Create( WebRequestConditionAttribute::Create(
keys::kContentTypeKey, &content_types, &error); keys::kContentTypeKey, &content_types, &error);
EXPECT_EQ("", error); EXPECT_EQ("", error);
ASSERT_TRUE(attribute_fail.get()); ASSERT_TRUE(attribute_unincluded.get());
EXPECT_FALSE(attribute_unincluded->IsFulfilled(
WebRequestRule::RequestData(&url_request, ON_HEADERS_RECEIVED,
url_request.response_headers())));
EXPECT_FALSE(attribute_fail->IsFulfilled( scoped_ptr<WebRequestConditionAttribute> attribute_unexcluded =
WebRequestConditionAttribute::Create(
keys::kExcludeContentTypeKey, &content_types, &error);
EXPECT_EQ("", error);
ASSERT_TRUE(attribute_unexcluded.get());
EXPECT_TRUE(attribute_unexcluded->IsFulfilled(
WebRequestRule::RequestData(&url_request, ON_HEADERS_RECEIVED, WebRequestRule::RequestData(&url_request, ON_HEADERS_RECEIVED,
url_request.response_headers()))); url_request.response_headers())));
} }
......
...@@ -15,6 +15,7 @@ const char kCookieKey[] = "cookie"; ...@@ -15,6 +15,7 @@ const char kCookieKey[] = "cookie";
const char kContentTypeKey[] = "contentType"; const char kContentTypeKey[] = "contentType";
const char kDirectionKey[] = "direction"; const char kDirectionKey[] = "direction";
const char kDomainKey[] = "domain"; const char kDomainKey[] = "domain";
const char kExcludeContentTypeKey[] = "excludeContentType";
const char kExpiresKey[] = "expires"; const char kExpiresKey[] = "expires";
const char kFilterKey[] ="filter"; const char kFilterKey[] ="filter";
const char kFromKey[] = "from"; const char kFromKey[] = "from";
......
...@@ -18,6 +18,7 @@ extern const char kCookieKey[]; ...@@ -18,6 +18,7 @@ extern const char kCookieKey[];
extern const char kContentTypeKey[]; extern const char kContentTypeKey[];
extern const char kDirectionKey[]; extern const char kDirectionKey[];
extern const char kDomainKey[]; extern const char kDomainKey[];
extern const char kExcludeContentTypeKey[];
extern const char kExpiresKey[]; extern const char kExpiresKey[];
extern const char kFilterKey[]; extern const char kFilterKey[];
extern const char kFromKey[]; extern const char kFromKey[];
......
...@@ -29,6 +29,12 @@ ...@@ -29,6 +29,12 @@
"description": "Matches if the MIME media type of a response (from the HTTP Content-Type header) is contained in the list.", "description": "Matches if the MIME media type of a response (from the HTTP Content-Type header) is contained in the list.",
"items": { "type": "string" } "items": { "type": "string" }
}, },
"excludeContentType": {
"type": "array",
"optional": true,
"description": "Matches if the MIME media type of a response (from the HTTP Content-Type header) is <em>not</em> contained in the list.",
"items": { "type": "string" }
},
"instanceType": { "instanceType": {
"type": "string", "enum": ["declarativeWebRequest.RequestMatcher"], "type": "string", "enum": ["declarativeWebRequest.RequestMatcher"],
"nodoc": true "nodoc": true
......
...@@ -361,7 +361,7 @@ requests if and only if all listed criteria are met. The following ...@@ -361,7 +361,7 @@ requests if and only if all listed criteria are met. The following
</p> </p>
<pre>var matcher = new chrome.declarativeWebRequest.RequestMatcher({ <pre>var matcher = new chrome.declarativeWebRequest.RequestMatcher({
url: { hostSuffix: 'example.com', schemes: ['http'] }, url: { hostSuffix: 'example.com', schemes: ['http'] },
resourceType: 'main_frame' resourceType: ['main_frame']
}); });
</pre> </pre>
<p> <p>
...@@ -803,6 +803,36 @@ very fast URL matching algorithm for hundreds of thousands of URLs. ...@@ -803,6 +803,36 @@ very fast URL matching algorithm for hundreds of thousands of URLs.
<!-- OBJECT METHODS --> <!-- OBJECT METHODS -->
<!-- OBJECT EVENT FIELDS --> <!-- OBJECT EVENT FIELDS -->
<!-- FUNCTION PARAMETERS --> <!-- FUNCTION PARAMETERS -->
</div>
</div><div>
<div>
<dt>
<var>excludeContentType</var>
<em>
<!-- TYPE -->
<div style="display:inline">
(
<span class="optional">optional</span>
<span id="typeTemplate">
<span>
<span>
array of <span><span>
<span>
<span>string</span>
</span>
</span></span>
</span>
</span>
</span>
)
</div>
</em>
</dt>
<dd>Matches if the MIME media type of a response (from the HTTP Content-Type header) is <em>not</em> contained in the list.</dd>
<!-- OBJECT PROPERTIES -->
<!-- OBJECT METHODS -->
<!-- OBJECT EVENT FIELDS -->
<!-- FUNCTION PARAMETERS -->
</div> </div>
</div> </div>
</dl> </dl>
......
...@@ -177,6 +177,14 @@ ...@@ -177,6 +177,14 @@
"chrome.experimental.processes.terminate": "experimental.processes.html#method-terminate", "chrome.experimental.processes.terminate": "experimental.processes.html#method-terminate",
"chrome.experimental.record.captureURLs": "experimental.record.html#method-captureURLs", "chrome.experimental.record.captureURLs": "experimental.record.html#method-captureURLs",
"chrome.experimental.record.replayURLs": "experimental.record.html#method-replayURLs", "chrome.experimental.record.replayURLs": "experimental.record.html#method-replayURLs",
"chrome.experimental.serial.close": "experimental.serial.html#method-close",
"chrome.experimental.serial.flush": "experimental.serial.html#method-flush",
"chrome.experimental.serial.getControlSignals": "experimental.serial.html#method-getControlSignals",
"chrome.experimental.serial.getPorts": "experimental.serial.html#method-getPorts",
"chrome.experimental.serial.open": "experimental.serial.html#method-open",
"chrome.experimental.serial.read": "experimental.serial.html#method-read",
"chrome.experimental.serial.setControlSignals": "experimental.serial.html#method-setControlSignals",
"chrome.experimental.serial.write": "experimental.serial.html#method-write",
"chrome.experimental.speechInput.isRecording": "experimental.speechInput.html#method-isRecording", "chrome.experimental.speechInput.isRecording": "experimental.speechInput.html#method-isRecording",
"chrome.experimental.speechInput.onError": "experimental.speechInput.html#event-onError", "chrome.experimental.speechInput.onError": "experimental.speechInput.html#event-onError",
"chrome.experimental.speechInput.onResult": "experimental.speechInput.html#event-onResult", "chrome.experimental.speechInput.onResult": "experimental.speechInput.html#event-onResult",
......
...@@ -49,7 +49,7 @@ requests if and only if all listed criteria are met. The following ...@@ -49,7 +49,7 @@ requests if and only if all listed criteria are met. The following
<pre> <pre>
var matcher = new chrome.declarativeWebRequest.RequestMatcher({ var matcher = new chrome.declarativeWebRequest.RequestMatcher({
url: { hostSuffix: 'example.com', schemes: ['http'] }, url: { hostSuffix: 'example.com', schemes: ['http'] },
resourceType: 'main_frame' resourceType: ['main_frame']
}); });
</pre> </pre>
......
...@@ -104,7 +104,8 @@ runTests([ ...@@ -104,7 +104,8 @@ runTests([
'schemes': ["http"] 'schemes': ["http"]
}, },
'resourceType': ["main_frame"], 'resourceType': ["main_frame"],
'contentType': ["text/html"]})], 'contentType': ["text/html"],
'excludeContentType': ["image/png"]})],
'actions': [new CancelRequest()]} 'actions': [new CancelRequest()]}
], ],
function() {navigateAndWait(getURLHttpWithHeaders());} function() {navigateAndWait(getURLHttpWithHeaders());}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment