| 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 "content/public/browser/resource_dispatcher_host.h" | 5 #include "content/public/browser/resource_dispatcher_host.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 #include "content/public/common/url_constants.h" | 25 #include "content/public/common/url_constants.h" |
| 26 #include "content/public/test/browser_test_utils.h" | 26 #include "content/public/test/browser_test_utils.h" |
| 27 #include "content/public/test/content_browser_test.h" | 27 #include "content/public/test/content_browser_test.h" |
| 28 #include "content/public/test/content_browser_test_utils.h" | 28 #include "content/public/test/content_browser_test_utils.h" |
| 29 #include "content/public/test/test_navigation_observer.h" | 29 #include "content/public/test/test_navigation_observer.h" |
| 30 #include "content/public/test/test_utils.h" | 30 #include "content/public/test/test_utils.h" |
| 31 #include "content/shell/browser/shell.h" | 31 #include "content/shell/browser/shell.h" |
| 32 #include "content/shell/browser/shell_content_browser_client.h" | 32 #include "content/shell/browser/shell_content_browser_client.h" |
| 33 #include "content/shell/browser/shell_network_delegate.h" | 33 #include "content/shell/browser/shell_network_delegate.h" |
| 34 #include "net/base/net_errors.h" | 34 #include "net/base/net_errors.h" |
| 35 #include "net/dns/mock_host_resolver.h" |
| 35 #include "net/test/embedded_test_server/embedded_test_server.h" | 36 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 36 #include "net/test/embedded_test_server/http_request.h" | 37 #include "net/test/embedded_test_server/http_request.h" |
| 37 #include "net/test/embedded_test_server/http_response.h" | 38 #include "net/test/embedded_test_server/http_response.h" |
| 38 #include "net/test/url_request/url_request_failed_job.h" | 39 #include "net/test/url_request/url_request_failed_job.h" |
| 39 #include "net/test/url_request/url_request_mock_http_job.h" | 40 #include "net/test/url_request/url_request_mock_http_job.h" |
| 40 #include "net/url_request/url_request.h" | 41 #include "net/url_request/url_request.h" |
| 41 #include "url/gurl.h" | 42 #include "url/gurl.h" |
| 42 | 43 |
| 43 using base::ASCIIToUTF16; | 44 using base::ASCIIToUTF16; |
| 44 | 45 |
| (...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 CheckResourcesRequested(true); | 743 CheckResourcesRequested(true); |
| 743 | 744 |
| 744 // Reload with Lo-Fi disabled. | 745 // Reload with Lo-Fi disabled. |
| 745 Reset(false); | 746 Reset(false); |
| 746 TestNavigationObserver tab_observer(shell()->web_contents(), 1); | 747 TestNavigationObserver tab_observer(shell()->web_contents(), 1); |
| 747 shell()->web_contents()->GetController().ReloadDisableLoFi(true); | 748 shell()->web_contents()->GetController().ReloadDisableLoFi(true); |
| 748 tab_observer.Wait(); | 749 tab_observer.Wait(); |
| 749 CheckResourcesRequested(false); | 750 CheckResourcesRequested(false); |
| 750 } | 751 } |
| 751 | 752 |
| 753 namespace { |
| 754 |
| 755 struct RequestDataForDelegate { |
| 756 const GURL url; |
| 757 const GURL first_party; |
| 758 const url::Origin initiator; |
| 759 |
| 760 RequestDataForDelegate(const GURL& url, |
| 761 const GURL& first_party, |
| 762 const url::Origin initiator) |
| 763 : url(url), first_party(first_party), initiator(initiator) {} |
| 764 }; |
| 765 |
| 766 // Captures calls to 'RequestBeginning' and records the URL, first-party for |
| 767 // cookies, and initiator. |
| 768 class RequestDataResourceDispatcherHostDelegate |
| 769 : public ResourceDispatcherHostDelegate { |
| 770 public: |
| 771 RequestDataResourceDispatcherHostDelegate() {} |
| 772 |
| 773 const ScopedVector<RequestDataForDelegate>& data() { return requests_; } |
| 774 |
| 775 // ResourceDispatcherHostDelegate implementation: |
| 776 void RequestBeginning(net::URLRequest* request, |
| 777 ResourceContext* resource_context, |
| 778 AppCacheService* appcache_service, |
| 779 ResourceType resource_type, |
| 780 ScopedVector<ResourceThrottle>* throttles) override { |
| 781 requests_.push_back(new RequestDataForDelegate( |
| 782 request->url(), request->first_party_for_cookies(), |
| 783 request->initiator())); |
| 784 } |
| 785 |
| 786 void SetDelegate() { ResourceDispatcherHost::Get()->SetDelegate(this); } |
| 787 |
| 788 private: |
| 789 ScopedVector<RequestDataForDelegate> requests_; |
| 790 |
| 791 DISALLOW_COPY_AND_ASSIGN(RequestDataResourceDispatcherHostDelegate); |
| 792 }; |
| 793 |
| 794 const GURL kURLWithUniqueOrigin("data:,"); |
| 795 |
| 796 } // namespace |
| 797 |
| 798 class RequestDataResourceDispatcherHostBrowserTest : public ContentBrowserTest { |
| 799 public: |
| 800 ~RequestDataResourceDispatcherHostBrowserTest() override {} |
| 801 |
| 802 protected: |
| 803 void SetUpOnMainThread() override { |
| 804 ContentBrowserTest::SetUpOnMainThread(); |
| 805 |
| 806 ASSERT_TRUE(embedded_test_server()->Start()); |
| 807 |
| 808 delegate_.reset(new RequestDataResourceDispatcherHostDelegate()); |
| 809 |
| 810 content::BrowserThread::PostTask( |
| 811 content::BrowserThread::IO, FROM_HERE, |
| 812 base::Bind(&RequestDataResourceDispatcherHostDelegate::SetDelegate, |
| 813 base::Unretained(delegate_.get()))); |
| 814 } |
| 815 |
| 816 protected: |
| 817 std::unique_ptr<RequestDataResourceDispatcherHostDelegate> delegate_; |
| 818 }; |
| 819 |
| 820 IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest, Basic) { |
| 821 GURL top_url(embedded_test_server()->GetURL("/simple_page.html")); |
| 822 url::Origin top_origin(top_url); |
| 823 |
| 824 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1); |
| 825 |
| 826 EXPECT_EQ(1u, delegate_->data().size()); |
| 827 |
| 828 // User-initiated top-level navigations have a first-party and initiator that |
| 829 // matches the URL to which they navigate. |
| 830 EXPECT_EQ(top_url, delegate_->data()[0]->url); |
| 831 EXPECT_EQ(top_url, delegate_->data()[0]->first_party); |
| 832 EXPECT_EQ(top_origin, delegate_->data()[0]->initiator); |
| 833 } |
| 834 |
| 835 IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest, |
| 836 SameOriginNested) { |
| 837 GURL top_url(embedded_test_server()->GetURL("/page_with_iframe.html")); |
| 838 GURL image_url(embedded_test_server()->GetURL("/image.jpg")); |
| 839 GURL nested_url(embedded_test_server()->GetURL("/title1.html")); |
| 840 url::Origin top_origin(top_url); |
| 841 |
| 842 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1); |
| 843 |
| 844 EXPECT_EQ(3u, delegate_->data().size()); |
| 845 |
| 846 // User-initiated top-level navigations have a first-party and initiator that |
| 847 // matches the URL to which they navigate. |
| 848 EXPECT_EQ(top_url, delegate_->data()[0]->url); |
| 849 EXPECT_EQ(top_url, delegate_->data()[0]->first_party); |
| 850 EXPECT_EQ(top_origin, delegate_->data()[0]->initiator); |
| 851 |
| 852 // Subresource requests have a first-party and initiator that matches the |
| 853 // document in which they're embedded. |
| 854 EXPECT_EQ(image_url, delegate_->data()[1]->url); |
| 855 EXPECT_EQ(top_url, delegate_->data()[1]->first_party); |
| 856 EXPECT_EQ(top_origin, delegate_->data()[1]->initiator); |
| 857 |
| 858 // Same-origin nested frames have a first-party and initiator that matches |
| 859 // the document in which they're embedded. |
| 860 EXPECT_EQ(nested_url, delegate_->data()[2]->url); |
| 861 EXPECT_EQ(top_url, delegate_->data()[2]->first_party); |
| 862 EXPECT_EQ(top_origin, delegate_->data()[2]->initiator); |
| 863 } |
| 864 |
| 865 IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest, |
| 866 SameOriginAuxiliary) { |
| 867 GURL top_url(embedded_test_server()->GetURL("/simple_links.html")); |
| 868 GURL auxiliary_url(embedded_test_server()->GetURL("/title2.html")); |
| 869 url::Origin top_origin(top_url); |
| 870 |
| 871 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1); |
| 872 |
| 873 ShellAddedObserver new_shell_observer; |
| 874 bool success = false; |
| 875 EXPECT_TRUE(ExecuteScriptAndExtractBool( |
| 876 shell(), |
| 877 "window.domAutomationController.send(clickSameSiteNewWindowLink());", |
| 878 &success)); |
| 879 EXPECT_TRUE(success); |
| 880 Shell* new_shell = new_shell_observer.GetShell(); |
| 881 WaitForLoadStop(new_shell->web_contents()); |
| 882 |
| 883 EXPECT_EQ(2u, delegate_->data().size()); |
| 884 |
| 885 // User-initiated top-level navigations have a first-party and initiator that |
| 886 // matches the URL to which they navigate, even if they fail to load. |
| 887 EXPECT_EQ(top_url, delegate_->data()[0]->url); |
| 888 EXPECT_EQ(top_url, delegate_->data()[0]->first_party); |
| 889 EXPECT_EQ(top_origin, delegate_->data()[0]->initiator); |
| 890 |
| 891 // Auxiliary navigations have a first-party that matches the URL to which they |
| 892 // navigate, and an initiator that matches the document that triggered them. |
| 893 EXPECT_EQ(auxiliary_url, delegate_->data()[1]->url); |
| 894 EXPECT_EQ(auxiliary_url, delegate_->data()[1]->first_party); |
| 895 EXPECT_EQ(top_origin, delegate_->data()[1]->initiator); |
| 896 } |
| 897 |
| 898 IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest, |
| 899 CrossOriginAuxiliary) { |
| 900 GURL top_url(embedded_test_server()->GetURL("/simple_links.html")); |
| 901 GURL auxiliary_url(embedded_test_server()->GetURL("foo.com", "/title2.html")); |
| 902 url::Origin top_origin(top_url); |
| 903 |
| 904 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1); |
| 905 |
| 906 const char kReplacePortNumber[] = |
| 907 "window.domAutomationController.send(setPortNumber(%d));"; |
| 908 uint16_t port_number = embedded_test_server()->port(); |
| 909 bool success = false; |
| 910 EXPECT_TRUE(ExecuteScriptAndExtractBool( |
| 911 shell(), base::StringPrintf(kReplacePortNumber, port_number), &success)); |
| 912 success = false; |
| 913 |
| 914 ShellAddedObserver new_shell_observer; |
| 915 success = false; |
| 916 EXPECT_TRUE(ExecuteScriptAndExtractBool( |
| 917 shell(), |
| 918 "window.domAutomationController.send(clickCrossSiteNewWindowLink());", |
| 919 &success)); |
| 920 EXPECT_TRUE(success); |
| 921 Shell* new_shell = new_shell_observer.GetShell(); |
| 922 WaitForLoadStop(new_shell->web_contents()); |
| 923 |
| 924 EXPECT_EQ(2u, delegate_->data().size()); |
| 925 |
| 926 // User-initiated top-level navigations have a first-party and initiator that |
| 927 // matches the URL to which they navigate, even if they fail to load. |
| 928 EXPECT_EQ(top_url, delegate_->data()[0]->url); |
| 929 EXPECT_EQ(top_url, delegate_->data()[0]->first_party); |
| 930 EXPECT_EQ(top_origin, delegate_->data()[0]->initiator); |
| 931 |
| 932 // Auxiliary navigations have a first-party that matches the URL to which they |
| 933 // navigate, and an initiator that matches the document that triggered them. |
| 934 EXPECT_EQ(auxiliary_url, delegate_->data()[1]->url); |
| 935 EXPECT_EQ(auxiliary_url, delegate_->data()[1]->first_party); |
| 936 EXPECT_EQ(top_origin, delegate_->data()[1]->initiator); |
| 937 } |
| 938 |
| 939 IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest, |
| 940 FailedNavigation) { |
| 941 // Navigating to this URL will fail, as we haven't taught the host resolver |
| 942 // about 'a.com'. |
| 943 GURL top_url(embedded_test_server()->GetURL("a.com", "/simple_page.html")); |
| 944 url::Origin top_origin(top_url); |
| 945 |
| 946 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1); |
| 947 |
| 948 EXPECT_EQ(1u, delegate_->data().size()); |
| 949 |
| 950 // User-initiated top-level navigations have a first-party and initiator that |
| 951 // matches the URL to which they navigate, even if they fail to load. |
| 952 EXPECT_EQ(top_url, delegate_->data()[0]->url); |
| 953 EXPECT_EQ(top_url, delegate_->data()[0]->first_party); |
| 954 EXPECT_EQ(top_origin, delegate_->data()[0]->initiator); |
| 955 } |
| 956 |
| 957 IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest, |
| 958 CrossOriginNested) { |
| 959 host_resolver()->AddRule("*", "127.0.0.1"); |
| 960 GURL top_url(embedded_test_server()->GetURL( |
| 961 "a.com", "/cross_site_iframe_factory.html?a(b)")); |
| 962 GURL top_js_url( |
| 963 embedded_test_server()->GetURL("a.com", "/tree_parser_util.js")); |
| 964 GURL nested_url(embedded_test_server()->GetURL( |
| 965 "b.com", "/cross_site_iframe_factory.html?b()")); |
| 966 GURL nested_js_url( |
| 967 embedded_test_server()->GetURL("b.com", "/tree_parser_util.js")); |
| 968 url::Origin top_origin(top_url); |
| 969 url::Origin nested_origin(nested_url); |
| 970 |
| 971 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1); |
| 972 |
| 973 EXPECT_EQ(4u, delegate_->data().size()); |
| 974 |
| 975 // User-initiated top-level navigations have a first-party and initiator that |
| 976 // matches the URL to which they navigate. |
| 977 EXPECT_EQ(top_url, delegate_->data()[0]->url); |
| 978 EXPECT_EQ(top_url, delegate_->data()[0]->first_party); |
| 979 EXPECT_EQ(top_origin, delegate_->data()[0]->initiator); |
| 980 |
| 981 EXPECT_EQ(top_js_url, delegate_->data()[1]->url); |
| 982 EXPECT_EQ(top_url, delegate_->data()[1]->first_party); |
| 983 EXPECT_EQ(top_origin, delegate_->data()[1]->initiator); |
| 984 |
| 985 // Cross-origin frames have a first-party and initiator that matches the URL |
| 986 // in which they're embedded. |
| 987 EXPECT_EQ(nested_url, delegate_->data()[2]->url); |
| 988 EXPECT_EQ(top_url, delegate_->data()[2]->first_party); |
| 989 EXPECT_EQ(top_origin, delegate_->data()[2]->initiator); |
| 990 |
| 991 // Cross-origin subresource requests have a unique first-party, and an |
| 992 // initiator that matches the document in which they're embedded. |
| 993 EXPECT_EQ(nested_js_url, delegate_->data()[3]->url); |
| 994 EXPECT_EQ(kURLWithUniqueOrigin, delegate_->data()[3]->first_party); |
| 995 EXPECT_EQ(nested_origin, delegate_->data()[3]->initiator); |
| 996 } |
| 997 |
| 752 } // namespace content | 998 } // namespace content |
| OLD | NEW |