| Index: content/browser/frame_host/navigator_impl_unittest.cc
|
| diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc
|
| index b304ba177af50b2d108ac6c548040bb738d9c5ad..cf4eb5b4c70b01180383c6ed8b27efbdeab5081e 100644
|
| --- a/content/browser/frame_host/navigator_impl_unittest.cc
|
| +++ b/content/browser/frame_host/navigator_impl_unittest.cc
|
| @@ -5,7 +5,6 @@
|
| #include "base/command_line.h"
|
| #include "base/test/histogram_tester.h"
|
| #include "base/time/time.h"
|
| -#include "content/browser/frame_host/navigation_before_commit_info.h"
|
| #include "content/browser/frame_host/navigation_controller_impl.h"
|
| #include "content/browser/frame_host/navigation_entry_impl.h"
|
| #include "content/browser/frame_host/navigation_request.h"
|
| @@ -13,21 +12,125 @@
|
| #include "content/browser/frame_host/navigator.h"
|
| #include "content/browser/frame_host/navigator_impl.h"
|
| #include "content/browser/frame_host/render_frame_host_manager.h"
|
| +#include "content/browser/loader/navigation_url_loader.h"
|
| +#include "content/browser/loader/navigation_url_loader_factory.h"
|
| #include "content/browser/site_instance_impl.h"
|
| #include "content/common/navigation_params.h"
|
| +#include "content/public/browser/stream_handle.h"
|
| #include "content/public/common/content_switches.h"
|
| #include "content/public/common/url_constants.h"
|
| #include "content/public/common/url_utils.h"
|
| #include "content/test/test_render_frame_host.h"
|
| #include "content/test/test_web_contents.h"
|
| #include "net/base/load_flags.h"
|
| +#include "net/url_request/redirect_info.h"
|
| #include "ui/base/page_transition_types.h"
|
|
|
| namespace content {
|
|
|
| +namespace {
|
| +
|
| +class TestNavigationURLLoader : public NavigationURLLoader {
|
| + public:
|
| + TestNavigationURLLoader(const CommonNavigationParams& common_params,
|
| + scoped_ptr<NavigationRequestInfo> request_info,
|
| + NavigationURLLoader::Delegate* delegate)
|
| + : common_params_(common_params),
|
| + request_info_(request_info.Pass()),
|
| + delegate_(delegate) {
|
| + }
|
| +
|
| + virtual ~TestNavigationURLLoader() {
|
| + // Record the number of times a loader was canceled before ResponseStarted
|
| + // or RequestFailed was returned.
|
| + if (delegate_)
|
| + cancel_count_++;
|
| + }
|
| +
|
| + // NavigationURLLoader implementation.
|
| + virtual void FollowRedirect() OVERRIDE {
|
| + redirect_count_++;
|
| + }
|
| +
|
| + const CommonNavigationParams& common_params() const { return common_params_; }
|
| + NavigationRequestInfo* request_info() const { return request_info_.get(); }
|
| +
|
| + void CallOnRequestRedirected(const net::RedirectInfo& redirect_info,
|
| + ResourceResponse* response) {
|
| + delegate_->OnRequestRedirected(redirect_info, response);
|
| + }
|
| +
|
| + void CallOnResponseStarted(ResourceResponse* response,
|
| + scoped_ptr<StreamHandle> body) {
|
| + delegate_->OnResponseStarted(response, body.Pass());
|
| + delegate_ = NULL;
|
| + }
|
| +
|
| + static int redirect_count() { return redirect_count_; }
|
| + static int cancel_count() { return cancel_count_; }
|
| +
|
| + private:
|
| + static int redirect_count_;
|
| + static int cancel_count_;
|
| +
|
| + CommonNavigationParams common_params_;
|
| + scoped_ptr<NavigationRequestInfo> request_info_;
|
| + NavigationURLLoader::Delegate* delegate_;
|
| +};
|
| +
|
| +int TestNavigationURLLoader::redirect_count_ = 0;
|
| +int TestNavigationURLLoader::cancel_count_ = 0;
|
| +
|
| +class TestNavigationURLLoaderFactory : public NavigationURLLoaderFactory {
|
| + public:
|
| + // NavigationURLLoaderFactory implementation.
|
| + virtual scoped_ptr<NavigationURLLoader> CreateLoader(
|
| + BrowserContext* browser_context,
|
| + int64 frame_tree_node_id,
|
| + const CommonNavigationParams& common_params,
|
| + scoped_ptr<NavigationRequestInfo> request_info,
|
| + ResourceRequestBody* request_body,
|
| + NavigationURLLoader::Delegate* delegate) OVERRIDE {
|
| + return scoped_ptr<NavigationURLLoader>(new TestNavigationURLLoader(
|
| + common_params, request_info.Pass(), delegate));
|
| + }
|
| +};
|
| +
|
| +// Mocked out stream handle to call OnResponseStarted with.
|
| +class TestStreamHandle : public StreamHandle {
|
| + public:
|
| + TestStreamHandle() : url_("test:stream") {}
|
| +
|
| + virtual const GURL& GetURL() OVERRIDE {
|
| + return url_;
|
| + }
|
| +
|
| + virtual void AddCloseListener(const base::Closure& callback) OVERRIDE {
|
| + NOTREACHED();
|
| + }
|
| + private:
|
| + GURL url_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TestStreamHandle);
|
| +};
|
| +
|
| +}
|
| +
|
| class NavigatorTest
|
| : public RenderViewHostImplTestHarness {
|
| public:
|
| + virtual void SetUp() OVERRIDE {
|
| + RenderViewHostImplTestHarness::SetUp();
|
| + loader_factory_.reset(new TestNavigationURLLoaderFactory);
|
| + NavigationURLLoader::SetFactoryForTesting(loader_factory_.get());
|
| + }
|
| +
|
| + virtual void TearDown() OVERRIDE {
|
| + NavigationURLLoader::SetFactoryForTesting(NULL);
|
| + loader_factory_.reset();
|
| + RenderViewHostImplTestHarness::TearDown();
|
| + }
|
| +
|
| NavigationRequest* GetNavigationRequestForFrameTreeNode(
|
| FrameTreeNode* frame_tree_node) const {
|
| NavigatorImpl* navigator =
|
| @@ -36,6 +139,11 @@ class NavigatorTest
|
| frame_tree_node->frame_tree_node_id());
|
| }
|
|
|
| + TestNavigationURLLoader* GetLoaderForNavigationRequest(
|
| + NavigationRequest* request) const {
|
| + return static_cast<TestNavigationURLLoader*>(request->loader_for_testing());
|
| + }
|
| +
|
| void EnableBrowserSideNavigation() {
|
| CommandLine::ForCurrentProcess()->AppendSwitch(
|
| switches::kEnableBrowserSideNavigation);
|
| @@ -66,6 +174,9 @@ class NavigatorTest
|
| static_cast<NavigatorImpl*>(node->navigator())->RequestNavigation(
|
| node, *entry, reload_type, base::TimeTicks::Now());
|
| }
|
| +
|
| + private:
|
| + scoped_ptr<TestNavigationURLLoaderFactory> loader_factory_;
|
| };
|
|
|
| // PlzNavigate: Test that a proper NavigationRequest is created by
|
| @@ -76,7 +187,6 @@ TEST_F(NavigatorTest, BrowserSideNavigationBeginNavigation) {
|
| const GURL kUrl1("http://www.google.com/");
|
| const GURL kUrl2("http://www.chromium.org/");
|
| const GURL kUrl3("http://www.gmail.com/");
|
| - const int64 kFirstNavRequestID = 1;
|
|
|
| EnableBrowserSideNavigation();
|
| contents()->NavigateAndCommit(kUrl1);
|
| @@ -88,37 +198,38 @@ TEST_F(NavigatorTest, BrowserSideNavigationBeginNavigation) {
|
|
|
| FrameTreeNode* subframe_node = subframe_rfh->frame_tree_node();
|
| SendRequestNavigation(subframe_rfh->frame_tree_node(), kUrl2);
|
| - // Simulate a BeginNavigation IPC on the subframe.
|
| - subframe_rfh->SendBeginNavigationWithURL(kUrl2);
|
| + // There is no previous renderer, so BeginNavigation is handled already.
|
| NavigationRequest* subframe_request =
|
| GetNavigationRequestForFrameTreeNode(subframe_node);
|
| + TestNavigationURLLoader* subframe_loader =
|
| + GetLoaderForNavigationRequest(subframe_request);
|
| ASSERT_TRUE(subframe_request);
|
| EXPECT_EQ(kUrl2, subframe_request->common_params().url);
|
| + EXPECT_EQ(kUrl2, subframe_loader->common_params().url);
|
| // First party for cookies url should be that of the main frame.
|
| - EXPECT_EQ(kUrl1, subframe_request->info_for_test()->first_party_for_cookies);
|
| - EXPECT_FALSE(subframe_request->info_for_test()->is_main_frame);
|
| - EXPECT_TRUE(subframe_request->info_for_test()->parent_is_main_frame);
|
| - EXPECT_EQ(kFirstNavRequestID + 1, subframe_request->navigation_request_id());
|
| + EXPECT_EQ(kUrl1, subframe_loader->request_info()->first_party_for_cookies);
|
| + EXPECT_FALSE(subframe_loader->request_info()->is_main_frame);
|
| + EXPECT_TRUE(subframe_loader->request_info()->parent_is_main_frame);
|
|
|
| FrameTreeNode* main_frame_node =
|
| contents()->GetMainFrame()->frame_tree_node();
|
| SendRequestNavigation(main_frame_node, kUrl3);
|
| - // Simulate a BeginNavigation IPC on the main frame.
|
| - contents()->GetMainFrame()->SendBeginNavigationWithURL(kUrl3);
|
| + // There is no previous renderer, so BeginNavigation is handled already.
|
| NavigationRequest* main_request =
|
| GetNavigationRequestForFrameTreeNode(main_frame_node);
|
| + TestNavigationURLLoader* main_loader =
|
| + GetLoaderForNavigationRequest(main_request);
|
| ASSERT_TRUE(main_request);
|
| EXPECT_EQ(kUrl3, main_request->common_params().url);
|
| - EXPECT_EQ(kUrl3, main_request->info_for_test()->first_party_for_cookies);
|
| - EXPECT_TRUE(main_request->info_for_test()->is_main_frame);
|
| - EXPECT_FALSE(main_request->info_for_test()->parent_is_main_frame);
|
| - EXPECT_EQ(kFirstNavRequestID + 2, main_request->navigation_request_id());
|
| + EXPECT_EQ(kUrl3, main_loader->common_params().url);
|
| + EXPECT_EQ(kUrl3, main_loader->request_info()->first_party_for_cookies);
|
| + EXPECT_TRUE(main_loader->request_info()->is_main_frame);
|
| + EXPECT_FALSE(main_loader->request_info()->parent_is_main_frame);
|
| }
|
|
|
| // PlzNavigate: Test that RequestNavigation creates a NavigationRequest and that
|
| // RenderFrameHost is not modified when the navigation commits.
|
| -TEST_F(NavigatorTest,
|
| - BrowserSideNavigationRequestNavigationNoLiveRenderer) {
|
| +TEST_F(NavigatorTest, BrowserSideNavigationRequestNavigationNoLiveRenderer) {
|
| const GURL kUrl("http://www.google.com/");
|
|
|
| EnableBrowserSideNavigation();
|
| @@ -130,11 +241,11 @@ TEST_F(NavigatorTest,
|
| EXPECT_TRUE(main_request != NULL);
|
| RenderFrameHostImpl* rfh = main_test_rfh();
|
|
|
| - // Now commit the same url.
|
| - NavigationBeforeCommitInfo commit_info;
|
| - commit_info.navigation_url = kUrl;
|
| - commit_info.navigation_request_id = main_request->navigation_request_id();
|
| - node->navigator()->CommitNavigation(node, commit_info);
|
| + // Now return the response without any redirects. This will cause the
|
| + // navigation to commit at the same URL.
|
| + scoped_refptr<ResourceResponse> response(new ResourceResponse);
|
| + GetLoaderForNavigationRequest(main_request)->CallOnResponseStarted(
|
| + response.get(), scoped_ptr<StreamHandle>(new TestStreamHandle));
|
| main_request = GetNavigationRequestForFrameTreeNode(node);
|
|
|
| // The main RFH should not have been changed, and the renderer should have
|
| @@ -146,40 +257,80 @@ TEST_F(NavigatorTest,
|
|
|
| // PlzNavigate: Test that a new RenderFrameHost is created when doing a cross
|
| // site navigation.
|
| -TEST_F(NavigatorTest,
|
| - BrowserSideNavigationCrossSiteNavigation) {
|
| +TEST_F(NavigatorTest, BrowserSideNavigationCrossSiteNavigation) {
|
| const GURL kUrl1("http://www.chromium.org/");
|
| const GURL kUrl2("http://www.google.com/");
|
|
|
| - EnableBrowserSideNavigation();
|
| contents()->NavigateAndCommit(kUrl1);
|
| RenderFrameHostImpl* rfh = main_test_rfh();
|
| EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh->rfh_state());
|
| FrameTreeNode* node = main_test_rfh()->frame_tree_node();
|
|
|
| + EnableBrowserSideNavigation();
|
| +
|
| // Navigate to a different site.
|
| SendRequestNavigation(node, kUrl2);
|
| main_test_rfh()->SendBeginNavigationWithURL(kUrl2);
|
| NavigationRequest* main_request = GetNavigationRequestForFrameTreeNode(node);
|
| ASSERT_TRUE(main_request);
|
|
|
| - NavigationBeforeCommitInfo commit_info;
|
| - commit_info.navigation_url = kUrl2;
|
| - commit_info.navigation_request_id = main_request->navigation_request_id();
|
| - node->navigator()->CommitNavigation(node, commit_info);
|
| - EXPECT_NE(main_test_rfh(), rfh);
|
| - EXPECT_TRUE(main_test_rfh()->IsRenderFrameLive());
|
| - EXPECT_TRUE(main_test_rfh()->render_view_host()->IsRenderViewLive());
|
| + scoped_refptr<ResourceResponse> response(new ResourceResponse);
|
| + GetLoaderForNavigationRequest(main_request)->CallOnResponseStarted(
|
| + response.get(), scoped_ptr<StreamHandle>(new TestStreamHandle));
|
| + RenderFrameHostImpl* pending_rfh =
|
| + node->render_manager()->pending_frame_host();
|
| + ASSERT_TRUE(pending_rfh);
|
| + EXPECT_NE(pending_rfh, rfh);
|
| + EXPECT_TRUE(pending_rfh->IsRenderFrameLive());
|
| + EXPECT_TRUE(pending_rfh->render_view_host()->IsRenderViewLive());
|
| }
|
|
|
| -// PlzNavigate: Test that a navigation commit is ignored if another request has
|
| -// been issued in the meantime.
|
| -// TODO(carlosk): add checks to assert that the cancel call was sent to
|
| -// ResourceDispatcherHost in the IO thread by extending
|
| -// ResourceDispatcherHostDelegate (like in cross_site_transfer_browsertest.cc
|
| -// and plugin_browsertest.cc).
|
| -TEST_F(NavigatorTest,
|
| - BrowserSideNavigationIgnoreStaleNavigationCommit) {
|
| +// PlzNavigate: Test that redirects are followed.
|
| +TEST_F(NavigatorTest, BrowserSideNavigationRedirectCrossSite) {
|
| + const GURL kUrl1("http://www.chromium.org/");
|
| + const GURL kUrl2("http://www.google.com/");
|
| +
|
| + contents()->NavigateAndCommit(kUrl1);
|
| + RenderFrameHostImpl* rfh = main_test_rfh();
|
| + EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh->rfh_state());
|
| + FrameTreeNode* node = main_test_rfh()->frame_tree_node();
|
| +
|
| + EnableBrowserSideNavigation();
|
| +
|
| + // Navigate to a URL on the same site.
|
| + SendRequestNavigation(node, kUrl1);
|
| + main_test_rfh()->SendBeginNavigationWithURL(kUrl1);
|
| + NavigationRequest* main_request = GetNavigationRequestForFrameTreeNode(node);
|
| + ASSERT_TRUE(main_request);
|
| +
|
| + // It then redirects to another site.
|
| + net::RedirectInfo redirect_info;
|
| + redirect_info.status_code = 302;
|
| + redirect_info.new_method = "GET";
|
| + redirect_info.new_url = kUrl2;
|
| + redirect_info.new_first_party_for_cookies = kUrl2;
|
| + scoped_refptr<ResourceResponse> response(new ResourceResponse);
|
| + GetLoaderForNavigationRequest(main_request)->CallOnRequestRedirected(
|
| + redirect_info, response.get());
|
| +
|
| + // The redirect should have been followed.
|
| + EXPECT_EQ(1, TestNavigationURLLoader::redirect_count());
|
| +
|
| + // Then it commits.
|
| + response = new ResourceResponse;
|
| + GetLoaderForNavigationRequest(main_request)->CallOnResponseStarted(
|
| + response.get(), scoped_ptr<StreamHandle>(new TestStreamHandle));
|
| + RenderFrameHostImpl* pending_rfh =
|
| + node->render_manager()->pending_frame_host();
|
| + ASSERT_TRUE(pending_rfh);
|
| + EXPECT_NE(pending_rfh, rfh);
|
| + EXPECT_TRUE(pending_rfh->IsRenderFrameLive());
|
| + EXPECT_TRUE(pending_rfh->render_view_host()->IsRenderViewLive());
|
| +}
|
| +
|
| +// PlzNavigate: Test that a navigation is cancelled if another request has been
|
| +// issued in the meantime.
|
| +TEST_F(NavigatorTest, BrowserSideNavigationReplacePendingNavigation) {
|
| const GURL kUrl0("http://www.wikipedia.org/");
|
| const GURL kUrl0_site = SiteInstance::GetSiteForURL(browser_context(), kUrl0);
|
| const GURL kUrl1("http://www.chromium.org/");
|
| @@ -197,32 +348,28 @@ TEST_F(NavigatorTest,
|
| main_test_rfh()->SendBeginNavigationWithURL(kUrl1);
|
| NavigationRequest* request1 = GetNavigationRequestForFrameTreeNode(node);
|
| ASSERT_TRUE(request1);
|
| - int64 request_id1 = request1->navigation_request_id();
|
| + int cancel_count = TestNavigationURLLoader::cancel_count();
|
|
|
| // Request navigation to the 2nd URL and gather more data.
|
| - SendRequestNavigation(node, kUrl2);
|
| + SendRequestNavigation(main_test_rfh()->frame_tree_node(), kUrl2);
|
| main_test_rfh()->SendBeginNavigationWithURL(kUrl2);
|
| NavigationRequest* request2 = GetNavigationRequestForFrameTreeNode(node);
|
| ASSERT_TRUE(request2);
|
| - int64 request_id2 = request2->navigation_request_id();
|
| - EXPECT_NE(request_id1, request_id2);
|
| -
|
| - // Confirms that a stale commit is ignored by the Navigator.
|
| - NavigationBeforeCommitInfo nbc_info;
|
| - nbc_info.navigation_url = kUrl1;
|
| - nbc_info.navigation_request_id = request_id1;
|
| - node->navigator()->CommitNavigation(node, nbc_info);
|
| - EXPECT_FALSE(node->render_manager()->pending_frame_host());
|
| - EXPECT_EQ(kUrl0_site, main_test_rfh()->GetSiteInstance()->GetSiteURL());
|
| +
|
| + // Confirm that the first request got canceled.
|
| + EXPECT_EQ(cancel_count + 1, TestNavigationURLLoader::cancel_count());
|
|
|
| // Confirms that a valid, request-matching commit is correctly processed.
|
| - nbc_info.navigation_url = kUrl2;
|
| - nbc_info.navigation_request_id = request_id2;
|
| - node->navigator()->CommitNavigation(node, nbc_info);
|
| + scoped_refptr<ResourceResponse> response(new ResourceResponse);
|
| + GetLoaderForNavigationRequest(request2)->CallOnResponseStarted(
|
| + response.get(), scoped_ptr<StreamHandle>(new TestStreamHandle));
|
| RenderFrameHostImpl* pending_rfh =
|
| node->render_manager()->pending_frame_host();
|
| ASSERT_TRUE(pending_rfh);
|
| EXPECT_EQ(kUrl2_site, pending_rfh->GetSiteInstance()->GetSiteURL());
|
| +
|
| + // The loader should not have been canceled.
|
| + EXPECT_EQ(cancel_count + 1, TestNavigationURLLoader::cancel_count());
|
| }
|
|
|
| // PlzNavigate: Tests that the navigation histograms are correctly tracked both
|
|
|