Index: chrome/browser/extensions/api/web_request/web_request_api_unittest.cc |
diff --git a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc |
index fc3dc17c564494ba300ae51a06d757d2e47148ad..6d6f58d79440d246514f3fc5b2c30c4d8289fd6e 100644 |
--- a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc |
+++ b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc |
@@ -73,6 +73,32 @@ bool Contains(const Collection& collection, const Key& key) { |
collection.end(); |
} |
+// Inspects the data attached to the |message| and tries to extract its |
+// "keys::kFormDataKey" section into |form_data|. Returns true on success. |
+bool GetFormData(IPC::Message* message, std::string* form_data) { |
+ CHECK(message->type() == ExtensionMsg_MessageInvoke::ID); |
+ ExtensionMsg_MessageInvoke::Param param; |
+ Value* temp_value = NULL; |
+ CHECK(ExtensionMsg_MessageInvoke::Read(message, ¶m)); |
+ CHECK(param.c.GetSize() >= 2); |
+ CHECK(param.c.Get(1, &temp_value)); |
+ std::string args; |
+ CHECK(temp_value->GetAsString(&args)); |
+ |
+ const std::string kFormDataHead( |
+ std::string("\"") + keys::kFormDataKey + "\":{"); |
+ size_t form_data_start = args.find(kFormDataHead); |
+ if (form_data_start == std::string::npos) |
+ return false; |
+ form_data_start += kFormDataHead.size(); |
+ |
+ const size_t form_data_end = args.find("}", form_data_start); |
+ CHECK(form_data_end != std::string::npos); |
+ const size_t form_data_length = form_data_end - form_data_start; |
+ *form_data = std::string(args, form_data_start, form_data_length); |
+ return true; |
+} |
+ |
} // namespace |
// A mock event router that responds to events with a pre-arranged queue of |
@@ -133,6 +159,10 @@ class ExtensionWebRequestTest : public testing::Test { |
context_->Init(); |
} |
+ // Fires a URLRequest with the specified |content_type|. Method will be "POST" |
+ // and the data will be |bytes|. |
+ void FireURLRequestWithPostData(const char* content_type, const char* bytes); |
+ |
MessageLoopForIO message_loop_; |
content::TestBrowserThread ui_thread_; |
content::TestBrowserThread io_thread_; |
@@ -398,7 +428,91 @@ TEST_F(ExtensionWebRequestTest, SimulateChancelWhileBlocked) { |
ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
&profile_, extension_id, kEventName + "/1"); |
ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
- &profile_, extension_id, kEventName2 + "/1"); |
+ &profile_, extension_id, kEventName2 + "/1"); |
+} |
+ |
+void ExtensionWebRequestTest::FireURLRequestWithPostData( |
+ const char* content_type, |
+ const char* bytes) { |
+ // The request URL can be arbitrary but must have an HTTP or HTTPS scheme. |
+ GURL request_url("http://www.example.com"); |
+ net::URLRequest request(request_url, &delegate_, context_.get()); |
+ request.set_method("POST"); |
+ request.SetExtraRequestHeaderByName("Content-Type", content_type, true); |
+ request.AppendBytesToUpload(bytes, strlen(bytes)); |
+ ipc_sender_.PushTask(base::Bind(&base::DoNothing)); |
+ request.Start(); |
+} |
+ |
+TEST_F(ExtensionWebRequestTest, AccessPostData) { |
+ // We verify that POST data are accessible to OnBeforeRequest listeners. |
+ // Construct the test data. |
+#define kBoundary "THIS_IS_A_BOUNDARY" |
+#define kBlock "--" kBoundary "\r\n" \ |
+ "Content-Disposition: form-data; name=\"text\"\r\n" \ |
+ "\r\n" \ |
+ "test text\r\n" \ |
+ "--" kBoundary "--" |
+ // POST data input. |
+ const char kMultipartBytes[] = kBlock; |
+ // POST data output. |
+ const char kResultString[] = "\"text\":[\"test text\"]"; |
+ // Header. |
+ const char kMultipart[] = "multipart/form-data; boundary=" kBoundary; |
+#undef kBlock |
+#undef kBoundary |
+ bool kSuccessExpected[] = {true, false}; |
+ |
+ // Set up a dummy extension name. |
+ ExtensionWebRequestEventRouter::RequestFilter filter; |
+ std::string extension_id("1"); |
+ int extra_info_spec_post = |
+ ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING | |
+ ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_POST_DATA; |
+ int extra_info_spec_no_post = |
+ ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING; |
+ |
+ // Subscribe to OnBeforeRequest with POST data requirement. |
+ const std::string kEventName(keys::kOnBeforeRequest); |
+ base::WeakPtrFactory<TestIPCSender> ipc_sender_factory(&ipc_sender_); |
+ ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( |
+ &profile_, extension_id, extension_id, kEventName, kEventName + "/1", |
+ filter, extra_info_spec_post, ipc_sender_factory.GetWeakPtr()); |
+ |
+ FireURLRequestWithPostData(kMultipart, kMultipartBytes); |
+ |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ // Now remove the requirement of POST data. |
+ ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
+ &profile_, extension_id, kEventName + "/1"); |
+ ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( |
+ &profile_, extension_id, extension_id, kEventName, kEventName + "/1", |
+ filter, extra_info_spec_no_post, ipc_sender_factory.GetWeakPtr()); |
+ |
+ FireURLRequestWithPostData(kMultipart, kMultipartBytes); |
+ |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ IPC::Message* message = NULL; |
+ std::string form_data; |
+ TestIPCSender::SentMessages::const_iterator i = ipc_sender_.sent_begin(); |
+ for (size_t test = 0; test < arraysize(kSuccessExpected); ++test) { |
+ EXPECT_NE(i, ipc_sender_.sent_end()); |
+ message = (i++)->get(); |
+ if (kSuccessExpected[test]) { |
+ EXPECT_TRUE(GetFormData(message, &form_data)) << test; |
+ EXPECT_EQ(kResultString, form_data); |
+ } else { |
+ EXPECT_FALSE(GetFormData(message, &form_data)); |
+ } |
+ } |
+ |
+ EXPECT_EQ(i, ipc_sender_.sent_end()); |
+ |
+ // Clean-up. |
+ ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
+ &profile_, extension_id, kEventName + "/1"); |
} |
struct HeaderModificationTest_Header { |
@@ -663,6 +777,10 @@ TEST_F(ExtensionWebRequestTest, InitFromValue) { |
"asyncBlocking", |
true, |
ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING); |
+ TestInitFromValue( |
+ "requestPostData", |
+ true, |
+ ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_POST_DATA); |
// Multiple valid values are bitwise-or'ed. |
TestInitFromValue( |