Chromium Code Reviews| 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 13 matching lines...) Expand all Loading... | |
| 24 #include "chrome/common/extensions/extension_messages.h" | 24 #include "chrome/common/extensions/extension_messages.h" |
| 25 #include "chrome/common/pref_names.h" | 25 #include "chrome/common/pref_names.h" |
| 26 #include "chrome/test/base/testing_browser_process.h" | 26 #include "chrome/test/base/testing_browser_process.h" |
| 27 #include "chrome/test/base/testing_pref_service.h" | 27 #include "chrome/test/base/testing_pref_service.h" |
| 28 #include "chrome/test/base/testing_profile.h" | 28 #include "chrome/test/base/testing_profile.h" |
| 29 #include "content/public/test/test_browser_thread.h" | 29 #include "content/public/test/test_browser_thread.h" |
| 30 #include "net/base/auth.h" | 30 #include "net/base/auth.h" |
| 31 #include "net/base/capturing_net_log.h" | 31 #include "net/base/capturing_net_log.h" |
| 32 #include "net/base/mock_host_resolver.h" | 32 #include "net/base/mock_host_resolver.h" |
| 33 #include "net/base/net_util.h" | 33 #include "net/base/net_util.h" |
| 34 #include "net/base/upload_data.h" | |
| 34 #include "net/url_request/url_request_test_util.h" | 35 #include "net/url_request/url_request_test_util.h" |
| 35 #include "testing/gtest/include/gtest/gtest.h" | 36 #include "testing/gtest/include/gtest/gtest.h" |
| 36 | 37 |
| 37 namespace helpers = extension_web_request_api_helpers; | 38 namespace helpers = extension_web_request_api_helpers; |
| 38 namespace keys = extension_web_request_api_constants; | 39 namespace keys = extension_web_request_api_constants; |
| 39 | 40 |
| 40 using helpers::CalculateOnAuthRequiredDelta; | 41 using helpers::CalculateOnAuthRequiredDelta; |
| 41 using helpers::CalculateOnBeforeRequestDelta; | 42 using helpers::CalculateOnBeforeRequestDelta; |
| 42 using helpers::CalculateOnBeforeSendHeadersDelta; | 43 using helpers::CalculateOnBeforeSendHeadersDelta; |
| 43 using helpers::CalculateOnHeadersReceivedDelta; | 44 using helpers::CalculateOnHeadersReceivedDelta; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 66 } | 67 } |
| 67 | 68 |
| 68 // Searches |key| in |collection| by iterating over its elements and returns | 69 // Searches |key| in |collection| by iterating over its elements and returns |
| 69 // true if found. | 70 // true if found. |
| 70 template <typename Collection, typename Key> | 71 template <typename Collection, typename Key> |
| 71 bool Contains(const Collection& collection, const Key& key) { | 72 bool Contains(const Collection& collection, const Key& key) { |
| 72 return std::find(collection.begin(), collection.end(), key) != | 73 return std::find(collection.begin(), collection.end(), key) != |
| 73 collection.end(); | 74 collection.end(); |
| 74 } | 75 } |
| 75 | 76 |
| 77 // Tests whether |message| is a valid ExtensionMsg_MessageInvoke, and tries | |
| 78 // to extract a "postData" section to be passed to onBeforeRequest listeners. | |
| 79 enum TestMessageResult {kPostDataFound, kNoPostData, kError}; | |
|
battre
2012/07/06 07:36:24
style:
enum TestMessageResult {
kPostDataFound,
vabr (Chromium)
2012/07/06 14:09:01
Done.
| |
| 80 TestMessageResult TestMessage(IPC::Message* message, std::string* post_data) { | |
| 81 if (message->type() != ExtensionMsg_MessageInvoke::ID) return kError; | |
| 82 ExtensionMsg_MessageInvoke::Param param; | |
| 83 Value* temp_value = NULL; | |
| 84 if (!ExtensionMsg_MessageInvoke::Read(message, ¶m)) return kError; | |
| 85 if (param.c.GetSize() != 2) return kError; | |
| 86 if (!param.c.Get(1,&temp_value)) return kError; | |
| 87 std::string args; | |
| 88 if (!temp_value->GetAsString(&args)) return kError; | |
| 89 const char kPostDataHead[] = "\"postData\":{"; | |
| 90 size_t post_data_start = args.find(kPostDataHead); | |
| 91 if (post_data_start == std::string::npos) return kNoPostData; | |
| 92 post_data_start += sizeof(kPostDataHead) - 1; //-1 for trailing '\0' | |
| 93 const size_t post_data_end = args.find("}", post_data_start); | |
| 94 if (post_data_end == std::string::npos) return kError; | |
| 95 const size_t post_data_length = (post_data_end - 1) - post_data_start; | |
| 96 *post_data = std::string(args, post_data_start, post_data_length); | |
| 97 return kPostDataFound; | |
| 98 } | |
| 99 | |
| 76 } // namespace | 100 } // namespace |
| 77 | 101 |
| 78 // A mock event router that responds to events with a pre-arranged queue of | 102 // A mock event router that responds to events with a pre-arranged queue of |
| 79 // Tasks. | 103 // Tasks. |
| 80 class TestIPCSender : public IPC::Sender { | 104 class TestIPCSender : public IPC::Sender { |
| 81 public: | 105 public: |
| 82 typedef std::list<linked_ptr<IPC::Message> > SentMessages; | 106 typedef std::list<linked_ptr<IPC::Message> > SentMessages; |
| 83 | 107 |
| 84 // Adds a Task to the queue. We will fire these in order as events are | 108 // Adds a Task to the queue. We will fire these in order as events are |
| 85 // dispatched. | 109 // dispatched. |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 391 EXPECT_TRUE(!request.is_pending()); | 415 EXPECT_TRUE(!request.is_pending()); |
| 392 EXPECT_EQ(net::URLRequestStatus::CANCELED, request.status().status()); | 416 EXPECT_EQ(net::URLRequestStatus::CANCELED, request.status().status()); |
| 393 EXPECT_EQ(net::ERR_ABORTED, request.status().error()); | 417 EXPECT_EQ(net::ERR_ABORTED, request.status().error()); |
| 394 EXPECT_EQ(request_url, request.url()); | 418 EXPECT_EQ(request_url, request.url()); |
| 395 EXPECT_EQ(1U, request.url_chain().size()); | 419 EXPECT_EQ(1U, request.url_chain().size()); |
| 396 EXPECT_EQ(0U, ipc_sender_.GetNumTasks()); | 420 EXPECT_EQ(0U, ipc_sender_.GetNumTasks()); |
| 397 | 421 |
| 398 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | 422 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
| 399 &profile_, extension_id, kEventName + "/1"); | 423 &profile_, extension_id, kEventName + "/1"); |
| 400 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | 424 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
| 401 &profile_, extension_id, kEventName2 + "/1"); | 425 &profile_, extension_id, kEventName2 + "/1"); |
| 426 } | |
| 427 | |
| 428 TEST_F(ExtensionWebRequestTest, AccessPostData) { | |
| 429 // We verify that POST data are accessible to OnBeforeRequest listeners. | |
| 430 // Construct the test data. | |
| 431 #define kBoundary "THIS_IS_A_BOUNDARY" | |
| 432 #define kMultipartBytesBlock1 "--" kBoundary "\r\n" \ | |
| 433 "Content-Disposition: form-data; name=\"text\"\r\n" \ | |
| 434 "\r\n" \ | |
| 435 "test text\r\n" \ | |
| 436 "--" kBoundary "\r\n" \ | |
| 437 "Content-Disposition: form-data; name=\"file\"; filename=\"test\"\r\n" \ | |
| 438 "Content-Type: application/octet-stream\r\n" \ | |
| 439 "\r\n" | |
| 440 #define kMultipartBytesBlock2 "\r\n" \ | |
| 441 "--" kBoundary "\r\n" \ | |
| 442 "Content-Disposition: form-data; name=\"password\"\r\n" \ | |
| 443 "\r\n" \ | |
| 444 "test password\r\n" \ | |
| 445 "--" kBoundary "\r\n" \ | |
| 446 "Content-Disposition: form-data; name=\"radio\"\r\n" \ | |
| 447 "\r\n" \ | |
| 448 "Yes\r\n" \ | |
| 449 "--" kBoundary "\r\n" \ | |
| 450 "Content-Disposition: form-data; name=\"check\"\r\n" \ | |
| 451 "\r\n" \ | |
| 452 "option A\r\n" \ | |
| 453 "--" kBoundary "\r\n" \ | |
| 454 "Content-Disposition: form-data; name=\"check\"\r\n" \ | |
| 455 "\r\n" \ | |
| 456 "option B\r\n" \ | |
| 457 "--" kBoundary "\r\n" \ | |
| 458 "Content-Disposition: form-data; name=\"txtarea\"\r\n" \ | |
| 459 "\r\n" \ | |
| 460 "Some text.\r\n" \ | |
| 461 "Other.\r\n" \ | |
| 462 "\r\n" \ | |
| 463 "--" kBoundary "\r\n" \ | |
| 464 "Content-Disposition: form-data; name=\"select\"\r\n" \ | |
| 465 "\r\n" \ | |
| 466 "one\r\n" \ | |
| 467 "--" kBoundary "--" | |
| 468 // POST data input. | |
| 469 const char kMultipartBytes[] = kMultipartBytesBlock1 kMultipartBytesBlock2; | |
| 470 const char kMultipartBytesSplit1[] = kMultipartBytesBlock1; | |
| 471 const char kMultipartBytesSplit2[] = kMultipartBytesBlock2; | |
| 472 const char kUrlEncodedBytes[] = "text=test+text&file=test-file" | |
| 473 "&password=test+password&radio=Yes&check=option+A&check=option+B" | |
| 474 "&txtarea=Some+text.%0D%0AOther.%0D%0A&select=one"; | |
| 475 const char kTextPlainBytes[] = "dummy text"; | |
| 476 // POST data output. | |
| 477 const char kResultMultipart[] = "\"check\":[\"option A\",\"option B\"]," \ | |
| 478 "\"file\":[\"test\"],\"password\":[\"test password\"]," \ | |
| 479 "\"radio\":[\"Yes\"],\"select\":[\"one\"],\"text\":[\"test text\"]," \ | |
| 480 "\"txtarea\":[\"Some text.\\r\\nOther.\\r\\n\""; | |
| 481 const char kResultUrlEncoded[] = "\"check\":[\"option+A\",\"option+B\"]," \ | |
| 482 "\"file\":[\"test-file\"],\"password\":[\"test+password\"]," \ | |
| 483 "\"radio\":[\"Yes\"],\"select\":[\"one\"],\"text\":[\"test+text\"]," \ | |
| 484 "\"txtarea\":[\"Some+text.%0D%0AOther.%0D%0A\""; | |
| 485 const char* kResults[] = | |
| 486 {kResultMultipart, kResultMultipart, kResultUrlEncoded}; | |
| 487 // Headers. | |
| 488 const char kUrlEncoded[] = "application/x-www-form-urlencoded"; | |
| 489 const char kTextPlain[] = "text/plain"; | |
| 490 const char kMultipart[] = "multipart/form-data; boundary=" kBoundary; | |
| 491 #undef kMultipartBytesBlock2 | |
| 492 #undef kMultipartBytesBlock1 | |
| 493 #undef kBoundary | |
| 494 | |
| 495 // Set up a dummy extension name. | |
| 496 std::string extension_id("1"); | |
| 497 ExtensionWebRequestEventRouter::RequestFilter filter; | |
| 498 int extra_info_spec = | |
| 499 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING | | |
| 500 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_POST_DATA; | |
| 501 | |
| 502 // Subscribe to OnBeforeRequest. | |
| 503 const std::string kEventName(keys::kOnBeforeRequest); | |
| 504 base::WeakPtrFactory<TestIPCSender> ipc_sender_factory(&ipc_sender_); | |
| 505 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( | |
| 506 &profile_, extension_id, extension_id, kEventName, kEventName + "/1", | |
| 507 filter, extra_info_spec, ipc_sender_factory.GetWeakPtr()); | |
| 508 | |
| 509 // The request URL can be arbitrary but must have a HTTP or HTTPS scheme. | |
| 510 GURL request_url("http://www.example.com"); | |
| 511 | |
| 512 // First test: multipart POST data in one lump. | |
| 513 net::URLRequest request1(request_url, &delegate_, context_.get()); | |
| 514 request1.set_method("POST"); | |
| 515 request1.SetExtraRequestHeaderByName("Content-Type", kMultipart, true); | |
| 516 request1.AppendBytesToUpload(kMultipartBytes, sizeof(kMultipartBytes)-1); | |
| 517 ipc_sender_.PushTask(base::Bind(&base::DoNothing)); | |
| 518 request1.Start(); | |
| 519 | |
| 520 // Second test: multipart POST data in several lumps. | |
| 521 net::URLRequest request2(request_url, &delegate_, context_.get()); | |
| 522 request2.set_method("POST"); | |
| 523 request2.SetExtraRequestHeaderByName("Content-Type", kMultipart, true); | |
| 524 request2.AppendBytesToUpload(kMultipartBytesSplit1, | |
| 525 sizeof(kMultipartBytesSplit1)-1); | |
| 526 request2.AppendBytesToUpload(kMultipartBytesSplit2, | |
| 527 sizeof(kMultipartBytesSplit2)-1); | |
| 528 ipc_sender_.PushTask(base::Bind(&base::DoNothing)); | |
| 529 request2.Start(); | |
| 530 | |
| 531 // Third test: URL-encoded POST data. | |
| 532 net::URLRequest request3(request_url, &delegate_, context_.get()); | |
| 533 request3.set_method("POST"); | |
| 534 request3.SetExtraRequestHeaderByName("Content-Type", kUrlEncoded, true); | |
| 535 request3.AppendBytesToUpload(kUrlEncodedBytes, sizeof(kUrlEncodedBytes)-1); | |
| 536 ipc_sender_.PushTask(base::Bind(&base::DoNothing)); | |
| 537 request3.Start(); | |
| 538 | |
| 539 // Fourth test: text/plain POST data in one lump. | |
| 540 net::URLRequest request4(request_url, &delegate_, context_.get()); | |
| 541 request4.set_method("POST"); | |
| 542 request4.SetExtraRequestHeaderByName("Content-Type", kTextPlain, true); | |
| 543 request4.AppendBytesToUpload(kTextPlainBytes, sizeof(kTextPlainBytes)-1); | |
| 544 ipc_sender_.PushTask(base::Bind(&base::DoNothing)); | |
| 545 request4.Start(); | |
| 546 | |
| 547 MessageLoop::current()->RunAllPending(); | |
| 548 | |
| 549 IPC::Message* message = NULL; | |
| 550 std::string post_data; | |
| 551 TestIPCSender::SentMessages::const_iterator i = ipc_sender_.sent_begin(); | |
| 552 // The first 3 tests should succeed. | |
| 553 for (int test = 0; test < 3; ++test) { | |
| 554 EXPECT_FALSE(i == ipc_sender_.sent_end()); | |
| 555 message = (i++)->get(); | |
| 556 EXPECT_EQ(kPostDataFound, TestMessage(message, &post_data)); | |
| 557 EXPECT_EQ(kResults[test], post_data); | |
| 558 } | |
| 559 // Whereas the last test should fail, text/plain is not supported for parsing. | |
| 560 EXPECT_FALSE(i == ipc_sender_.sent_end()); | |
| 561 message = (i++)->get(); | |
| 562 EXPECT_EQ(kNoPostData, TestMessage(message, &post_data)); | |
| 563 | |
| 564 EXPECT_TRUE(i == ipc_sender_.sent_end()); | |
| 565 | |
| 566 // Clean-up. | |
| 567 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | |
| 568 &profile_, extension_id, kEventName + "/1"); | |
| 402 } | 569 } |
| 403 | 570 |
| 404 struct HeaderModificationTest_Header { | 571 struct HeaderModificationTest_Header { |
| 405 const char* name; | 572 const char* name; |
| 406 const char* value; | 573 const char* value; |
| 407 }; | 574 }; |
| 408 | 575 |
| 409 struct HeaderModificationTest_Modification { | 576 struct HeaderModificationTest_Modification { |
| 410 enum Type { | 577 enum Type { |
| 411 SET, | 578 SET, |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 656 true, | 823 true, |
| 657 ExtensionWebRequestEventRouter::ExtraInfoSpec::RESPONSE_HEADERS); | 824 ExtensionWebRequestEventRouter::ExtraInfoSpec::RESPONSE_HEADERS); |
| 658 TestInitFromValue( | 825 TestInitFromValue( |
| 659 "blocking", | 826 "blocking", |
| 660 true, | 827 true, |
| 661 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); | 828 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); |
| 662 TestInitFromValue( | 829 TestInitFromValue( |
| 663 "asyncBlocking", | 830 "asyncBlocking", |
| 664 true, | 831 true, |
| 665 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING); | 832 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING); |
| 833 TestInitFromValue( | |
| 834 "requestPostData", | |
| 835 true, | |
| 836 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_POST_DATA); | |
| 666 | 837 |
| 667 // Multiple valid values are bitwise-or'ed. | 838 // Multiple valid values are bitwise-or'ed. |
| 668 TestInitFromValue( | 839 TestInitFromValue( |
| 669 "requestHeaders,blocking", | 840 "requestHeaders,blocking", |
| 670 true, | 841 true, |
| 671 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_HEADERS | | 842 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_HEADERS | |
| 672 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); | 843 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); |
| 673 | 844 |
| 674 // Any invalid values lead to a bad parse. | 845 // Any invalid values lead to a bad parse. |
| 675 TestInitFromValue("invalidValue", false, 0); | 846 TestInitFromValue("invalidValue", false, 0); |
| (...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1510 }; | 1681 }; |
| 1511 for (size_t i = 0; i < arraysize(sensitive_urls); ++i) { | 1682 for (size_t i = 0; i < arraysize(sensitive_urls); ++i) { |
| 1512 EXPECT_TRUE(helpers::HideRequestForURL(GURL(sensitive_urls[i]))) | 1683 EXPECT_TRUE(helpers::HideRequestForURL(GURL(sensitive_urls[i]))) |
| 1513 << sensitive_urls[i]; | 1684 << sensitive_urls[i]; |
| 1514 } | 1685 } |
| 1515 for (size_t i = 0; i < arraysize(non_sensitive_urls); ++i) { | 1686 for (size_t i = 0; i < arraysize(non_sensitive_urls); ++i) { |
| 1516 EXPECT_FALSE(helpers::HideRequestForURL(GURL(non_sensitive_urls[i]))) | 1687 EXPECT_FALSE(helpers::HideRequestForURL(GURL(non_sensitive_urls[i]))) |
| 1517 << non_sensitive_urls[i]; | 1688 << non_sensitive_urls[i]; |
| 1518 } | 1689 } |
| 1519 } | 1690 } |
| OLD | NEW |