summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryoz@chromium.org <yoz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-06 19:08:47 +0000
committeryoz@chromium.org <yoz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-06 19:08:47 +0000
commit840eccefff0f2b79e86771216bd71ddde7e5726c (patch)
tree4fce9a28f4f2aa66c2deccca3dbc7adb18ba629d
parent8fd9eeeeeb2764568c5d4403bd0c564deb8201df (diff)
downloadchromium_src-840eccefff0f2b79e86771216bd71ddde7e5726c.zip
chromium_src-840eccefff0f2b79e86771216bd71ddde7e5726c.tar.gz
chromium_src-840eccefff0f2b79e86771216bd71ddde7e5726c.tar.bz2
Add condition attribute for MIME media types from Content-Type header.
This only supports positive tests. BUG=112155 Review URL: https://chromiumcodereview.appspot.com/10843065 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150126 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h1
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc99
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h33
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc57
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.cc1
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h1
-rw-r--r--chrome/common/extensions/api/declarative_web_request.json6
-rw-r--r--chrome/common/extensions/docs/extensions/declarativeWebRequest.html30
-rw-r--r--chrome/test/data/extensions/api_test/webrequest/declarative/headers.html1
-rw-r--r--chrome/test/data/extensions/api_test/webrequest/declarative/headers.html.mock-http-headers2
-rw-r--r--chrome/test/data/extensions/api_test/webrequest/test_declarative.js12
11 files changed, 230 insertions, 13 deletions
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h
index 0a84a84..95dc5b3 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h
@@ -11,6 +11,7 @@
#include "base/basictypes.h"
#include "base/memory/linked_ptr.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h"
+#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h"
#include "chrome/common/extensions/matcher/url_matcher.h"
namespace extensions {
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc
index d79eb3b..c52349d8 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc
@@ -12,13 +12,16 @@
#include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h"
#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
+#include "chrome/common/extensions/extension_error_utils.h"
#include "content/public/browser/resource_request_info.h"
+#include "net/http/http_util.h"
+#include "net/http/http_request_headers.h"
#include "net/url_request/url_request.h"
namespace {
// Error messages.
-const char kUnknownConditionAttribute[] = "Unknown matching condition: '%s'";
-const char kInvalidValue[] = "Condition '%s' has an invalid value";
+const char kUnknownConditionAttribute[] = "Unknown matching condition: '*'";
+const char kInvalidValue[] = "Condition '*' has an invalid value";
}
namespace helpers = extension_web_request_api_helpers;
@@ -38,8 +41,9 @@ WebRequestConditionAttribute::~WebRequestConditionAttribute() {}
// static
bool WebRequestConditionAttribute::IsKnownType(
const std::string& instance_type) {
- return WebRequestConditionAttributeResourceType::IsMatchingType(
- instance_type);
+ return
+ WebRequestConditionAttributeResourceType::IsMatchingType(instance_type) ||
+ WebRequestConditionAttributeContentType::IsMatchingType(instance_type);
}
// static
@@ -50,13 +54,15 @@ WebRequestConditionAttribute::Create(
std::string* error) {
if (WebRequestConditionAttributeResourceType::IsMatchingType(name)) {
return WebRequestConditionAttributeResourceType::Create(name, value, error);
+ } else if (WebRequestConditionAttributeContentType::IsMatchingType(name)) {
+ return WebRequestConditionAttributeContentType::Create(name, value, error);
}
- *error = base::StringPrintf(kUnknownConditionAttribute, name.c_str());
+ *error = ExtensionErrorUtils::FormatErrorMessage(kUnknownConditionAttribute,
+ name);
return scoped_ptr<WebRequestConditionAttribute>(NULL);
}
-
//
// WebRequestConditionAttributeResourceType
//
@@ -83,9 +89,10 @@ WebRequestConditionAttributeResourceType::Create(
std::string* error) {
DCHECK(IsMatchingType(name));
- const ListValue* value_as_list = 0;
+ const ListValue* value_as_list = NULL;
if (!value->GetAsList(&value_as_list)) {
- *error = base::StringPrintf(kInvalidValue, keys::kResourceTypeKey);
+ *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidValue,
+ keys::kResourceTypeKey);
return scoped_ptr<WebRequestConditionAttribute>(NULL);
}
@@ -97,7 +104,8 @@ WebRequestConditionAttributeResourceType::Create(
ResourceType::Type type = ResourceType::LAST_TYPE;
if (!value_as_list->GetString(i, &resource_type_string) ||
!helpers::ParseResourceType(resource_type_string, &type)) {
- *error = base::StringPrintf(kInvalidValue, keys::kResourceTypeKey);
+ *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidValue,
+ keys::kResourceTypeKey);
return scoped_ptr<WebRequestConditionAttribute>(NULL);
}
passed_types.push_back(type);
@@ -130,4 +138,77 @@ WebRequestConditionAttributeResourceType::GetType() const {
return CONDITION_RESOURCE_TYPE;
}
+//
+// WebRequestConditionAttributeContentType
+//
+
+WebRequestConditionAttributeContentType::
+WebRequestConditionAttributeContentType(
+ const std::vector<std::string>& content_types)
+ : content_types_(content_types) {}
+
+WebRequestConditionAttributeContentType::
+~WebRequestConditionAttributeContentType() {}
+
+// static
+bool WebRequestConditionAttributeContentType::IsMatchingType(
+ const std::string& instance_type) {
+ return instance_type == keys::kContentTypeKey;
+}
+
+// static
+scoped_ptr<WebRequestConditionAttribute>
+WebRequestConditionAttributeContentType::Create(
+ const std::string& name,
+ const base::Value* value,
+ std::string* error) {
+ std::vector<std::string> content_types;
+
+ const ListValue* value_as_list = NULL;
+ if (!value->GetAsList(&value_as_list)) {
+ *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidValue,
+ keys::kContentTypeKey);
+ return scoped_ptr<WebRequestConditionAttribute>(NULL);
+ }
+
+ for (ListValue::const_iterator it = value_as_list->begin();
+ it != value_as_list->end(); ++it) {
+ std::string content_type;
+ if (!(*it)->GetAsString(&content_type)) {
+ *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidValue,
+ keys::kContentTypeKey);
+ return scoped_ptr<WebRequestConditionAttribute>(NULL);
+ }
+ content_types.push_back(content_type);
+ }
+ return scoped_ptr<WebRequestConditionAttribute>(
+ new WebRequestConditionAttributeContentType(content_types));
+}
+
+int WebRequestConditionAttributeContentType::GetStages() const {
+ return ON_HEADERS_RECEIVED;
+}
+
+bool WebRequestConditionAttributeContentType::IsFulfilled(
+ const WebRequestRule::RequestData& request_data) {
+ 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;
+ net::HttpUtil::ParseContentType(
+ content_type, &mime_type, &charset, &had_charset, NULL);
+
+ return std::find(content_types_.begin(), content_types_.end(),
+ mime_type) != content_types_.end();
+}
+
+WebRequestConditionAttribute::Type
+WebRequestConditionAttributeContentType::GetType() const {
+ return CONDITION_CONTENT_TYPE;
+}
+
} // namespace extensions
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h
index ca420aa..cec4b55 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h
@@ -31,7 +31,8 @@ namespace extensions {
class WebRequestConditionAttribute {
public:
enum Type {
- CONDITION_RESOURCE_TYPE
+ CONDITION_RESOURCE_TYPE,
+ CONDITION_CONTENT_TYPE
};
WebRequestConditionAttribute();
@@ -100,6 +101,36 @@ class WebRequestConditionAttributeResourceType
DISALLOW_COPY_AND_ASSIGN(WebRequestConditionAttributeResourceType);
};
+// Condition that checks whether a response's Content-Type header has a
+// certain MIME media type.
+class WebRequestConditionAttributeContentType
+ : public WebRequestConditionAttribute {
+ public:
+ virtual ~WebRequestConditionAttributeContentType();
+
+ static bool IsMatchingType(const std::string& instance_type);
+
+ // Factory method, see WebRequestConditionAttribute::Create.
+ static scoped_ptr<WebRequestConditionAttribute> Create(
+ const std::string& name,
+ const base::Value* value,
+ std::string* error);
+
+ // Implementation of WebRequestConditionAttribute:
+ virtual int GetStages() const OVERRIDE;
+ virtual bool IsFulfilled(const WebRequestRule::RequestData& request_data)
+ OVERRIDE;
+ virtual Type GetType() const OVERRIDE;
+
+ private:
+ explicit WebRequestConditionAttributeContentType(
+ const std::vector<std::string>& content_types);
+
+ std::vector<std::string> content_types_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRequestConditionAttributeContentType);
+};
+
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_CONDITION_ATTRIBUTE_H_
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
index 791ac06..641d070 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
@@ -4,12 +4,14 @@
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h"
+#include "base/file_path.h"
#include "base/message_loop.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h"
#include "content/public/browser/resource_request_info.h"
#include "net/url_request/url_request_test_util.h"
+#include "net/test/test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -44,6 +46,12 @@ TEST(WebRequestConditionAttributeTest, CreateConditionAttribute) {
EXPECT_FALSE(error.empty());
EXPECT_FALSE(result.get());
+ error.clear();
+ result = WebRequestConditionAttribute::Create(
+ keys::kContentTypeKey, &string_value, &error);
+ EXPECT_FALSE(error.empty());
+ EXPECT_FALSE(result.get());
+
// Test success
error.clear();
result = WebRequestConditionAttribute::Create(
@@ -83,4 +91,53 @@ TEST(WebRequestConditionAttributeTest, TestResourceType) {
WebRequestRule::RequestData(&url_request_fail, ON_BEFORE_REQUEST)));
}
+TEST(WebRequestConditionAttributeTest, TestContentType) {
+ // Necessary for TestURLRequest.
+ MessageLoop message_loop(MessageLoop::TYPE_IO);
+
+ std::string error;
+ scoped_ptr<WebRequestConditionAttribute> result;
+
+ net::TestServer test_server(
+ net::TestServer::TYPE_HTTP,
+ net::TestServer::kLocalhost,
+ FilePath(FILE_PATH_LITERAL(
+ "chrome/test/data/extensions/api_test/webrequest/declarative")));
+ ASSERT_TRUE(test_server.Start());
+
+ TestURLRequestContext context;
+ TestDelegate delegate;
+ TestURLRequest url_request(test_server.GetURL("headers.html"),
+ &delegate, &context);
+ url_request.Start();
+ MessageLoop::current()->Run();
+
+ ListValue content_types;
+ content_types.Append(Value::CreateStringValue("text/html"));
+ scoped_ptr<WebRequestConditionAttribute> attribute_ok =
+ WebRequestConditionAttribute::Create(
+ keys::kContentTypeKey, &content_types, &error);
+ EXPECT_EQ("", error);
+ ASSERT_TRUE(attribute_ok.get());
+
+ EXPECT_FALSE(attribute_ok->IsFulfilled(
+ WebRequestRule::RequestData(&url_request, ON_BEFORE_REQUEST,
+ url_request.response_headers())));
+ EXPECT_TRUE(attribute_ok->IsFulfilled(
+ WebRequestRule::RequestData(&url_request, ON_HEADERS_RECEIVED,
+ url_request.response_headers())));
+
+ content_types.Clear();
+ content_types.Append(Value::CreateStringValue("something/invalid"));
+ scoped_ptr<WebRequestConditionAttribute> attribute_fail =
+ WebRequestConditionAttribute::Create(
+ keys::kContentTypeKey, &content_types, &error);
+ EXPECT_EQ("", error);
+ ASSERT_TRUE(attribute_fail.get());
+
+ EXPECT_FALSE(attribute_fail->IsFulfilled(
+ WebRequestRule::RequestData(&url_request, ON_HEADERS_RECEIVED,
+ url_request.response_headers())));
+}
+
} // namespace extensions
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.cc
index 8ec9d26..5a629b1 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.cc
@@ -12,6 +12,7 @@ const char kOnRequest[] = "declarativeWebRequest.onRequest";
// Keys of dictionaries.
const char kCookieKey[] = "cookie";
+const char kContentTypeKey[] = "contentType";
const char kDirectionKey[] = "direction";
const char kDomainKey[] = "domain";
const char kExpiresKey[] = "expires";
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h
index 4dc1942..3603591 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h
@@ -15,6 +15,7 @@ extern const char kOnRequest[];
// Keys of dictionaries.
extern const char kCookieKey[];
+extern const char kContentTypeKey[];
extern const char kDirectionKey[];
extern const char kDomainKey[];
extern const char kExpiresKey[];
diff --git a/chrome/common/extensions/api/declarative_web_request.json b/chrome/common/extensions/api/declarative_web_request.json
index 675eebd..2752367 100644
--- a/chrome/common/extensions/api/declarative_web_request.json
+++ b/chrome/common/extensions/api/declarative_web_request.json
@@ -23,6 +23,12 @@
"description": "Matches if the request type of a request is contained in the list. Requests that cannot match any of the types will be filtered out.",
"items": { "type": "string", "enum": ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "xmlhttprequest", "other"] }
},
+ "contentType": {
+ "type": "array",
+ "optional": true,
+ "description": "Matches if the MIME media type of a response (from the HTTP Content-Type header) is contained in the list.",
+ "items": { "type": "string" }
+ },
"instanceType": {
"type": "string", "enum": ["declarativeWebRequest.RequestMatcher"],
"nodoc": true
diff --git a/chrome/common/extensions/docs/extensions/declarativeWebRequest.html b/chrome/common/extensions/docs/extensions/declarativeWebRequest.html
index 44ab433..6dc32f0 100644
--- a/chrome/common/extensions/docs/extensions/declarativeWebRequest.html
+++ b/chrome/common/extensions/docs/extensions/declarativeWebRequest.html
@@ -774,6 +774,36 @@ very fast URL matching algorithm for hundreds of thousands of URLs.
<!-- OBJECT EVENT FIELDS -->
<!-- FUNCTION PARAMETERS -->
</div>
+ </div><div>
+ <div>
+ <dt>
+ <var>contentType</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 contained in the list.</dd>
+ <!-- OBJECT PROPERTIES -->
+ <!-- OBJECT METHODS -->
+ <!-- OBJECT EVENT FIELDS -->
+ <!-- FUNCTION PARAMETERS -->
+ </div>
</div>
</dl>
</dd>
diff --git a/chrome/test/data/extensions/api_test/webrequest/declarative/headers.html b/chrome/test/data/extensions/api_test/webrequest/declarative/headers.html
new file mode 100644
index 0000000..31174e9
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/webrequest/declarative/headers.html
@@ -0,0 +1 @@
+Nothing here. See .mock-http-headers.
diff --git a/chrome/test/data/extensions/api_test/webrequest/declarative/headers.html.mock-http-headers b/chrome/test/data/extensions/api_test/webrequest/declarative/headers.html.mock-http-headers
new file mode 100644
index 0000000..6020fce
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/webrequest/declarative/headers.html.mock-http-headers
@@ -0,0 +1,2 @@
+HTTP/1.1 200 OK
+Content-Type: text/html; UTF-8
diff --git a/chrome/test/data/extensions/api_test/webrequest/test_declarative.js b/chrome/test/data/extensions/api_test/webrequest/test_declarative.js
index f40b735..16bdf3f 100644
--- a/chrome/test/data/extensions/api_test/webrequest/test_declarative.js
+++ b/chrome/test/data/extensions/api_test/webrequest/test_declarative.js
@@ -51,6 +51,11 @@ function getURLHttpRedirectTest() {
"files/extensions/api_test/webrequest/declarative/a.html");
}
+function getURLHttpWithHeaders() {
+ return getServerURL(
+ "files/extensions/api_test/webrequest/declarative/headers.html");
+}
+
function getURLSetCookie() {
return getServerURL('set-cookie?Foo=Bar');
}
@@ -83,7 +88,7 @@ runTests([
{ label: "onErrorOccurred",
event: "onErrorOccurred",
details: {
- url: getURLHttpSimple(),
+ url: getURLHttpWithHeaders(),
fromCache: false,
error: "net::ERR_BLOCKED_BY_CLIENT"
}
@@ -98,10 +103,11 @@ runTests([
'ports': [testServerPort, [1000, 2000]],
'schemes': ["http"]
},
- 'resourceType': ["main_frame"]})],
+ 'resourceType': ["main_frame"],
+ 'contentType': ["text/html"]})],
'actions': [new CancelRequest()]}
],
- function() {navigateAndWait(getURLHttpSimple());}
+ function() {navigateAndWait(getURLHttpWithHeaders());}
);
},