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 <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | |
| 8 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 9 #include "base/memory/scoped_vector.h" | 10 #include "base/memory/scoped_vector.h" |
| 10 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 11 #include "base/pickle.h" | 12 #include "base/pickle.h" |
| 12 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
| 13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/string_split.h" | 15 #include "base/strings/string_split.h" |
| 15 #include "content/browser/browser_thread_impl.h" | 16 #include "content/browser/browser_thread_impl.h" |
| 16 #include "content/browser/child_process_security_policy_impl.h" | 17 #include "content/browser/child_process_security_policy_impl.h" |
| 17 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 18 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
| 19 #include "content/browser/loader/resource_loader.h" | |
| 18 #include "content/browser/loader/resource_message_filter.h" | 20 #include "content/browser/loader/resource_message_filter.h" |
| 19 #include "content/browser/loader/resource_request_info_impl.h" | 21 #include "content/browser/loader/resource_request_info_impl.h" |
| 20 #include "content/browser/worker_host/worker_service_impl.h" | 22 #include "content/browser/worker_host/worker_service_impl.h" |
| 21 #include "content/common/child_process_host_impl.h" | 23 #include "content/common/child_process_host_impl.h" |
| 22 #include "content/common/resource_messages.h" | 24 #include "content/common/resource_messages.h" |
| 23 #include "content/common/view_messages.h" | 25 #include "content/common/view_messages.h" |
| 24 #include "content/public/browser/global_request_id.h" | 26 #include "content/public/browser/global_request_id.h" |
| 25 #include "content/public/browser/resource_context.h" | 27 #include "content/public/browser/resource_context.h" |
| 26 #include "content/public/browser/resource_dispatcher_host_delegate.h" | 28 #include "content/public/browser/resource_dispatcher_host_delegate.h" |
| 27 #include "content/public/browser/resource_request_info.h" | 29 #include "content/public/browser/resource_request_info.h" |
| 28 #include "content/public/browser/resource_throttle.h" | 30 #include "content/public/browser/resource_throttle.h" |
| 31 #include "content/public/common/content_switches.h" | |
| 29 #include "content/public/common/process_type.h" | 32 #include "content/public/common/process_type.h" |
| 30 #include "content/public/common/resource_response.h" | 33 #include "content/public/common/resource_response.h" |
| 31 #include "content/public/test/test_browser_context.h" | 34 #include "content/public/test/test_browser_context.h" |
| 32 #include "content/test/test_content_browser_client.h" | 35 #include "content/test/test_content_browser_client.h" |
| 33 #include "net/base/net_errors.h" | 36 #include "net/base/net_errors.h" |
| 34 #include "net/base/upload_bytes_element_reader.h" | 37 #include "net/base/upload_bytes_element_reader.h" |
| 35 #include "net/base/upload_data_stream.h" | 38 #include "net/base/upload_data_stream.h" |
| 36 #include "net/http/http_util.h" | 39 #include "net/http/http_util.h" |
| 37 #include "net/url_request/url_request.h" | 40 #include "net/url_request/url_request.h" |
| 38 #include "net/url_request/url_request_context.h" | 41 #include "net/url_request/url_request_context.h" |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 browser_context_.reset(); | 596 browser_context_.reset(); |
| 594 message_loop_.RunUntilIdle(); | 597 message_loop_.RunUntilIdle(); |
| 595 } | 598 } |
| 596 | 599 |
| 597 // Creates a request using the current test object as the filter. | 600 // Creates a request using the current test object as the filter. |
| 598 void MakeTestRequest(int render_view_id, | 601 void MakeTestRequest(int render_view_id, |
| 599 int request_id, | 602 int request_id, |
| 600 const GURL& url); | 603 const GURL& url); |
| 601 | 604 |
| 602 // Generates a request using the given filter. This will probably be a | 605 // Generates a request using the given filter. This will probably be a |
| 603 // ForwardingFilter. | 606 // ForwardingFilter. Uses the resource_type_ as the resource type. |
| 604 void MakeTestRequest(ResourceMessageFilter* filter, | 607 void MakeTestRequest(ResourceMessageFilter* filter, |
| 605 int render_view_id, | 608 int render_view_id, |
| 606 int request_id, | 609 int request_id, |
| 607 const GURL& url); | 610 const GURL& url); |
| 608 | 611 |
| 612 // Generates a request using the given filter. This will probably be a | |
| 613 // ForwardingFilter. | |
| 614 void MakeTestRequestWithResourceType(ResourceMessageFilter* filter, | |
| 615 int render_view_id, int request_id, | |
| 616 const GURL& url, | |
| 617 ResourceType::Type type); | |
| 618 | |
| 609 void CancelRequest(int request_id); | 619 void CancelRequest(int request_id); |
| 610 | 620 |
| 611 void CompleteStartRequest(int request_id); | 621 void CompleteStartRequest(int request_id); |
| 612 void CompleteStartRequest(ResourceMessageFilter* filter, int request_id); | 622 void CompleteStartRequest(ResourceMessageFilter* filter, int request_id); |
| 613 | 623 |
| 614 void EnsureSchemeIsAllowed(const std::string& scheme) { | 624 void EnsureSchemeIsAllowed(const std::string& scheme) { |
| 615 ChildProcessSecurityPolicyImpl* policy = | 625 ChildProcessSecurityPolicyImpl* policy = |
| 616 ChildProcessSecurityPolicyImpl::GetInstance(); | 626 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 617 if (!policy->IsWebSafeScheme(scheme)) | 627 if (!policy->IsWebSafeScheme(scheme)) |
| 618 policy->RegisterWebSafeScheme(scheme); | 628 policy->RegisterWebSafeScheme(scheme); |
| 619 } | 629 } |
| 620 | 630 |
| 621 void EnsureTestSchemeIsAllowed() { | 631 void EnsureTestSchemeIsAllowed() { |
| 622 EnsureSchemeIsAllowed("test"); | 632 EnsureSchemeIsAllowed("test"); |
| 623 } | 633 } |
| 624 | 634 |
| 625 // Sets a particular response for any request from now on. To switch back to | 635 // Sets a particular response for any request from now on. To switch back to |
| 626 // the default bahavior, pass an empty |headers|. |headers| should be raw- | 636 // the default bahavior, pass an empty |headers|. |headers| should be raw- |
| 627 // formatted (NULLs instead of EOLs). | 637 // formatted (NULLs instead of EOLs). |
| 628 void SetResponse(const std::string& headers, const std::string& data) { | 638 void SetResponse(const std::string& headers, const std::string& data) { |
| 629 response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(), | 639 response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(), |
| 630 headers.size()); | 640 headers.size()); |
| 631 response_data_ = data; | 641 response_data_ = data; |
| 632 } | 642 } |
| 633 void SetResponse(const std::string& headers) { | 643 void SetResponse(const std::string& headers) { |
| 634 SetResponse(headers, std::string()); | 644 SetResponse(headers, std::string()); |
| 635 } | 645 } |
| 636 | 646 |
| 637 // Sets a particular resource type for any request from now on. | |
| 638 void SetResourceType(ResourceType::Type type) { | |
| 639 resource_type_ = type; | |
| 640 } | |
| 641 | |
| 642 void SendDataReceivedACKs(bool send_acks) { | 647 void SendDataReceivedACKs(bool send_acks) { |
| 643 send_data_received_acks_ = send_acks; | 648 send_data_received_acks_ = send_acks; |
| 644 } | 649 } |
| 645 | 650 |
| 646 // Intercepts requests for the given protocol. | 651 // Intercepts requests for the given protocol. |
| 647 void HandleScheme(const std::string& scheme) { | 652 void HandleScheme(const std::string& scheme) { |
| 648 DCHECK(scheme_.empty()); | 653 DCHECK(scheme_.empty()); |
| 649 DCHECK(!old_factory_); | 654 DCHECK(!old_factory_); |
| 650 scheme_ = scheme; | 655 scheme_ = scheme; |
| 651 old_factory_ = net::URLRequest::Deprecated::RegisterProtocolFactory( | 656 old_factory_ = net::URLRequest::Deprecated::RegisterProtocolFactory( |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 742 int request_id, | 747 int request_id, |
| 743 const GURL& url) { | 748 const GURL& url) { |
| 744 MakeTestRequest(filter_.get(), render_view_id, request_id, url); | 749 MakeTestRequest(filter_.get(), render_view_id, request_id, url); |
| 745 } | 750 } |
| 746 | 751 |
| 747 void ResourceDispatcherHostTest::MakeTestRequest( | 752 void ResourceDispatcherHostTest::MakeTestRequest( |
| 748 ResourceMessageFilter* filter, | 753 ResourceMessageFilter* filter, |
| 749 int render_view_id, | 754 int render_view_id, |
| 750 int request_id, | 755 int request_id, |
| 751 const GURL& url) { | 756 const GURL& url) { |
| 757 MakeTestRequestWithResourceType(filter, render_view_id, request_id, url, | |
| 758 resource_type_); | |
| 759 } | |
| 760 | |
| 761 void ResourceDispatcherHostTest::MakeTestRequestWithResourceType( | |
| 762 ResourceMessageFilter* filter, | |
| 763 int render_view_id, | |
| 764 int request_id, | |
| 765 const GURL& url, | |
| 766 ResourceType::Type type) { | |
| 752 // If it's already there, this'll be dropped on the floor, which is fine. | 767 // If it's already there, this'll be dropped on the floor, which is fine. |
| 753 child_ids_.insert(filter->child_id()); | 768 child_ids_.insert(filter->child_id()); |
| 754 | 769 |
| 755 ResourceHostMsg_Request request = | 770 ResourceHostMsg_Request request = |
| 756 CreateResourceRequest("GET", resource_type_, url); | 771 CreateResourceRequest("GET", type, url); |
| 757 ResourceHostMsg_RequestResource msg(render_view_id, request_id, request); | 772 ResourceHostMsg_RequestResource msg(render_view_id, request_id, request); |
| 758 bool msg_was_ok; | 773 bool msg_was_ok; |
| 759 host_.OnMessageReceived(msg, filter, &msg_was_ok); | 774 host_.OnMessageReceived(msg, filter, &msg_was_ok); |
| 760 KickOffRequest(); | 775 KickOffRequest(); |
| 761 } | 776 } |
| 762 | 777 |
| 763 void ResourceDispatcherHostTest::CancelRequest(int request_id) { | 778 void ResourceDispatcherHostTest::CancelRequest(int request_id) { |
| 764 host_.CancelRequest(filter_->child_id(), request_id, false); | 779 host_.CancelRequest(filter_->child_id(), request_id, false); |
| 765 } | 780 } |
| 766 | 781 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 901 | 916 |
| 902 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); | 917 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); |
| 903 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3()); | 918 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3()); |
| 904 | 919 |
| 905 // Check that request 2 got canceled. | 920 // Check that request 2 got canceled. |
| 906 ASSERT_EQ(2U, msgs[1].size()); | 921 ASSERT_EQ(2U, msgs[1].size()); |
| 907 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type()); | 922 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type()); |
| 908 CheckCancelledRequestCompleteMessage(msgs[1][1]); | 923 CheckCancelledRequestCompleteMessage(msgs[1][1]); |
| 909 } | 924 } |
| 910 | 925 |
| 926 // Shows that unlike normal requests, prefetched async requests are not | |
| 927 // immediately canceled, and will complete within a timeout period. | |
| 928 TEST_F(ResourceDispatcherHostTest, PrefetchIgnoreCancel) { | |
| 929 CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 930 command_line->AppendSwitch(switches::kDelayPrefetchCancellation); | |
| 931 MakeTestRequestWithResourceType(filter_.get(), 0, 1, | |
| 932 net::URLRequestTestJob::test_url_1(), | |
| 933 ResourceType::PREFETCH); | |
| 934 MakeTestRequestWithResourceType(filter_.get(), 0, 2, | |
| 935 net::URLRequestTestJob::test_url_2(), | |
| 936 ResourceType::PREFETCH); | |
| 937 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); | |
| 938 | |
| 939 // test_url_1 is synchronous and already complete. | |
| 940 EXPECT_EQ(2, host_.pending_requests()); | |
| 941 // We need to make sure that the request comes from the renderer, else it | |
| 942 // won't delay. | |
| 943 host_.CancelRequest(filter_->child_id(), 2, true); | |
| 944 host_.CancelRequest(filter_->child_id(), 3, true); | |
| 945 | |
| 946 // Process any completion messages from cancelling. | |
| 947 base::MessageLoop::current()->RunUntilIdle(); | |
| 948 | |
| 949 EXPECT_EQ(1, host_.pending_requests()); | |
| 950 | |
| 951 // Run the requests to completion. | |
| 952 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
| 953 base::MessageLoop::current()->RunUntilIdle(); | |
| 954 | |
| 955 EXPECT_EQ(0, host_.pending_requests()); | |
| 956 | |
| 957 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
| 958 accum_.GetClassifiedMessages(&msgs); | |
| 959 | |
| 960 ASSERT_EQ(3U, msgs.size()); | |
| 961 | |
| 962 // The first fetch was synchronous and should have completed successfully. | |
| 963 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); | |
| 964 ASSERT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][1].type()); | |
| 965 | |
| 966 // The prefetch should have ignored the cancel and completed. Note that | |
| 967 // prefetches run detached and do not receive data notifications. | |
| 968 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type()); | |
| 969 ASSERT_EQ(ResourceMsg_RequestComplete::ID, msgs[1][1].type()); | |
| 970 // Verify that there was no error. | |
| 971 int request_id; | |
| 972 int error_code; | |
| 973 PickleIterator iter(msgs[1][1]); | |
| 974 ASSERT_TRUE(IPC::ReadParam(&msgs[1][1], &iter, &request_id)); | |
| 975 ASSERT_TRUE(IPC::ReadParam(&msgs[1][1], &iter, &error_code)); | |
| 976 EXPECT_EQ(0, error_code); | |
| 977 | |
| 978 // Request 3 should have been cancelled immediately. | |
| 979 ASSERT_EQ(2U, msgs[2].size()); | |
| 980 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[2][0].type()); | |
| 981 CheckCancelledRequestCompleteMessage(msgs[2][1]); | |
| 982 } | |
| 983 | |
| 984 // Shows that prefetched requests will timeout if the request takes too long | |
| 985 // to complete. | |
| 986 TEST_F(ResourceDispatcherHostTest, PrefetchIgnoreCancelTimesOut) { | |
| 987 CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 988 command_line->AppendSwitchASCII(switches::kDelayPrefetchCancellation, "200"); | |
| 989 | |
| 990 MakeTestRequestWithResourceType(filter_.get(), 0, 1, | |
| 991 net::URLRequestTestJob::test_url_2(), | |
| 992 ResourceType::PREFETCH); | |
| 993 host_.CancelRequest(filter_->child_id(), 1, true); | |
| 994 base::MessageLoop::current()->RunUntilIdle(); | |
| 995 EXPECT_EQ(1, host_.pending_requests()); | |
| 996 | |
| 997 // Wait until after the delay timer times before letting any Reads complete. | |
| 998 base::OneShotTimer<base::MessageLoop> timer; | |
| 999 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210), | |
| 1000 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle); | |
| 1001 | |
| 1002 // We should have cancelled the prefetch by now. | |
| 1003 base::MessageLoop::current()->Run(); | |
| 1004 EXPECT_EQ(0, host_.pending_requests()); | |
| 1005 | |
| 1006 // In case any messages are still to be processed. | |
| 1007 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | |
| 1008 base::MessageLoop::current()->RunUntilIdle(); | |
| 1009 | |
| 1010 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
| 1011 accum_.GetClassifiedMessages(&msgs); | |
| 1012 | |
| 1013 ASSERT_EQ(1U, msgs.size()); | |
| 1014 | |
| 1015 // The request should have cancelled. | |
| 1016 ASSERT_EQ(2U, msgs[0].size()); | |
| 1017 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); | |
| 1018 CheckCancelledRequestCompleteMessage(msgs[0][1]); | |
| 1019 } | |
| 1020 | |
| 911 TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) { | 1021 TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) { |
| 912 bool was_deleted = false; | 1022 bool was_deleted = false; |
| 913 | 1023 |
| 914 // Arrange to have requests deferred before starting. | 1024 // Arrange to have requests deferred before starting. |
| 915 TestResourceDispatcherHostDelegate delegate; | 1025 TestResourceDispatcherHostDelegate delegate; |
| 916 delegate.set_flags(DEFER_STARTING_REQUEST); | 1026 delegate.set_flags(DEFER_STARTING_REQUEST); |
| 917 delegate.set_url_request_user_data(new TestUserData(&was_deleted)); | 1027 delegate.set_url_request_user_data(new TestUserData(&was_deleted)); |
| 918 host_.SetDelegate(&delegate); | 1028 host_.SetDelegate(&delegate); |
| 919 | 1029 |
| 920 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); | 1030 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1537 } | 1647 } |
| 1538 | 1648 |
| 1539 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream). | 1649 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream). |
| 1540 TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) { | 1650 TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) { |
| 1541 std::string raw_headers("HTTP/1.1 403 Forbidden\n" | 1651 std::string raw_headers("HTTP/1.1 403 Forbidden\n" |
| 1542 "Content-disposition: attachment; filename=blah\n" | 1652 "Content-disposition: attachment; filename=blah\n" |
| 1543 "Content-type: application/octet-stream\n\n"); | 1653 "Content-type: application/octet-stream\n\n"); |
| 1544 std::string response_data("<html><title>Test One</title></html>"); | 1654 std::string response_data("<html><title>Test One</title></html>"); |
| 1545 SetResponse(raw_headers, response_data); | 1655 SetResponse(raw_headers, response_data); |
| 1546 | 1656 |
| 1657 HandleScheme("http"); | |
| 1658 | |
| 1547 // Only MAIN_FRAMEs can trigger a download. | 1659 // Only MAIN_FRAMEs can trigger a download. |
| 1548 SetResourceType(ResourceType::MAIN_FRAME); | 1660 MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("http:bla"), |
| 1549 | 1661 ResourceType::MAIN_FRAME); |
| 1550 HandleScheme("http"); | |
| 1551 MakeTestRequest(0, 1, GURL("http:bla")); | |
| 1552 | 1662 |
| 1553 // Flush all pending requests. | 1663 // Flush all pending requests. |
| 1554 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | 1664 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| 1555 | 1665 |
| 1556 // Sorts out all the messages we saw by request. | 1666 // Sorts out all the messages we saw by request. |
| 1557 ResourceIPCAccumulator::ClassifiedMessages msgs; | 1667 ResourceIPCAccumulator::ClassifiedMessages msgs; |
| 1558 accum_.GetClassifiedMessages(&msgs); | 1668 accum_.GetClassifiedMessages(&msgs); |
| 1559 | 1669 |
| 1560 // We should have gotten one RequestComplete message. | 1670 // We should have gotten one RequestComplete message. |
| 1561 ASSERT_EQ(1U, msgs[0].size()); | 1671 ASSERT_EQ(1U, msgs[0].size()); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1588 std::string response_data("01234567890123456789\x01foobar"); | 1698 std::string response_data("01234567890123456789\x01foobar"); |
| 1589 | 1699 |
| 1590 // Get past sniffing metrics in the BufferedResourceHandler. Note that | 1700 // Get past sniffing metrics in the BufferedResourceHandler. Note that |
| 1591 // if we don't get past the sniffing metrics, the result will be that | 1701 // if we don't get past the sniffing metrics, the result will be that |
| 1592 // the BufferedResourceHandler won't have figured out that it's a download, | 1702 // the BufferedResourceHandler won't have figured out that it's a download, |
| 1593 // won't have constructed a DownloadResourceHandler, and and the request | 1703 // won't have constructed a DownloadResourceHandler, and and the request |
| 1594 // will be successfully canceled below, failing the test. | 1704 // will be successfully canceled below, failing the test. |
| 1595 response_data.resize(1025, ' '); | 1705 response_data.resize(1025, ' '); |
| 1596 | 1706 |
| 1597 SetResponse(raw_headers, response_data); | 1707 SetResponse(raw_headers, response_data); |
| 1598 SetResourceType(ResourceType::MAIN_FRAME); | |
| 1599 SetDelayedCompleteJobGeneration(true); | 1708 SetDelayedCompleteJobGeneration(true); |
| 1600 HandleScheme("http"); | 1709 HandleScheme("http"); |
| 1601 | 1710 |
| 1602 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); | 1711 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| 1712 GURL("http://example.com/blah"), | |
| 1713 ResourceType::MAIN_FRAME); | |
| 1603 // Return some data so that the request is identified as a download | 1714 // Return some data so that the request is identified as a download |
| 1604 // and the proper resource handlers are created. | 1715 // and the proper resource handlers are created. |
| 1605 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); | 1716 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); |
| 1606 | 1717 |
| 1607 // And now simulate a cancellation coming from the renderer. | 1718 // And now simulate a cancellation coming from the renderer. |
| 1608 ResourceHostMsg_CancelRequest msg(request_id); | 1719 ResourceHostMsg_CancelRequest msg(request_id); |
| 1609 bool msg_was_ok; | 1720 bool msg_was_ok; |
| 1610 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); | 1721 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); |
| 1611 | 1722 |
| 1612 // Since the request had already started processing as a download, | 1723 // Since the request had already started processing as a download, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1623 int render_view_id = 0; | 1734 int render_view_id = 0; |
| 1624 int request_id = 1; | 1735 int request_id = 1; |
| 1625 | 1736 |
| 1626 std::string raw_headers("HTTP\n" | 1737 std::string raw_headers("HTTP\n" |
| 1627 "Content-disposition: attachment; filename=foo\n\n"); | 1738 "Content-disposition: attachment; filename=foo\n\n"); |
| 1628 std::string response_data("01234567890123456789\x01foobar"); | 1739 std::string response_data("01234567890123456789\x01foobar"); |
| 1629 // Get past sniffing metrics. | 1740 // Get past sniffing metrics. |
| 1630 response_data.resize(1025, ' '); | 1741 response_data.resize(1025, ' '); |
| 1631 | 1742 |
| 1632 SetResponse(raw_headers, response_data); | 1743 SetResponse(raw_headers, response_data); |
| 1633 SetResourceType(ResourceType::MAIN_FRAME); | |
| 1634 SetDelayedCompleteJobGeneration(true); | 1744 SetDelayedCompleteJobGeneration(true); |
| 1635 HandleScheme("http"); | 1745 HandleScheme("http"); |
| 1636 | 1746 |
| 1637 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); | 1747 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| 1748 GURL("http://example.com/blah"), | |
| 1749 ResourceType::MAIN_FRAME); | |
| 1638 // Return some data so that the request is identified as a download | 1750 // Return some data so that the request is identified as a download |
| 1639 // and the proper resource handlers are created. | 1751 // and the proper resource handlers are created. |
| 1640 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); | 1752 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); |
| 1641 | 1753 |
| 1642 // And now simulate a cancellation coming from the renderer. | 1754 // And now simulate a cancellation coming from the renderer. |
| 1643 ResourceHostMsg_CancelRequest msg(request_id); | 1755 ResourceHostMsg_CancelRequest msg(request_id); |
| 1644 bool msg_was_ok; | 1756 bool msg_was_ok; |
| 1645 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); | 1757 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); |
| 1646 | 1758 |
| 1647 // Since the request had already started processing as a download, | 1759 // Since the request had already started processing as a download, |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1664 EXPECT_EQ(0, host_.pending_requests()); | 1776 EXPECT_EQ(0, host_.pending_requests()); |
| 1665 | 1777 |
| 1666 int render_view_id = 0; | 1778 int render_view_id = 0; |
| 1667 int request_id = 1; | 1779 int request_id = 1; |
| 1668 | 1780 |
| 1669 std::string raw_headers("HTTP/1.1 200 OK\n" | 1781 std::string raw_headers("HTTP/1.1 200 OK\n" |
| 1670 "Content-Type: text/html; charset=utf-8\n\n"); | 1782 "Content-Type: text/html; charset=utf-8\n\n"); |
| 1671 std::string response_data("<html>foobar</html>"); | 1783 std::string response_data("<html>foobar</html>"); |
| 1672 | 1784 |
| 1673 SetResponse(raw_headers, response_data); | 1785 SetResponse(raw_headers, response_data); |
| 1674 SetResourceType(ResourceType::MAIN_FRAME); | |
| 1675 HandleScheme("http"); | 1786 HandleScheme("http"); |
| 1676 | 1787 |
| 1677 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); | 1788 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| 1789 GURL("http://example.com/blah"), | |
| 1790 ResourceType::MAIN_FRAME); | |
| 1791 | |
| 1678 | 1792 |
| 1679 GlobalRequestID global_request_id(filter_->child_id(), request_id); | 1793 GlobalRequestID global_request_id(filter_->child_id(), request_id); |
| 1680 host_.MarkAsTransferredNavigation(global_request_id, | 1794 host_.MarkAsTransferredNavigation(global_request_id, |
| 1681 GURL("http://example.com/blah")); | 1795 GURL("http://example.com/blah")); |
| 1682 | 1796 |
| 1683 // And now simulate a cancellation coming from the renderer. | 1797 // And now simulate a cancellation coming from the renderer. |
| 1684 ResourceHostMsg_CancelRequest msg(request_id); | 1798 ResourceHostMsg_CancelRequest msg(request_id); |
| 1685 bool msg_was_ok; | 1799 bool msg_was_ok; |
| 1686 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); | 1800 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); |
| 1687 | 1801 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1704 TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) { | 1818 TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) { |
| 1705 EXPECT_EQ(0, host_.pending_requests()); | 1819 EXPECT_EQ(0, host_.pending_requests()); |
| 1706 | 1820 |
| 1707 int render_view_id = 0; | 1821 int render_view_id = 0; |
| 1708 int request_id = 1; | 1822 int request_id = 1; |
| 1709 | 1823 |
| 1710 // Configure initial request. | 1824 // Configure initial request. |
| 1711 SetResponse("HTTP/1.1 302 Found\n" | 1825 SetResponse("HTTP/1.1 302 Found\n" |
| 1712 "Location: http://other.com/blech\n\n"); | 1826 "Location: http://other.com/blech\n\n"); |
| 1713 | 1827 |
| 1714 SetResourceType(ResourceType::MAIN_FRAME); | |
| 1715 HandleScheme("http"); | 1828 HandleScheme("http"); |
| 1716 | 1829 |
| 1717 // Temporarily replace ContentBrowserClient with one that will trigger the | 1830 // Temporarily replace ContentBrowserClient with one that will trigger the |
| 1718 // transfer navigation code paths. | 1831 // transfer navigation code paths. |
| 1719 TransfersAllNavigationsContentBrowserClient new_client; | 1832 TransfersAllNavigationsContentBrowserClient new_client; |
| 1720 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); | 1833 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); |
| 1721 | 1834 |
| 1722 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); | 1835 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| 1836 GURL("http://example.com/blah"), ResourceType::MAIN_FRAME); | |
| 1723 | 1837 |
| 1724 // Now that we're blocked on the redirect, update the response and unblock by | 1838 // Now that we're blocked on the redirect, update the response and unblock by |
| 1725 // telling the AsyncResourceHandler to follow the redirect. | 1839 // telling the AsyncResourceHandler to follow the redirect. |
| 1726 const std::string kResponseBody = "hello world"; | 1840 const std::string kResponseBody = "hello world"; |
| 1727 SetResponse("HTTP/1.1 200 OK\n" | 1841 SetResponse("HTTP/1.1 200 OK\n" |
| 1728 "Content-Type: text/html\n\n", | 1842 "Content-Type: text/html\n\n", |
| 1729 kResponseBody); | 1843 kResponseBody); |
| 1730 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); | 1844 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); |
| 1731 bool msg_was_ok; | 1845 bool msg_was_ok; |
| 1732 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok); | 1846 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1775 TEST_F(ResourceDispatcherHostTest, TransferNavigationText) { | 1889 TEST_F(ResourceDispatcherHostTest, TransferNavigationText) { |
| 1776 EXPECT_EQ(0, host_.pending_requests()); | 1890 EXPECT_EQ(0, host_.pending_requests()); |
| 1777 | 1891 |
| 1778 int render_view_id = 0; | 1892 int render_view_id = 0; |
| 1779 int request_id = 1; | 1893 int request_id = 1; |
| 1780 | 1894 |
| 1781 // Configure initial request. | 1895 // Configure initial request. |
| 1782 SetResponse("HTTP/1.1 302 Found\n" | 1896 SetResponse("HTTP/1.1 302 Found\n" |
| 1783 "Location: http://other.com/blech\n\n"); | 1897 "Location: http://other.com/blech\n\n"); |
| 1784 | 1898 |
| 1785 SetResourceType(ResourceType::MAIN_FRAME); | |
| 1786 HandleScheme("http"); | 1899 HandleScheme("http"); |
| 1787 | 1900 |
| 1788 // Temporarily replace ContentBrowserClient with one that will trigger the | 1901 // Temporarily replace ContentBrowserClient with one that will trigger the |
| 1789 // transfer navigation code paths. | 1902 // transfer navigation code paths. |
| 1790 TransfersAllNavigationsContentBrowserClient new_client; | 1903 TransfersAllNavigationsContentBrowserClient new_client; |
| 1791 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); | 1904 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); |
| 1792 | 1905 |
| 1793 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); | 1906 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| 1907 GURL("http://example.com/blah"), | |
| 1908 ResourceType::MAIN_FRAME); | |
| 1794 | 1909 |
| 1795 // Now that we're blocked on the redirect, update the response and unblock by | 1910 // Now that we're blocked on the redirect, update the response and unblock by |
| 1796 // telling the AsyncResourceHandler to follow the redirect. Use a text/plain | 1911 // telling the AsyncResourceHandler to follow the redirect. Use a text/plain |
| 1797 // MIME type, which causes BufferedResourceHandler to buffer it before the | 1912 // MIME type, which causes BufferedResourceHandler to buffer it before the |
| 1798 // transfer occurs. | 1913 // transfer occurs. |
| 1799 const std::string kResponseBody = "hello world"; | 1914 const std::string kResponseBody = "hello world"; |
| 1800 SetResponse("HTTP/1.1 200 OK\n" | 1915 SetResponse("HTTP/1.1 200 OK\n" |
| 1801 "Content-Type: text/plain\n\n", | 1916 "Content-Type: text/plain\n\n", |
| 1802 kResponseBody); | 1917 kResponseBody); |
| 1803 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); | 1918 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1847 | 1962 |
| 1848 int render_view_id = 0; | 1963 int render_view_id = 0; |
| 1849 int request_id = 1; | 1964 int request_id = 1; |
| 1850 int first_child_id = -1; | 1965 int first_child_id = -1; |
| 1851 | 1966 |
| 1852 // Configure initial request. | 1967 // Configure initial request. |
| 1853 SetResponse("HTTP/1.1 302 Found\n" | 1968 SetResponse("HTTP/1.1 302 Found\n" |
| 1854 "Location: http://other.com/blech\n\n"); | 1969 "Location: http://other.com/blech\n\n"); |
| 1855 const std::string kResponseBody = "hello world"; | 1970 const std::string kResponseBody = "hello world"; |
| 1856 | 1971 |
| 1857 SetResourceType(ResourceType::MAIN_FRAME); | |
| 1858 HandleScheme("http"); | 1972 HandleScheme("http"); |
| 1859 | 1973 |
| 1860 // Temporarily replace ContentBrowserClient with one that will trigger the | 1974 // Temporarily replace ContentBrowserClient with one that will trigger the |
| 1861 // transfer navigation code paths. | 1975 // transfer navigation code paths. |
| 1862 TransfersAllNavigationsContentBrowserClient new_client; | 1976 TransfersAllNavigationsContentBrowserClient new_client; |
| 1863 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); | 1977 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); |
| 1864 | 1978 |
| 1865 // Create a first filter that can be deleted before the second one starts. | 1979 // Create a first filter that can be deleted before the second one starts. |
| 1866 { | 1980 { |
| 1867 scoped_refptr<ForwardingFilter> first_filter = new ForwardingFilter( | 1981 scoped_refptr<ForwardingFilter> first_filter = new ForwardingFilter( |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1936 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) { | 2050 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) { |
| 1937 EXPECT_EQ(0, host_.pending_requests()); | 2051 EXPECT_EQ(0, host_.pending_requests()); |
| 1938 | 2052 |
| 1939 int render_view_id = 0; | 2053 int render_view_id = 0; |
| 1940 int request_id = 1; | 2054 int request_id = 1; |
| 1941 | 2055 |
| 1942 // Configure initial request. | 2056 // Configure initial request. |
| 1943 SetResponse("HTTP/1.1 302 Found\n" | 2057 SetResponse("HTTP/1.1 302 Found\n" |
| 1944 "Location: http://other.com/blech\n\n"); | 2058 "Location: http://other.com/blech\n\n"); |
| 1945 | 2059 |
| 1946 SetResourceType(ResourceType::MAIN_FRAME); | |
| 1947 HandleScheme("http"); | 2060 HandleScheme("http"); |
| 1948 | 2061 |
| 1949 // Temporarily replace ContentBrowserClient with one that will trigger the | 2062 // Temporarily replace ContentBrowserClient with one that will trigger the |
| 1950 // transfer navigation code paths. | 2063 // transfer navigation code paths. |
| 1951 TransfersAllNavigationsContentBrowserClient new_client; | 2064 TransfersAllNavigationsContentBrowserClient new_client; |
| 1952 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); | 2065 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); |
| 1953 | 2066 |
| 1954 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); | 2067 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| 2068 GURL("http://example.com/blah"), | |
| 2069 ResourceType::MAIN_FRAME); | |
| 1955 | 2070 |
| 1956 // Now that we're blocked on the redirect, simulate hitting another redirect. | 2071 // Now that we're blocked on the redirect, simulate hitting another redirect. |
| 1957 SetResponse("HTTP/1.1 302 Found\n" | 2072 SetResponse("HTTP/1.1 302 Found\n" |
| 1958 "Location: http://other.com/blerg\n\n"); | 2073 "Location: http://other.com/blerg\n\n"); |
| 1959 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); | 2074 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); |
| 1960 bool msg_was_ok; | 2075 bool msg_was_ok; |
| 1961 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok); | 2076 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok); |
| 1962 base::MessageLoop::current()->RunUntilIdle(); | 2077 base::MessageLoop::current()->RunUntilIdle(); |
| 1963 | 2078 |
| 1964 // Now that we're blocked on the second redirect, update the response and | 2079 // Now that we're blocked on the second redirect, update the response and |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2017 accum_.GetClassifiedMessages(&msgs); | 2132 accum_.GetClassifiedMessages(&msgs); |
| 2018 | 2133 |
| 2019 ASSERT_EQ(2U, msgs.size()); | 2134 ASSERT_EQ(2U, msgs.size()); |
| 2020 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type()); | 2135 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type()); |
| 2021 CheckSuccessfulRequest(msgs[1], kResponseBody); | 2136 CheckSuccessfulRequest(msgs[1], kResponseBody); |
| 2022 } | 2137 } |
| 2023 | 2138 |
| 2024 TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) { | 2139 TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) { |
| 2025 EXPECT_EQ(0, host_.pending_requests()); | 2140 EXPECT_EQ(0, host_.pending_requests()); |
| 2026 | 2141 |
| 2027 SetResourceType(ResourceType::MAIN_FRAME); | |
| 2028 HandleScheme("http"); | 2142 HandleScheme("http"); |
| 2029 | 2143 |
| 2030 MakeTestRequest(0, 1, GURL("foo://bar")); | 2144 MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("foo://bar"), |
| 2145 ResourceType::MAIN_FRAME); | |
| 2031 | 2146 |
| 2032 // Flush all pending requests. | 2147 // Flush all pending requests. |
| 2033 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} | 2148 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| 2034 | 2149 |
| 2035 // Sort all the messages we saw by request. | 2150 // Sort all the messages we saw by request. |
| 2036 ResourceIPCAccumulator::ClassifiedMessages msgs; | 2151 ResourceIPCAccumulator::ClassifiedMessages msgs; |
| 2037 accum_.GetClassifiedMessages(&msgs); | 2152 accum_.GetClassifiedMessages(&msgs); |
| 2038 | 2153 |
| 2039 // We should have gotten one RequestComplete message. | 2154 // We should have gotten one RequestComplete message. |
| 2040 ASSERT_EQ(1U, msgs[0].size()); | 2155 ASSERT_EQ(1U, msgs[0].size()); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2067 | 2182 |
| 2068 size_t size = msgs[0].size(); | 2183 size_t size = msgs[0].size(); |
| 2069 | 2184 |
| 2070 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); | 2185 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); |
| 2071 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type()); | 2186 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type()); |
| 2072 for (size_t i = 2; i < size - 1; ++i) | 2187 for (size_t i = 2; i < size - 1; ++i) |
| 2073 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type()); | 2188 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type()); |
| 2074 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type()); | 2189 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type()); |
| 2075 } | 2190 } |
| 2076 | 2191 |
| 2192 // Request a very large prefetch. This tests to make sure that the data | |
| 2193 // is not sent to the render process and verifies that the async handler | |
| 2194 // doesn't fill up its pending buffers and block. | |
| 2195 TEST_F(ResourceDispatcherHostTest, DetachedNoDataSentOrReceived) { | |
| 2196 EXPECT_EQ(0, host_.pending_requests()); | |
| 2197 | |
| 2198 SendDataReceivedACKs(true); | |
| 2199 | |
| 2200 HandleScheme("big-job"); | |
| 2201 | |
| 2202 // This request would normally result in many messages (>300). | |
| 2203 MakeTestRequestWithResourceType(filter_.get(), 0, 1, | |
| 2204 GURL("big-job:0123456789,1000000"), | |
| 2205 ResourceType::PREFETCH); | |
| 2206 | |
| 2207 // Sort all the messages we saw by request. | |
| 2208 ResourceIPCAccumulator::ClassifiedMessages msgs; | |
| 2209 accum_.GetClassifiedMessages(&msgs); | |
| 2210 | |
| 2211 EXPECT_EQ(size_t(2), msgs[0].size()); | |
|
mmenke
2013/10/11 16:39:07
C-style casts aren't allowed. Just use 2u here.
jkarlin2
2013/10/11 18:37:04
Done. Thanks.
| |
| 2212 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); | |
| 2213 ASSERT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][1].type()); | |
| 2214 } | |
| 2215 | |
| 2077 TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) { | 2216 TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) { |
| 2078 EXPECT_EQ(0, host_.pending_requests()); | 2217 EXPECT_EQ(0, host_.pending_requests()); |
| 2079 | 2218 |
| 2080 HandleScheme("big-job"); | 2219 HandleScheme("big-job"); |
| 2081 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000")); | 2220 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000")); |
| 2082 | 2221 |
| 2083 // Sort all the messages we saw by request. | 2222 // Sort all the messages we saw by request. |
| 2084 ResourceIPCAccumulator::ClassifiedMessages msgs; | 2223 ResourceIPCAccumulator::ClassifiedMessages msgs; |
| 2085 accum_.GetClassifiedMessages(&msgs); | 2224 accum_.GetClassifiedMessages(&msgs); |
| 2086 | 2225 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2168 } | 2307 } |
| 2169 | 2308 |
| 2170 base::MessageLoop::current()->RunUntilIdle(); | 2309 base::MessageLoop::current()->RunUntilIdle(); |
| 2171 | 2310 |
| 2172 msgs.clear(); | 2311 msgs.clear(); |
| 2173 accum_.GetClassifiedMessages(&msgs); | 2312 accum_.GetClassifiedMessages(&msgs); |
| 2174 } | 2313 } |
| 2175 } | 2314 } |
| 2176 | 2315 |
| 2177 } // namespace content | 2316 } // namespace content |
| OLD | NEW |