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 <queue> | 5 #include <queue> |
6 #include <map> | 6 #include <map> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 } | 66 } |
67 | 67 |
68 // Searches |key| in |collection| by iterating over its elements and returns | 68 // Searches |key| in |collection| by iterating over its elements and returns |
69 // true if found. | 69 // true if found. |
70 template <typename Collection, typename Key> | 70 template <typename Collection, typename Key> |
71 bool Contains(const Collection& collection, const Key& key) { | 71 bool Contains(const Collection& collection, const Key& key) { |
72 return std::find(collection.begin(), collection.end(), key) != | 72 return std::find(collection.begin(), collection.end(), key) != |
73 collection.end(); | 73 collection.end(); |
74 } | 74 } |
75 | 75 |
| 76 // Inspects the data attached to the |message| and tries to extract its |
| 77 // "keys::kFormDataKey" section into |form_data|. Returns true on success. |
| 78 bool GetFormData(IPC::Message* message, std::string* form_data) { |
| 79 CHECK(message->type() == ExtensionMsg_MessageInvoke::ID); |
| 80 ExtensionMsg_MessageInvoke::Param param; |
| 81 Value* temp_value = NULL; |
| 82 CHECK(ExtensionMsg_MessageInvoke::Read(message, ¶m)); |
| 83 CHECK(param.c.GetSize() >= 2); |
| 84 CHECK(param.c.Get(1, &temp_value)); |
| 85 std::string args; |
| 86 CHECK(temp_value->GetAsString(&args)); |
| 87 |
| 88 const std::string kFormDataHead( |
| 89 std::string("\"") + keys::kFormDataKey + "\":{"); |
| 90 size_t form_data_start = args.find(kFormDataHead); |
| 91 if (form_data_start == std::string::npos) |
| 92 return false; |
| 93 form_data_start += kFormDataHead.size(); |
| 94 |
| 95 const size_t form_data_end = args.find("}", form_data_start); |
| 96 CHECK(form_data_end != std::string::npos); |
| 97 const size_t form_data_length = form_data_end - form_data_start; |
| 98 *form_data = std::string(args, form_data_start, form_data_length); |
| 99 return true; |
| 100 } |
| 101 |
76 } // namespace | 102 } // namespace |
77 | 103 |
78 // A mock event router that responds to events with a pre-arranged queue of | 104 // A mock event router that responds to events with a pre-arranged queue of |
79 // Tasks. | 105 // Tasks. |
80 class TestIPCSender : public IPC::Sender { | 106 class TestIPCSender : public IPC::Sender { |
81 public: | 107 public: |
82 typedef std::list<linked_ptr<IPC::Message> > SentMessages; | 108 typedef std::list<linked_ptr<IPC::Message> > SentMessages; |
83 | 109 |
84 // Adds a Task to the queue. We will fire these in order as events are | 110 // Adds a Task to the queue. We will fire these in order as events are |
85 // dispatched. | 111 // dispatched. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 enable_referrers_.Init( | 152 enable_referrers_.Init( |
127 prefs::kEnableReferrers, profile_.GetTestingPrefService(), NULL); | 153 prefs::kEnableReferrers, profile_.GetTestingPrefService(), NULL); |
128 network_delegate_.reset(new ChromeNetworkDelegate( | 154 network_delegate_.reset(new ChromeNetworkDelegate( |
129 event_router_.get(), NULL, NULL, &profile_, | 155 event_router_.get(), NULL, NULL, &profile_, |
130 CookieSettings::Factory::GetForProfile(&profile_), &enable_referrers_)); | 156 CookieSettings::Factory::GetForProfile(&profile_), &enable_referrers_)); |
131 context_.reset(new TestURLRequestContext(true)); | 157 context_.reset(new TestURLRequestContext(true)); |
132 context_->set_network_delegate(network_delegate_.get()); | 158 context_->set_network_delegate(network_delegate_.get()); |
133 context_->Init(); | 159 context_->Init(); |
134 } | 160 } |
135 | 161 |
| 162 // Fires a URLRequest with the specified |content_type|. Method will be "POST" |
| 163 // and the data will be |bytes|. |
| 164 void FireURLRequestWithPostData(const char* content_type, const char* bytes); |
| 165 |
136 MessageLoopForIO message_loop_; | 166 MessageLoopForIO message_loop_; |
137 content::TestBrowserThread ui_thread_; | 167 content::TestBrowserThread ui_thread_; |
138 content::TestBrowserThread io_thread_; | 168 content::TestBrowserThread io_thread_; |
139 TestingProfile profile_; | 169 TestingProfile profile_; |
140 TestDelegate delegate_; | 170 TestDelegate delegate_; |
141 BooleanPrefMember enable_referrers_; | 171 BooleanPrefMember enable_referrers_; |
142 TestIPCSender ipc_sender_; | 172 TestIPCSender ipc_sender_; |
143 scoped_refptr<ExtensionEventRouterForwarder> event_router_; | 173 scoped_refptr<ExtensionEventRouterForwarder> event_router_; |
144 scoped_refptr<ExtensionInfoMap> extension_info_map_; | 174 scoped_refptr<ExtensionInfoMap> extension_info_map_; |
145 scoped_ptr<ChromeNetworkDelegate> network_delegate_; | 175 scoped_ptr<ChromeNetworkDelegate> network_delegate_; |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 EXPECT_TRUE(!request.is_pending()); | 421 EXPECT_TRUE(!request.is_pending()); |
392 EXPECT_EQ(net::URLRequestStatus::CANCELED, request.status().status()); | 422 EXPECT_EQ(net::URLRequestStatus::CANCELED, request.status().status()); |
393 EXPECT_EQ(net::ERR_ABORTED, request.status().error()); | 423 EXPECT_EQ(net::ERR_ABORTED, request.status().error()); |
394 EXPECT_EQ(request_url, request.url()); | 424 EXPECT_EQ(request_url, request.url()); |
395 EXPECT_EQ(1U, request.url_chain().size()); | 425 EXPECT_EQ(1U, request.url_chain().size()); |
396 EXPECT_EQ(0U, ipc_sender_.GetNumTasks()); | 426 EXPECT_EQ(0U, ipc_sender_.GetNumTasks()); |
397 | 427 |
398 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | 428 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
399 &profile_, extension_id, kEventName + "/1"); | 429 &profile_, extension_id, kEventName + "/1"); |
400 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | 430 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
401 &profile_, extension_id, kEventName2 + "/1"); | 431 &profile_, extension_id, kEventName2 + "/1"); |
| 432 } |
| 433 |
| 434 void ExtensionWebRequestTest::FireURLRequestWithPostData( |
| 435 const char* content_type, |
| 436 const char* bytes) { |
| 437 // The request URL can be arbitrary but must have an HTTP or HTTPS scheme. |
| 438 GURL request_url("http://www.example.com"); |
| 439 net::URLRequest request(request_url, &delegate_, context_.get()); |
| 440 request.set_method("POST"); |
| 441 request.SetExtraRequestHeaderByName("Content-Type", content_type, true); |
| 442 request.AppendBytesToUpload(bytes, strlen(bytes)); |
| 443 ipc_sender_.PushTask(base::Bind(&base::DoNothing)); |
| 444 request.Start(); |
| 445 } |
| 446 |
| 447 TEST_F(ExtensionWebRequestTest, AccessPostData) { |
| 448 // We verify that POST data are accessible to OnBeforeRequest listeners. |
| 449 // Construct the test data. |
| 450 #define kBoundary "THIS_IS_A_BOUNDARY" |
| 451 #define kBlock "--" kBoundary "\r\n" \ |
| 452 "Content-Disposition: form-data; name=\"text\"\r\n" \ |
| 453 "\r\n" \ |
| 454 "test text\r\n" \ |
| 455 "--" kBoundary "--" |
| 456 // POST data input. |
| 457 const char kMultipartBytes[] = kBlock; |
| 458 // POST data output. |
| 459 const char kResultString[] = "\"text\":[\"test text\"]"; |
| 460 // Header. |
| 461 const char kMultipart[] = "multipart/form-data; boundary=" kBoundary; |
| 462 #undef kBlock |
| 463 #undef kBoundary |
| 464 bool kSuccessExpected[] = {true, false}; |
| 465 |
| 466 // Set up a dummy extension name. |
| 467 ExtensionWebRequestEventRouter::RequestFilter filter; |
| 468 std::string extension_id("1"); |
| 469 int extra_info_spec_post = |
| 470 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING | |
| 471 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_POST_DATA; |
| 472 int extra_info_spec_no_post = |
| 473 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING; |
| 474 |
| 475 // Subscribe to OnBeforeRequest with POST data requirement. |
| 476 const std::string kEventName(keys::kOnBeforeRequest); |
| 477 base::WeakPtrFactory<TestIPCSender> ipc_sender_factory(&ipc_sender_); |
| 478 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( |
| 479 &profile_, extension_id, extension_id, kEventName, kEventName + "/1", |
| 480 filter, extra_info_spec_post, ipc_sender_factory.GetWeakPtr()); |
| 481 |
| 482 FireURLRequestWithPostData(kMultipart, kMultipartBytes); |
| 483 |
| 484 MessageLoop::current()->RunAllPending(); |
| 485 |
| 486 // Now remove the requirement of POST data. |
| 487 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
| 488 &profile_, extension_id, kEventName + "/1"); |
| 489 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( |
| 490 &profile_, extension_id, extension_id, kEventName, kEventName + "/1", |
| 491 filter, extra_info_spec_no_post, ipc_sender_factory.GetWeakPtr()); |
| 492 |
| 493 FireURLRequestWithPostData(kMultipart, kMultipartBytes); |
| 494 |
| 495 MessageLoop::current()->RunAllPending(); |
| 496 |
| 497 IPC::Message* message = NULL; |
| 498 std::string form_data; |
| 499 TestIPCSender::SentMessages::const_iterator i = ipc_sender_.sent_begin(); |
| 500 for (size_t test = 0; test < arraysize(kSuccessExpected); ++test) { |
| 501 EXPECT_NE(i, ipc_sender_.sent_end()); |
| 502 message = (i++)->get(); |
| 503 if (kSuccessExpected[test]) { |
| 504 EXPECT_TRUE(GetFormData(message, &form_data)) << test; |
| 505 EXPECT_EQ(kResultString, form_data); |
| 506 } else { |
| 507 EXPECT_FALSE(GetFormData(message, &form_data)); |
| 508 } |
| 509 } |
| 510 |
| 511 EXPECT_EQ(i, ipc_sender_.sent_end()); |
| 512 |
| 513 // Clean-up. |
| 514 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
| 515 &profile_, extension_id, kEventName + "/1"); |
402 } | 516 } |
403 | 517 |
404 struct HeaderModificationTest_Header { | 518 struct HeaderModificationTest_Header { |
405 const char* name; | 519 const char* name; |
406 const char* value; | 520 const char* value; |
407 }; | 521 }; |
408 | 522 |
409 struct HeaderModificationTest_Modification { | 523 struct HeaderModificationTest_Modification { |
410 enum Type { | 524 enum Type { |
411 SET, | 525 SET, |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 true, | 770 true, |
657 ExtensionWebRequestEventRouter::ExtraInfoSpec::RESPONSE_HEADERS); | 771 ExtensionWebRequestEventRouter::ExtraInfoSpec::RESPONSE_HEADERS); |
658 TestInitFromValue( | 772 TestInitFromValue( |
659 "blocking", | 773 "blocking", |
660 true, | 774 true, |
661 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); | 775 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); |
662 TestInitFromValue( | 776 TestInitFromValue( |
663 "asyncBlocking", | 777 "asyncBlocking", |
664 true, | 778 true, |
665 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING); | 779 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING); |
| 780 TestInitFromValue( |
| 781 "requestPostData", |
| 782 true, |
| 783 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_POST_DATA); |
666 | 784 |
667 // Multiple valid values are bitwise-or'ed. | 785 // Multiple valid values are bitwise-or'ed. |
668 TestInitFromValue( | 786 TestInitFromValue( |
669 "requestHeaders,blocking", | 787 "requestHeaders,blocking", |
670 true, | 788 true, |
671 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_HEADERS | | 789 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_HEADERS | |
672 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); | 790 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); |
673 | 791 |
674 // Any invalid values lead to a bad parse. | 792 // Any invalid values lead to a bad parse. |
675 TestInitFromValue("invalidValue", false, 0); | 793 TestInitFromValue("invalidValue", false, 0); |
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1525 // Check that requests are rejected if their first party url is sensitive. | 1643 // Check that requests are rejected if their first party url is sensitive. |
1526 ASSERT_GE(arraysize(non_sensitive_urls), 1u); | 1644 ASSERT_GE(arraysize(non_sensitive_urls), 1u); |
1527 GURL non_sensitive_url(non_sensitive_urls[0]); | 1645 GURL non_sensitive_url(non_sensitive_urls[0]); |
1528 for (size_t i = 0; i < arraysize(sensitive_urls); ++i) { | 1646 for (size_t i = 0; i < arraysize(sensitive_urls); ++i) { |
1529 TestURLRequest request(non_sensitive_url, NULL, &context); | 1647 TestURLRequest request(non_sensitive_url, NULL, &context); |
1530 GURL sensitive_url(sensitive_urls[i]); | 1648 GURL sensitive_url(sensitive_urls[i]); |
1531 request.set_first_party_for_cookies(sensitive_url); | 1649 request.set_first_party_for_cookies(sensitive_url); |
1532 EXPECT_TRUE(helpers::HideRequest(&request)) << sensitive_urls[i]; | 1650 EXPECT_TRUE(helpers::HideRequest(&request)) << sensitive_urls[i]; |
1533 } | 1651 } |
1534 } | 1652 } |
OLD | NEW |