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 { | |
| 80 kPostDataFound, | |
| 81 kNoPostData, | |
| 82 kError | |
| 83 }; | |
|
battre
2012/07/11 12:28:43
nit: newline
vabr (Chromium)
2012/07/12 15:13:11
Done.
| |
| 84 TestMessageResult TestMessage(IPC::Message* message, std::string* post_data) { | |
|
battre
2012/07/11 12:28:43
Can you rename this to something more descriptive?
vabr (Chromium)
2012/07/12 15:13:11
Done.
| |
| 85 if (message->type() != ExtensionMsg_MessageInvoke::ID) return kError; | |
|
battre
2012/07/11 12:28:43
can you move the return statements into the next l
battre
2012/07/11 12:28:43
I think all cases where you return kError are case
vabr (Chromium)
2012/07/12 15:13:11
Done. Had to move the return bool to (output) argu
vabr (Chromium)
2012/07/12 15:13:11
Done.
| |
| 86 ExtensionMsg_MessageInvoke::Param param; | |
| 87 Value* temp_value = NULL; | |
| 88 if (!ExtensionMsg_MessageInvoke::Read(message, ¶m)) return kError; | |
| 89 if (param.c.GetSize() != 2) return kError; | |
| 90 if (!param.c.Get(1,&temp_value)) return kError; | |
|
battre
2012/07/11 12:28:43
nit: space before &
vabr (Chromium)
2012/07/12 15:13:11
Done.
| |
| 91 std::string args; | |
| 92 if (!temp_value->GetAsString(&args)) return kError; | |
| 93 const char kPostDataHead[] = "\"postData\":{"; | |
| 94 size_t post_data_start = args.find(kPostDataHead); | |
| 95 if (post_data_start == std::string::npos) return kNoPostData; | |
| 96 post_data_start += sizeof(kPostDataHead) - 1; //-1 for trailing '\0' | |
|
battre
2012/07/11 12:28:43
nit: strlen? 2 spaces before //, 1 space after //
vabr (Chromium)
2012/07/12 15:13:11
Done.
| |
| 97 const size_t post_data_end = args.find("}", post_data_start); | |
| 98 if (post_data_end == std::string::npos) return kError; | |
| 99 const size_t post_data_length = (post_data_end - 1) - post_data_start; | |
| 100 *post_data = std::string(args, post_data_start, post_data_length); | |
| 101 return kPostDataFound; | |
| 102 } | |
| 103 | |
| 76 } // namespace | 104 } // namespace |
| 77 | 105 |
| 78 // A mock event router that responds to events with a pre-arranged queue of | 106 // A mock event router that responds to events with a pre-arranged queue of |
| 79 // Tasks. | 107 // Tasks. |
| 80 class TestIPCSender : public IPC::Sender { | 108 class TestIPCSender : public IPC::Sender { |
| 81 public: | 109 public: |
| 82 typedef std::list<linked_ptr<IPC::Message> > SentMessages; | 110 typedef std::list<linked_ptr<IPC::Message> > SentMessages; |
| 83 | 111 |
| 84 // Adds a Task to the queue. We will fire these in order as events are | 112 // Adds a Task to the queue. We will fire these in order as events are |
| 85 // dispatched. | 113 // dispatched. |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 391 EXPECT_TRUE(!request.is_pending()); | 419 EXPECT_TRUE(!request.is_pending()); |
| 392 EXPECT_EQ(net::URLRequestStatus::CANCELED, request.status().status()); | 420 EXPECT_EQ(net::URLRequestStatus::CANCELED, request.status().status()); |
| 393 EXPECT_EQ(net::ERR_ABORTED, request.status().error()); | 421 EXPECT_EQ(net::ERR_ABORTED, request.status().error()); |
| 394 EXPECT_EQ(request_url, request.url()); | 422 EXPECT_EQ(request_url, request.url()); |
| 395 EXPECT_EQ(1U, request.url_chain().size()); | 423 EXPECT_EQ(1U, request.url_chain().size()); |
| 396 EXPECT_EQ(0U, ipc_sender_.GetNumTasks()); | 424 EXPECT_EQ(0U, ipc_sender_.GetNumTasks()); |
| 397 | 425 |
| 398 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | 426 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
| 399 &profile_, extension_id, kEventName + "/1"); | 427 &profile_, extension_id, kEventName + "/1"); |
| 400 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | 428 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
| 401 &profile_, extension_id, kEventName2 + "/1"); | 429 &profile_, extension_id, kEventName2 + "/1"); |
| 430 } | |
| 431 | |
| 432 TEST_F(ExtensionWebRequestTest, AccessPostData) { | |
| 433 // We verify that POST data are accessible to OnBeforeRequest listeners. | |
| 434 // Construct the test data. | |
| 435 #define kBoundary "THIS_IS_A_BOUNDARY" | |
| 436 #define kMultipartBytesBlock1 "--" kBoundary "\r\n" \ | |
| 437 "Content-Disposition: form-data; name=\"text\"\r\n" \ | |
| 438 "\r\n" \ | |
| 439 "test text\r\n" \ | |
| 440 "--" kBoundary "\r\n" \ | |
| 441 "Content-Disposition: form-data; name=\"file\"; filename=\"test\"\r\n" \ | |
| 442 "Content-Type: application/octet-stream\r\n" \ | |
| 443 "\r\n" | |
| 444 #define kMultipartBytesBlock2 "\r\n" \ | |
| 445 "--" kBoundary "\r\n" \ | |
| 446 "Content-Disposition: form-data; name=\"password\"\r\n" \ | |
| 447 "\r\n" \ | |
| 448 "test password\r\n" \ | |
| 449 "--" kBoundary "\r\n" \ | |
| 450 "Content-Disposition: form-data; name=\"radio\"\r\n" \ | |
| 451 "\r\n" \ | |
| 452 "Yes\r\n" \ | |
| 453 "--" kBoundary "\r\n" \ | |
| 454 "Content-Disposition: form-data; name=\"check\"\r\n" \ | |
| 455 "\r\n" \ | |
| 456 "option A\r\n" \ | |
| 457 "--" kBoundary "\r\n" \ | |
| 458 "Content-Disposition: form-data; name=\"check\"\r\n" \ | |
| 459 "\r\n" \ | |
| 460 "option B\r\n" \ | |
| 461 "--" kBoundary "\r\n" \ | |
| 462 "Content-Disposition: form-data; name=\"txtarea\"\r\n" \ | |
| 463 "\r\n" \ | |
| 464 "Some text.\r\n" \ | |
| 465 "Other.\r\n" \ | |
| 466 "\r\n" \ | |
| 467 "--" kBoundary "\r\n" \ | |
| 468 "Content-Disposition: form-data; name=\"select\"\r\n" \ | |
| 469 "\r\n" \ | |
| 470 "one\r\n" \ | |
| 471 "--" kBoundary "--" | |
| 472 // POST data input. | |
| 473 const char kMultipartBytes[] = kMultipartBytesBlock1 kMultipartBytesBlock2; | |
| 474 const char kMultipartBytesSplit1[] = kMultipartBytesBlock1; | |
| 475 const char kMultipartBytesSplit2[] = kMultipartBytesBlock2; | |
| 476 const char kUrlEncodedBytes[] = "text=test+text&file=test-file" | |
| 477 "&password=test+password&radio=Yes&check=option+A&check=option+B" | |
| 478 "&txtarea=Some+text.%0D%0AOther.%0D%0A&select=one"; | |
| 479 const char kTextPlainBytes[] = "dummy text"; | |
| 480 // POST data output. | |
| 481 const char kResultMultipart[] = "\"check\":[\"option A\",\"option B\"]," \ | |
| 482 "\"file\":[\"test\"],\"password\":[\"test password\"]," \ | |
| 483 "\"radio\":[\"Yes\"],\"select\":[\"one\"],\"text\":[\"test text\"]," \ | |
| 484 "\"txtarea\":[\"Some text.\\r\\nOther.\\r\\n\""; | |
| 485 const char kResultUrlEncoded[] = "\"check\":[\"option+A\",\"option+B\"]," \ | |
| 486 "\"file\":[\"test-file\"],\"password\":[\"test+password\"]," \ | |
| 487 "\"radio\":[\"Yes\"],\"select\":[\"one\"],\"text\":[\"test+text\"]," \ | |
| 488 "\"txtarea\":[\"Some+text.%0D%0AOther.%0D%0A\""; | |
| 489 const char* kResults[] = | |
| 490 {kResultMultipart, kResultMultipart, kResultUrlEncoded, NULL, NULL}; | |
|
battre
2012/07/11 12:28:43
Rename this to kExpectedResults?
vabr (Chromium)
2012/07/12 15:13:11
Done.
| |
| 491 // Headers. | |
| 492 const char kUrlEncoded[] = "application/x-www-form-urlencoded"; | |
| 493 const char kTextPlain[] = "text/plain"; | |
| 494 const char kMultipart[] = "multipart/form-data; boundary=" kBoundary; | |
| 495 #undef kMultipartBytesBlock2 | |
| 496 #undef kMultipartBytesBlock1 | |
| 497 #undef kBoundary | |
| 498 | |
| 499 // Set up a dummy extension name. | |
| 500 ExtensionWebRequestEventRouter::RequestFilter filter; | |
| 501 std::string extension_id("1"); | |
| 502 int extra_info_spec_post = | |
| 503 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING | | |
| 504 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_POST_DATA; | |
| 505 int extra_info_spec_no_post = | |
| 506 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING; | |
| 507 | |
| 508 // Subscribe to OnBeforeRequest with POST data requirement. | |
| 509 const std::string kEventName(keys::kOnBeforeRequest); | |
| 510 base::WeakPtrFactory<TestIPCSender> ipc_sender_factory(&ipc_sender_); | |
| 511 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( | |
| 512 &profile_, extension_id, extension_id, kEventName, kEventName + "/1", | |
| 513 filter, extra_info_spec_post, ipc_sender_factory.GetWeakPtr()); | |
| 514 | |
| 515 // The request URL can be arbitrary but must have a HTTP or HTTPS scheme. | |
| 516 GURL request_url("http://www.example.com"); | |
| 517 | |
| 518 // First test: multipart POST data in one lump. | |
| 519 net::URLRequest request1(request_url, &delegate_, context_.get()); | |
| 520 request1.set_method("POST"); | |
| 521 request1.SetExtraRequestHeaderByName("Content-Type", kMultipart, true); | |
| 522 request1.AppendBytesToUpload(kMultipartBytes, strlen(kMultipartBytes)); | |
| 523 ipc_sender_.PushTask(base::Bind(&base::DoNothing)); | |
| 524 request1.Start(); | |
| 525 | |
| 526 // Second test: multipart POST data in several lumps. | |
| 527 net::URLRequest request2(request_url, &delegate_, context_.get()); | |
| 528 request2.set_method("POST"); | |
| 529 request2.SetExtraRequestHeaderByName("Content-Type", kMultipart, true); | |
| 530 request2.AppendBytesToUpload(kMultipartBytesSplit1, | |
| 531 strlen(kMultipartBytesSplit1)); | |
| 532 request2.AppendBytesToUpload(kMultipartBytesSplit2, | |
| 533 strlen(kMultipartBytesSplit2)); | |
| 534 ipc_sender_.PushTask(base::Bind(&base::DoNothing)); | |
| 535 request2.Start(); | |
| 536 | |
| 537 // Third test: URL-encoded POST data. | |
| 538 net::URLRequest request3(request_url, &delegate_, context_.get()); | |
| 539 request3.set_method("POST"); | |
| 540 request3.SetExtraRequestHeaderByName("Content-Type", kUrlEncoded, true); | |
| 541 request3.AppendBytesToUpload(kUrlEncodedBytes, strlen(kUrlEncodedBytes)); | |
| 542 ipc_sender_.PushTask(base::Bind(&base::DoNothing)); | |
| 543 request3.Start(); | |
| 544 | |
| 545 // Fourth test: text/plain POST data in one lump. | |
| 546 net::URLRequest request4(request_url, &delegate_, context_.get()); | |
| 547 request4.set_method("POST"); | |
| 548 request4.SetExtraRequestHeaderByName("Content-Type", kTextPlain, true); | |
| 549 request4.AppendBytesToUpload(kTextPlainBytes, strlen(kTextPlainBytes)); | |
| 550 ipc_sender_.PushTask(base::Bind(&base::DoNothing)); | |
| 551 request4.Start(); | |
| 552 | |
| 553 MessageLoop::current()->RunAllPending(); | |
| 554 | |
| 555 // Now remove the requirement of POST data. | |
| 556 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | |
| 557 &profile_, extension_id, kEventName + "/1"); | |
| 558 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( | |
| 559 &profile_, extension_id, extension_id, kEventName, kEventName + "/1", | |
| 560 filter, extra_info_spec_no_post, ipc_sender_factory.GetWeakPtr()); | |
| 561 | |
| 562 // Fifth test is the same as the first. Nobody asked for POST data, | |
| 563 // so in this case, none should be reported. | |
| 564 net::URLRequest request5(request_url, &delegate_, context_.get()); | |
| 565 request5.set_method("POST"); | |
| 566 request5.SetExtraRequestHeaderByName("Content-Type", kMultipart, true); | |
| 567 request5.AppendBytesToUpload(kMultipartBytes, strlen(kMultipartBytes)); | |
| 568 ipc_sender_.PushTask(base::Bind(&base::DoNothing)); | |
| 569 request5.Start(); | |
| 570 | |
| 571 MessageLoop::current()->RunAllPending(); | |
| 572 | |
| 573 IPC::Message* message = NULL; | |
| 574 std::string post_data; | |
| 575 TestIPCSender::SentMessages::const_iterator i = ipc_sender_.sent_begin(); | |
| 576 for (size_t test = 0; test < arraysize(kResults); ++test) { | |
| 577 EXPECT_FALSE(i == ipc_sender_.sent_end()); | |
|
battre
2012/07/11 12:28:43
does EXPECT_NE work? Otherwise, I think it is simp
vabr (Chromium)
2012/07/12 15:13:11
Done.
| |
| 578 message = (i++)->get(); | |
| 579 if (kResults[test] == NULL) { | |
| 580 EXPECT_EQ(kNoPostData, TestMessage(message, &post_data)); | |
| 581 } else { | |
| 582 EXPECT_EQ(kPostDataFound, TestMessage(message, &post_data)); | |
| 583 EXPECT_EQ(kResults[test], post_data); | |
| 584 } | |
| 585 } | |
| 586 | |
| 587 EXPECT_TRUE(i == ipc_sender_.sent_end()); | |
| 588 | |
| 589 // Clean-up. | |
| 590 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | |
| 591 &profile_, extension_id, kEventName + "/1"); | |
| 402 } | 592 } |
| 403 | 593 |
| 404 struct HeaderModificationTest_Header { | 594 struct HeaderModificationTest_Header { |
| 405 const char* name; | 595 const char* name; |
| 406 const char* value; | 596 const char* value; |
| 407 }; | 597 }; |
| 408 | 598 |
| 409 struct HeaderModificationTest_Modification { | 599 struct HeaderModificationTest_Modification { |
| 410 enum Type { | 600 enum Type { |
| 411 SET, | 601 SET, |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 656 true, | 846 true, |
| 657 ExtensionWebRequestEventRouter::ExtraInfoSpec::RESPONSE_HEADERS); | 847 ExtensionWebRequestEventRouter::ExtraInfoSpec::RESPONSE_HEADERS); |
| 658 TestInitFromValue( | 848 TestInitFromValue( |
| 659 "blocking", | 849 "blocking", |
| 660 true, | 850 true, |
| 661 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); | 851 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); |
| 662 TestInitFromValue( | 852 TestInitFromValue( |
| 663 "asyncBlocking", | 853 "asyncBlocking", |
| 664 true, | 854 true, |
| 665 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING); | 855 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING); |
| 856 TestInitFromValue( | |
| 857 "requestPostData", | |
| 858 true, | |
| 859 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_POST_DATA); | |
| 666 | 860 |
| 667 // Multiple valid values are bitwise-or'ed. | 861 // Multiple valid values are bitwise-or'ed. |
| 668 TestInitFromValue( | 862 TestInitFromValue( |
| 669 "requestHeaders,blocking", | 863 "requestHeaders,blocking", |
| 670 true, | 864 true, |
| 671 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_HEADERS | | 865 ExtensionWebRequestEventRouter::ExtraInfoSpec::REQUEST_HEADERS | |
| 672 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); | 866 ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING); |
| 673 | 867 |
| 674 // Any invalid values lead to a bad parse. | 868 // Any invalid values lead to a bad parse. |
| 675 TestInitFromValue("invalidValue", false, 0); | 869 TestInitFromValue("invalidValue", false, 0); |
| (...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1510 }; | 1704 }; |
| 1511 for (size_t i = 0; i < arraysize(sensitive_urls); ++i) { | 1705 for (size_t i = 0; i < arraysize(sensitive_urls); ++i) { |
| 1512 EXPECT_TRUE(helpers::HideRequestForURL(GURL(sensitive_urls[i]))) | 1706 EXPECT_TRUE(helpers::HideRequestForURL(GURL(sensitive_urls[i]))) |
| 1513 << sensitive_urls[i]; | 1707 << sensitive_urls[i]; |
| 1514 } | 1708 } |
| 1515 for (size_t i = 0; i < arraysize(non_sensitive_urls); ++i) { | 1709 for (size_t i = 0; i < arraysize(non_sensitive_urls); ++i) { |
| 1516 EXPECT_FALSE(helpers::HideRequestForURL(GURL(non_sensitive_urls[i]))) | 1710 EXPECT_FALSE(helpers::HideRequestForURL(GURL(non_sensitive_urls[i]))) |
| 1517 << non_sensitive_urls[i]; | 1711 << non_sensitive_urls[i]; |
| 1518 } | 1712 } |
| 1519 } | 1713 } |
| OLD | NEW |