diff options
author | rohitrao <rohitrao@chromium.org> | 2014-10-22 14:07:57 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-22 21:08:28 +0000 |
commit | 74b46fe2a697d6c6a19cddad5450c5c7d6fb8f6f (patch) | |
tree | 7f60d45a4283120f75ba22baca769fd8e5277b23 /components/sessions | |
parent | 361edfd55382eccf8b4541240e3d11125ff84aea (diff) | |
download | chromium_src-74b46fe2a697d6c6a19cddad5450c5c7d6fb8f6f.zip chromium_src-74b46fe2a697d6c6a19cddad5450c5c7d6fb8f6f.tar.gz chromium_src-74b46fe2a697d6c6a19cddad5450c5c7d6fb8f6f.tar.bz2 |
Moves content-specific code out of SerializedNavigationEntry.
This CL abstracts embedder-specific logic behind a SerializedNavigationDriver
interface. It adds a content-specific Driver implementation as well as a
content-specific Builder class to convert between SerializedNavigationEntry and
content::NavigationEntry.
This CL also separates the existing unittests into multiple files, depending on
whether or not they used content classes. It also adds new tests for the
content Driver.
TBR=sky@google.com
BUG=371476
TEST=No visible impact.
Review URL: https://codereview.chromium.org/671733002
Cr-Commit-Position: refs/heads/master@{#300756}
Diffstat (limited to 'components/sessions')
14 files changed, 784 insertions, 432 deletions
diff --git a/components/sessions/BUILD.gn b/components/sessions/BUILD.gn index 79a0d4b..f2ada05 100644 --- a/components/sessions/BUILD.gn +++ b/components/sessions/BUILD.gn @@ -8,6 +8,13 @@ if (is_android) { component("sessions") { sources = [ + # TODO(rohitrao): Split this target into three separate core, content, + # and web targets. + "content/content_serialized_navigation_builder.cc", + "content/content_serialized_navigation_builder.h", + "content/content_serialized_navigation_driver.cc", + "content/content_serialized_navigation_driver.h", + "core/serialized_navigation_driver.h", "serialized_navigation_entry.cc", "serialized_navigation_entry.h", "session_id.cc", @@ -18,6 +25,7 @@ component("sessions") { deps = [ "//base", + "//base/third_party/dynamic_annotations", "//content/public/browser", "//skia", "//ui/base", diff --git a/components/sessions/content/content_serialized_navigation_builder.cc b/components/sessions/content/content_serialized_navigation_builder.cc new file mode 100644 index 0000000..a9bd244 --- /dev/null +++ b/components/sessions/content/content_serialized_navigation_builder.cc @@ -0,0 +1,106 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sessions/content/content_serialized_navigation_builder.h" + +#include "components/sessions/serialized_navigation_entry.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/favicon_status.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/common/page_state.h" +#include "content/public/common/referrer.h" + +namespace sessions { + +// static +SerializedNavigationEntry +ContentSerializedNavigationBuilder::FromNavigationEntry( + int index, + const content::NavigationEntry& entry) { + SerializedNavigationEntry navigation; + navigation.index_ = index; + navigation.unique_id_ = entry.GetUniqueID(); + navigation.referrer_url_ = entry.GetReferrer().url; + navigation.referrer_policy_ = entry.GetReferrer().policy; + navigation.virtual_url_ = entry.GetVirtualURL(); + navigation.title_ = entry.GetTitle(); + navigation.encoded_page_state_ = entry.GetPageState().ToEncodedData(); + navigation.transition_type_ = entry.GetTransitionType(); + navigation.has_post_data_ = entry.GetHasPostData(); + navigation.post_id_ = entry.GetPostID(); + navigation.original_request_url_ = entry.GetOriginalRequestURL(); + navigation.is_overriding_user_agent_ = entry.GetIsOverridingUserAgent(); + navigation.timestamp_ = entry.GetTimestamp(); + navigation.is_restored_ = entry.IsRestored(); + // If you want to navigate a named frame in Chrome, you will first need to + // add support for persisting it. It is currently only used for layout tests. + CHECK(entry.GetFrameToNavigate().empty()); + entry.GetExtraData(kSearchTermsKey, &navigation.search_terms_); + if (entry.GetFavicon().valid) + navigation.favicon_url_ = entry.GetFavicon().url; + navigation.http_status_code_ = entry.GetHttpStatusCode(); + navigation.redirect_chain_ = entry.GetRedirectChain(); + + return navigation; +} + +// static +scoped_ptr<content::NavigationEntry> +ContentSerializedNavigationBuilder::ToNavigationEntry( + const SerializedNavigationEntry* navigation, + int page_id, + content::BrowserContext* browser_context) { + blink::WebReferrerPolicy policy = + static_cast<blink::WebReferrerPolicy>(navigation->referrer_policy_); + scoped_ptr<content::NavigationEntry> entry( + content::NavigationController::CreateNavigationEntry( + navigation->virtual_url_, + content::Referrer(navigation->referrer_url_, policy), + // Use a transition type of reload so that we don't incorrectly + // increase the typed count. + ui::PAGE_TRANSITION_RELOAD, + false, + // The extra headers are not sync'ed across sessions. + std::string(), + browser_context)); + + entry->SetTitle(navigation->title_); + entry->SetPageState(content::PageState::CreateFromEncodedData( + navigation->encoded_page_state_)); + entry->SetPageID(page_id); + entry->SetHasPostData(navigation->has_post_data_); + entry->SetPostID(navigation->post_id_); + entry->SetOriginalRequestURL(navigation->original_request_url_); + entry->SetIsOverridingUserAgent(navigation->is_overriding_user_agent_); + entry->SetTimestamp(navigation->timestamp_); + entry->SetExtraData(kSearchTermsKey, navigation->search_terms_); + entry->SetHttpStatusCode(navigation->http_status_code_); + entry->SetRedirectChain(navigation->redirect_chain_); + + // These fields should have default values. + DCHECK_EQ(SerializedNavigationEntry::STATE_INVALID, + navigation->blocked_state_); + DCHECK_EQ(0u, navigation->content_pack_categories_.size()); + + return entry.Pass(); +} + +// static +ScopedVector<content::NavigationEntry> +ContentSerializedNavigationBuilder::ToNavigationEntries( + const std::vector<SerializedNavigationEntry>& navigations, + content::BrowserContext* browser_context) { + int page_id = 0; + ScopedVector<content::NavigationEntry> entries; + for (std::vector<SerializedNavigationEntry>::const_iterator + it = navigations.begin(); it != navigations.end(); ++it) { + entries.push_back( + ToNavigationEntry(&(*it), page_id, browser_context).release()); + ++page_id; + } + return entries.Pass(); +} + +} // namespace sessions diff --git a/components/sessions/content/content_serialized_navigation_builder.h b/components/sessions/content/content_serialized_navigation_builder.h new file mode 100644 index 0000000..b02117a --- /dev/null +++ b/components/sessions/content/content_serialized_navigation_builder.h @@ -0,0 +1,49 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SESSIONS_CONTENT_CONTENT_SERIALIZED_NAVIGATION_BUILDER_H_ +#define COMPONENTS_SESSIONS_CONTENT_CONTENT_SERIALIZED_NAVIGATION_BUILDER_H_ + +#include <vector> + +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" +#include "components/sessions/sessions_export.h" + +namespace content { +class BrowserContext; +class NavigationEntry; +} + +namespace sessions { +class SerializedNavigationEntry; + +// Provides methods to convert between SerializedNavigationEntry and content +// classes. +class SESSIONS_EXPORT ContentSerializedNavigationBuilder { + public: + // Construct a SerializedNavigationEntry for a particular index from the given + // NavigationEntry. + static SerializedNavigationEntry FromNavigationEntry( + int index, + const content::NavigationEntry& entry); + + // Convert the given SerializedNavigationEntry into a NavigationEntry with the + // given page ID and context. The NavigationEntry will have a transition type + // of PAGE_TRANSITION_RELOAD and a new unique ID. + static scoped_ptr<content::NavigationEntry> ToNavigationEntry( + const SerializedNavigationEntry* navigation, + int page_id, + content::BrowserContext* browser_context); + + // Converts a set of SerializedNavigationEntrys into a list of + // NavigationEntrys with sequential page IDs and the given context. + static ScopedVector<content::NavigationEntry> ToNavigationEntries( + const std::vector<SerializedNavigationEntry>& navigations, + content::BrowserContext* browser_context); +}; + +} // namespace sessions + +#endif // COMPONENTS_SESSIONS_CONTENT_CONTENT_SERIALIZED_NAVIGATION_BUILDER_H_ diff --git a/components/sessions/content/content_serialized_navigation_builder_unittest.cc b/components/sessions/content/content_serialized_navigation_builder_unittest.cc new file mode 100644 index 0000000..ee0d7c9 --- /dev/null +++ b/components/sessions/content/content_serialized_navigation_builder_unittest.cc @@ -0,0 +1,131 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sessions/content/content_serialized_navigation_builder.h" + +#include "components/sessions/serialized_navigation_entry.h" +#include "components/sessions/serialized_navigation_entry_test_helper.h" +#include "content/public/browser/favicon_status.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/common/page_state.h" +#include "content/public/common/referrer.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sessions { + +namespace { +// Create a NavigationEntry from the test_data constants in +// serialized_navigation_entry_test_helper.h. +scoped_ptr<content::NavigationEntry> MakeNavigationEntryForTest() { + scoped_ptr<content::NavigationEntry> navigation_entry( + content::NavigationEntry::Create()); + navigation_entry->SetReferrer(content::Referrer( + test_data::kReferrerURL, + static_cast<blink::WebReferrerPolicy>(test_data::kReferrerPolicy))); + navigation_entry->SetVirtualURL(test_data::kVirtualURL); + navigation_entry->SetTitle(test_data::kTitle); + navigation_entry->SetPageState( + content::PageState::CreateFromEncodedData(test_data::kEncodedPageState)); + navigation_entry->SetTransitionType(test_data::kTransitionType); + navigation_entry->SetHasPostData(test_data::kHasPostData); + navigation_entry->SetPostID(test_data::kPostID); + navigation_entry->SetOriginalRequestURL(test_data::kOriginalRequestURL); + navigation_entry->SetIsOverridingUserAgent(test_data::kIsOverridingUserAgent); + navigation_entry->SetTimestamp(test_data::kTimestamp); + navigation_entry->SetExtraData(kSearchTermsKey, + test_data::kSearchTerms); + navigation_entry->GetFavicon().valid = true; + navigation_entry->GetFavicon().url = test_data::kFaviconURL; + navigation_entry->SetHttpStatusCode(test_data::kHttpStatusCode); + std::vector<GURL> redirect_chain; + redirect_chain.push_back(test_data::kRedirectURL0); + redirect_chain.push_back(test_data::kRedirectURL1); + redirect_chain.push_back(test_data::kVirtualURL); + navigation_entry->SetRedirectChain(redirect_chain); + return navigation_entry.Pass(); +} + +} // namespace + + +// Create a SerializedNavigationEntry from a NavigationEntry. All its fields +// should match the NavigationEntry's. +TEST(ContentSerializedNavigationBuilderTest, FromNavigationEntry) { + const scoped_ptr<content::NavigationEntry> navigation_entry( + MakeNavigationEntryForTest()); + + const SerializedNavigationEntry& navigation = + ContentSerializedNavigationBuilder::FromNavigationEntry( + test_data::kIndex, *navigation_entry); + + EXPECT_EQ(test_data::kIndex, navigation.index()); + + EXPECT_EQ(navigation_entry->GetUniqueID(), navigation.unique_id()); + EXPECT_EQ(test_data::kReferrerURL, navigation.referrer_url()); + EXPECT_EQ(test_data::kReferrerPolicy, navigation.referrer_policy()); + EXPECT_EQ(test_data::kVirtualURL, navigation.virtual_url()); + EXPECT_EQ(test_data::kTitle, navigation.title()); + EXPECT_EQ(test_data::kEncodedPageState, navigation.encoded_page_state()); + EXPECT_EQ(test_data::kTransitionType, navigation.transition_type()); + EXPECT_EQ(test_data::kHasPostData, navigation.has_post_data()); + EXPECT_EQ(test_data::kPostID, navigation.post_id()); + EXPECT_EQ(test_data::kOriginalRequestURL, navigation.original_request_url()); + EXPECT_EQ(test_data::kIsOverridingUserAgent, + navigation.is_overriding_user_agent()); + EXPECT_EQ(test_data::kTimestamp, navigation.timestamp()); + EXPECT_EQ(test_data::kFaviconURL, navigation.favicon_url()); + EXPECT_EQ(test_data::kHttpStatusCode, navigation.http_status_code()); + ASSERT_EQ(3U, navigation.redirect_chain().size()); + EXPECT_EQ(test_data::kRedirectURL0, navigation.redirect_chain()[0]); + EXPECT_EQ(test_data::kRedirectURL1, navigation.redirect_chain()[1]); + EXPECT_EQ(test_data::kVirtualURL, navigation.redirect_chain()[2]); +} + +// Create a NavigationEntry, then create another one by converting to +// a SerializedNavigationEntry and back. The new one should match the old one +// except for fields that aren't preserved, which should be set to +// expected values. +TEST(ContentSerializedNavigationBuilderTest, ToNavigationEntry) { + const scoped_ptr<content::NavigationEntry> old_navigation_entry( + MakeNavigationEntryForTest()); + + const SerializedNavigationEntry& navigation = + ContentSerializedNavigationBuilder::FromNavigationEntry( + test_data::kIndex, *old_navigation_entry); + + const scoped_ptr<content::NavigationEntry> new_navigation_entry( + ContentSerializedNavigationBuilder::ToNavigationEntry( + &navigation, test_data::kPageID, NULL)); + + EXPECT_EQ(test_data::kReferrerURL, new_navigation_entry->GetReferrer().url); + EXPECT_EQ(test_data::kReferrerPolicy, + new_navigation_entry->GetReferrer().policy); + EXPECT_EQ(test_data::kVirtualURL, new_navigation_entry->GetVirtualURL()); + EXPECT_EQ(test_data::kTitle, new_navigation_entry->GetTitle()); + EXPECT_EQ(test_data::kEncodedPageState, + new_navigation_entry->GetPageState().ToEncodedData()); + EXPECT_EQ(test_data::kPageID, new_navigation_entry->GetPageID()); + EXPECT_EQ(ui::PAGE_TRANSITION_RELOAD, + new_navigation_entry->GetTransitionType()); + EXPECT_EQ(test_data::kHasPostData, new_navigation_entry->GetHasPostData()); + EXPECT_EQ(test_data::kPostID, new_navigation_entry->GetPostID()); + EXPECT_EQ(test_data::kOriginalRequestURL, + new_navigation_entry->GetOriginalRequestURL()); + EXPECT_EQ(test_data::kIsOverridingUserAgent, + new_navigation_entry->GetIsOverridingUserAgent()); + base::string16 search_terms; + new_navigation_entry->GetExtraData(kSearchTermsKey, &search_terms); + EXPECT_EQ(test_data::kSearchTerms, search_terms); + EXPECT_EQ(test_data::kHttpStatusCode, + new_navigation_entry->GetHttpStatusCode()); + ASSERT_EQ(3U, new_navigation_entry->GetRedirectChain().size()); + EXPECT_EQ(test_data::kRedirectURL0, + new_navigation_entry->GetRedirectChain()[0]); + EXPECT_EQ(test_data::kRedirectURL1, + new_navigation_entry->GetRedirectChain()[1]); + EXPECT_EQ(test_data::kVirtualURL, + new_navigation_entry->GetRedirectChain()[2]); +} + +} // namespace sessions diff --git a/components/sessions/content/content_serialized_navigation_driver.cc b/components/sessions/content/content_serialized_navigation_driver.cc new file mode 100644 index 0000000..4dd6bd0 --- /dev/null +++ b/components/sessions/content/content_serialized_navigation_driver.cc @@ -0,0 +1,71 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sessions/content/content_serialized_navigation_driver.h" + +#include "base/memory/singleton.h" +#include "components/sessions/serialized_navigation_entry.h" +#include "content/public/common/page_state.h" +#include "content/public/common/referrer.h" + +namespace sessions { + +// static +SerializedNavigationDriver* SerializedNavigationDriver::Get() { + return ContentSerializedNavigationDriver::GetInstance(); +} + +// static +ContentSerializedNavigationDriver* +ContentSerializedNavigationDriver::GetInstance() { + return Singleton<ContentSerializedNavigationDriver, + LeakySingletonTraits<ContentSerializedNavigationDriver>>::get(); +} + +ContentSerializedNavigationDriver::ContentSerializedNavigationDriver() { +} + +ContentSerializedNavigationDriver::~ContentSerializedNavigationDriver() { +} + +int ContentSerializedNavigationDriver::GetDefaultReferrerPolicy() const { + return blink::WebReferrerPolicyDefault; +} + +std::string +ContentSerializedNavigationDriver::GetSanitizedPageStateForPickle( + const SerializedNavigationEntry* navigation) const { + if (!navigation->has_post_data_) { + return navigation->encoded_page_state_; + } + content::PageState page_state = + content::PageState::CreateFromEncodedData( + navigation->encoded_page_state_); + return page_state.RemovePasswordData().ToEncodedData(); +} + +void ContentSerializedNavigationDriver::Sanitize( + SerializedNavigationEntry* navigation) const { + content::Referrer old_referrer( + navigation->referrer_url_, + static_cast<blink::WebReferrerPolicy>(navigation->referrer_policy_)); + content::Referrer new_referrer = + content::Referrer::SanitizeForRequest(navigation->virtual_url_, + old_referrer); + + // No need to compare the policy, as it doesn't change during + // sanitization. If there has been a change, the referrer needs to be + // stripped from the page state as well. + if (navigation->referrer_url_ != new_referrer.url) { + navigation->referrer_url_ = GURL(); + navigation->referrer_policy_ = GetDefaultReferrerPolicy(); + navigation->encoded_page_state_ = + content::PageState::CreateFromEncodedData( + navigation->encoded_page_state_) + .RemoveReferrer() + .ToEncodedData(); + } +} + +} // namespace sessions diff --git a/components/sessions/content/content_serialized_navigation_driver.h b/components/sessions/content/content_serialized_navigation_driver.h new file mode 100644 index 0000000..499d258 --- /dev/null +++ b/components/sessions/content/content_serialized_navigation_driver.h @@ -0,0 +1,40 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SESSIONS_CONTENT_CONTENT_SERIALIZED_NAVIGATION_DRIVER_H_ +#define COMPONENTS_SESSIONS_CONTENT_CONTENT_SERIALIZED_NAVIGATION_DRIVER_H_ + +#include "components/sessions/core/serialized_navigation_driver.h" + +#include "components/sessions/sessions_export.h" + +template <typename T> struct DefaultSingletonTraits; + +namespace sessions { + +// Provides an implementation of SerializedNavigationDriver that is backed by +// content classes. +class SESSIONS_EXPORT_PRIVATE ContentSerializedNavigationDriver + : public SerializedNavigationDriver { + public: + virtual ~ContentSerializedNavigationDriver(); + + // Returns the singleton ContentSerializedNavigationDriver. Almost all + // callers should use SerializedNavigationDriver::Get() instead. + static ContentSerializedNavigationDriver* GetInstance(); + + // SerializedNavigationDriver implementation. + virtual int GetDefaultReferrerPolicy() const override; + virtual std::string GetSanitizedPageStateForPickle( + const SerializedNavigationEntry* navigation) const override; + virtual void Sanitize(SerializedNavigationEntry* navigation) const override; + + private: + ContentSerializedNavigationDriver(); + friend struct DefaultSingletonTraits<ContentSerializedNavigationDriver>; +}; + +} // namespace sessions + +#endif // COMPONENTS_SESSIONS_CONTENT_CONTENT_SERIALIZED_NAVIGATION_DRIVER_H_ diff --git a/components/sessions/content/content_serialized_navigation_driver_unittest.cc b/components/sessions/content/content_serialized_navigation_driver_unittest.cc new file mode 100644 index 0000000..9a3525c --- /dev/null +++ b/components/sessions/content/content_serialized_navigation_driver_unittest.cc @@ -0,0 +1,117 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sessions/content/content_serialized_navigation_driver.h" + +#include "components/sessions/serialized_navigation_entry.h" +#include "components/sessions/serialized_navigation_entry_test_helper.h" +#include "content/public/common/page_state.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/WebReferrerPolicy.h" + +namespace sessions { + +// Tests that PageState data is properly sanitized when post data is present. +TEST(ContentSerializedNavigationDriverTest, PickleSanitizationWithPostData) { + ContentSerializedNavigationDriver* driver = + ContentSerializedNavigationDriver::GetInstance(); + SerializedNavigationEntry navigation = + SerializedNavigationEntryTestHelper::CreateNavigationForTest(); + ASSERT_TRUE(navigation.has_post_data()); + + // When post data is present, the page state should be sanitized. + std::string sanitized_page_state = + driver->GetSanitizedPageStateForPickle(&navigation); + EXPECT_EQ(std::string(), sanitized_page_state); +} + +// Tests that PageState data is left unsanitized when post data is absent. +TEST(ContentSerializedNavigationDriverTest, PickleSanitizationNoPostData) { + ContentSerializedNavigationDriver* driver = + ContentSerializedNavigationDriver::GetInstance(); + SerializedNavigationEntry navigation = + SerializedNavigationEntryTestHelper::CreateNavigationForTest(); + SerializedNavigationEntryTestHelper::SetHasPostData(false, &navigation); + ASSERT_FALSE(navigation.has_post_data()); + + std::string sanitized_page_state = + driver->GetSanitizedPageStateForPickle(&navigation); + EXPECT_EQ(test_data::kEncodedPageState, sanitized_page_state); +} + +// Tests that the input data is left unsanitized when the referrer policy is +// Always. +TEST(ContentSerializedNavigationDriverTest, SanitizeWithReferrerPolicyAlways) { + ContentSerializedNavigationDriver* driver = + ContentSerializedNavigationDriver::GetInstance(); + SerializedNavigationEntry navigation = + SerializedNavigationEntryTestHelper::CreateNavigationForTest(); + SerializedNavigationEntryTestHelper::SetReferrerPolicy( + blink::WebReferrerPolicyAlways, &navigation); + + content::PageState page_state = + content::PageState::CreateFromURL(test_data::kVirtualURL); + SerializedNavigationEntryTestHelper::SetEncodedPageState( + page_state.ToEncodedData(), &navigation); + + driver->Sanitize(&navigation); + EXPECT_EQ(test_data::kIndex, navigation.index()); + EXPECT_EQ(test_data::kUniqueID, navigation.unique_id()); + EXPECT_EQ(test_data::kReferrerURL, navigation.referrer_url()); + EXPECT_EQ(blink::WebReferrerPolicyAlways, navigation.referrer_policy()); + EXPECT_EQ(test_data::kVirtualURL, navigation.virtual_url()); + EXPECT_EQ(test_data::kTitle, navigation.title()); + EXPECT_EQ(page_state.ToEncodedData(), navigation.encoded_page_state()); + EXPECT_EQ(test_data::kTransitionType, navigation.transition_type()); + EXPECT_EQ(test_data::kHasPostData, navigation.has_post_data()); + EXPECT_EQ(test_data::kPostID, navigation.post_id()); + EXPECT_EQ(test_data::kOriginalRequestURL, navigation.original_request_url()); + EXPECT_EQ(test_data::kIsOverridingUserAgent, + navigation.is_overriding_user_agent()); + EXPECT_EQ(test_data::kTimestamp, navigation.timestamp()); + EXPECT_EQ(test_data::kSearchTerms, navigation.search_terms()); + EXPECT_EQ(test_data::kFaviconURL, navigation.favicon_url()); + EXPECT_EQ(test_data::kHttpStatusCode, navigation.http_status_code()); +} + +// Tests that the input data is properly sanitized when the referrer policy is +// Never. +TEST(ContentSerializedNavigationDriverTest, SanitizeWithReferrerPolicyNever) { + ContentSerializedNavigationDriver* driver = + ContentSerializedNavigationDriver::GetInstance(); + SerializedNavigationEntry navigation = + SerializedNavigationEntryTestHelper::CreateNavigationForTest(); + SerializedNavigationEntryTestHelper::SetReferrerPolicy( + blink::WebReferrerPolicyNever, &navigation); + + content::PageState page_state = + content::PageState::CreateFromURL(test_data::kVirtualURL); + SerializedNavigationEntryTestHelper::SetEncodedPageState( + page_state.ToEncodedData(), &navigation); + + driver->Sanitize(&navigation); + + // Fields that should remain untouched. + EXPECT_EQ(test_data::kIndex, navigation.index()); + EXPECT_EQ(test_data::kUniqueID, navigation.unique_id()); + EXPECT_EQ(test_data::kVirtualURL, navigation.virtual_url()); + EXPECT_EQ(test_data::kTitle, navigation.title()); + EXPECT_EQ(test_data::kTransitionType, navigation.transition_type()); + EXPECT_EQ(test_data::kHasPostData, navigation.has_post_data()); + EXPECT_EQ(test_data::kPostID, navigation.post_id()); + EXPECT_EQ(test_data::kOriginalRequestURL, navigation.original_request_url()); + EXPECT_EQ(test_data::kIsOverridingUserAgent, + navigation.is_overriding_user_agent()); + EXPECT_EQ(test_data::kTimestamp, navigation.timestamp()); + EXPECT_EQ(test_data::kSearchTerms, navigation.search_terms()); + EXPECT_EQ(test_data::kFaviconURL, navigation.favicon_url()); + EXPECT_EQ(test_data::kHttpStatusCode, navigation.http_status_code()); + + // Fields that were sanitized. + EXPECT_EQ(GURL(), navigation.referrer_url()); + EXPECT_EQ(blink::WebReferrerPolicyDefault, navigation.referrer_policy()); + EXPECT_EQ(page_state.ToEncodedData(), navigation.encoded_page_state()); +} + +} // namespace sessions diff --git a/components/sessions/core/serialized_navigation_driver.h b/components/sessions/core/serialized_navigation_driver.h new file mode 100644 index 0000000..fafaa27 --- /dev/null +++ b/components/sessions/core/serialized_navigation_driver.h @@ -0,0 +1,40 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SESSIONS_CORE_SERIALIZED_NAVIGATION_DRIVER_H_ +#define COMPONENTS_SESSIONS_CORE_SERIALIZED_NAVIGATION_DRIVER_H_ + +#include <string> + +#include "components/sessions/sessions_export.h" + +namespace sessions { +class SerializedNavigationEntry; + +// The SerializedNavigationDriver interface allows SerializedNavigationEntry to +// obtain information from a singleton driver object. A concrete implementation +// must be provided by the driver on each platform. +class SESSIONS_EXPORT_PRIVATE SerializedNavigationDriver { + public: + virtual ~SerializedNavigationDriver() {} + + // Returns the singleton SerializedNavigationDriver. + static SerializedNavigationDriver* Get(); + + // Returns the default referrer policy. + virtual int GetDefaultReferrerPolicy() const = 0; + + // Returns a sanitized version of the given |navigation|'s encoded_page_state + // suitable for writing to disk. + virtual std::string GetSanitizedPageStateForPickle( + const SerializedNavigationEntry* navigation) const = 0; + + // Sanitizes the data in the given |navigation| to be more robust against + // faulty data written by older versions. + virtual void Sanitize(SerializedNavigationEntry* navigation) const = 0; +}; + +} // namespace sessions + +#endif // COMPONENTS_SESSIONS_CORE_SERIALIZED_NAVIGATION_DRIVER_H_ diff --git a/components/sessions/serialized_navigation_entry.cc b/components/sessions/serialized_navigation_entry.cc index facd7e4..5135223 100644 --- a/components/sessions/serialized_navigation_entry.cc +++ b/components/sessions/serialized_navigation_entry.cc @@ -6,17 +6,11 @@ #include "base/pickle.h" #include "base/strings/utf_string_conversions.h" -#include "content/public/browser/favicon_status.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/common/page_state.h" -#include "content/public/common/referrer.h" +#include "components/sessions/core/serialized_navigation_driver.h" #include "sync/protocol/session_specifics.pb.h" #include "sync/util/time.h" #include "third_party/WebKit/public/platform/WebReferrerPolicy.h" -using content::NavigationEntry; - namespace sessions { const char kSearchTermsKey[] = "search_terms"; @@ -31,42 +25,12 @@ SerializedNavigationEntry::SerializedNavigationEntry() http_status_code_(0), is_restored_(false), blocked_state_(STATE_INVALID) { - referrer_policy_ = GetDefaultReferrerPolicy(); + referrer_policy_ = + SerializedNavigationDriver::Get()->GetDefaultReferrerPolicy(); } SerializedNavigationEntry::~SerializedNavigationEntry() {} -// static -SerializedNavigationEntry SerializedNavigationEntry::FromNavigationEntry( - int index, - const NavigationEntry& entry) { - SerializedNavigationEntry navigation; - navigation.index_ = index; - navigation.unique_id_ = entry.GetUniqueID(); - navigation.referrer_url_ = entry.GetReferrer().url; - navigation.referrer_policy_ = entry.GetReferrer().policy; - navigation.virtual_url_ = entry.GetVirtualURL(); - navigation.title_ = entry.GetTitle(); - navigation.encoded_page_state_ = entry.GetPageState().ToEncodedData(); - navigation.transition_type_ = entry.GetTransitionType(); - navigation.has_post_data_ = entry.GetHasPostData(); - navigation.post_id_ = entry.GetPostID(); - navigation.original_request_url_ = entry.GetOriginalRequestURL(); - navigation.is_overriding_user_agent_ = entry.GetIsOverridingUserAgent(); - navigation.timestamp_ = entry.GetTimestamp(); - navigation.is_restored_ = entry.IsRestored(); - // If you want to navigate a named frame in Chrome, you will first need to - // add support for persisting it. It is currently only used for layout tests. - CHECK(entry.GetFrameToNavigate().empty()); - entry.GetExtraData(kSearchTermsKey, &navigation.search_terms_); - if (entry.GetFavicon().valid) - navigation.favicon_url_ = entry.GetFavicon().url; - navigation.http_status_code_ = entry.GetHttpStatusCode(); - navigation.redirect_chain_ = entry.GetRedirectChain(); - - return navigation; -} - SerializedNavigationEntry SerializedNavigationEntry::FromSyncData( int index, const sync_pb::TabNavigation& sync_data) { @@ -151,7 +115,7 @@ SerializedNavigationEntry SerializedNavigationEntry::FromSyncData( navigation.http_status_code_ = sync_data.http_status_code(); - navigation.Sanitize(); + SerializedNavigationDriver::Get()->Sanitize(&navigation); navigation.is_restored_ = true; @@ -238,7 +202,8 @@ void SerializedNavigationEntry::WriteToPickle(int max_size, WriteString16ToPickle(pickle, &bytes_written, max_size, title_); - const std::string encoded_page_state = GetSanitizedPageStateForPickle(); + const std::string encoded_page_state = + SerializedNavigationDriver::Get()->GetSanitizedPageStateForPickle(this); WriteStringToPickle(pickle, &bytes_written, max_size, encoded_page_state); pickle->WriteInt(transition_type_); @@ -295,7 +260,8 @@ bool SerializedNavigationEntry::ReadFromPickle(PickleIterator* iterator) { // The "referrer policy" property was added even later, so we fall back to // the default policy if the property is not present. if (!iterator->ReadInt(&referrer_policy_)) - referrer_policy_ = GetDefaultReferrerPolicy(); + referrer_policy_ = + SerializedNavigationDriver::Get()->GetDefaultReferrerPolicy(); // If the original URL can't be found, leave it empty. std::string original_request_url_spec; @@ -322,50 +288,13 @@ bool SerializedNavigationEntry::ReadFromPickle(PickleIterator* iterator) { http_status_code_ = 0; } - Sanitize(); + SerializedNavigationDriver::Get()->Sanitize(this); is_restored_ = true; return true; } -scoped_ptr<NavigationEntry> SerializedNavigationEntry::ToNavigationEntry( - int page_id, - content::BrowserContext* browser_context) const { - scoped_ptr<NavigationEntry> entry( - content::NavigationController::CreateNavigationEntry( - virtual_url_, - content::Referrer( - referrer_url_, - static_cast<blink::WebReferrerPolicy>(referrer_policy_)), - // Use a transition type of reload so that we don't incorrectly - // increase the typed count. - ui::PAGE_TRANSITION_RELOAD, - false, - // The extra headers are not sync'ed across sessions. - std::string(), - browser_context)); - - entry->SetTitle(title_); - entry->SetPageState( - content::PageState::CreateFromEncodedData(encoded_page_state_)); - entry->SetPageID(page_id); - entry->SetHasPostData(has_post_data_); - entry->SetPostID(post_id_); - entry->SetOriginalRequestURL(original_request_url_); - entry->SetIsOverridingUserAgent(is_overriding_user_agent_); - entry->SetTimestamp(timestamp_); - entry->SetExtraData(kSearchTermsKey, search_terms_); - entry->SetHttpStatusCode(http_status_code_); - entry->SetRedirectChain(redirect_chain_); - - // These fields should have default values. - DCHECK_EQ(STATE_INVALID, blocked_state_); - DCHECK_EQ(0u, content_pack_categories_.size()); - - return entry.Pass(); -} - // TODO(zea): perhaps sync state (scroll position, form entries, etc.) as well? // See http://crbug.com/67068. sync_pb::TabNavigation SerializedNavigationEntry::ToSyncData() const { @@ -493,58 +422,4 @@ sync_pb::TabNavigation SerializedNavigationEntry::ToSyncData() const { return sync_data; } -// static -std::vector<NavigationEntry*> SerializedNavigationEntry::ToNavigationEntries( - const std::vector<SerializedNavigationEntry>& navigations, - content::BrowserContext* browser_context) { - int page_id = 0; - std::vector<NavigationEntry*> entries; - for (std::vector<SerializedNavigationEntry>::const_iterator - it = navigations.begin(); it != navigations.end(); ++it) { - entries.push_back( - it->ToNavigationEntry(page_id, browser_context).release()); - ++page_id; - } - return entries; -} - -// TODO(rohitrao): Move this content-specific code into a -// SerializedNavigationEntryHelper class. -int SerializedNavigationEntry::GetDefaultReferrerPolicy() const { - return blink::WebReferrerPolicyDefault; -} - -// TODO(rohitrao): Move this content-specific code into a -// SerializedNavigationEntryHelper class. -std::string SerializedNavigationEntry::GetSanitizedPageStateForPickle() const { - content::PageState page_state = - content::PageState::CreateFromEncodedData(encoded_page_state_); - if (has_post_data_) - page_state = page_state.RemovePasswordData(); - - return page_state.ToEncodedData(); -} - -// TODO(rohitrao): Move this content-specific code into a -// SerializedNavigationEntryHelper class. -void SerializedNavigationEntry::Sanitize() { - content::Referrer old_referrer( - referrer_url_, - static_cast<blink::WebReferrerPolicy>(referrer_policy_)); - content::Referrer new_referrer = - content::Referrer::SanitizeForRequest(virtual_url_, old_referrer); - - // No need to compare the policy, as it doesn't change during - // sanitization. If there has been a change, the referrer needs to be - // stripped from the page state as well. - if (referrer_url_ != new_referrer.url) { - referrer_url_ = GURL(); - referrer_policy_ = GetDefaultReferrerPolicy(); - encoded_page_state_ = - content::PageState::CreateFromEncodedData(encoded_page_state_) - .RemoveReferrer() - .ToEncodedData(); - } -} - } // namespace sessions diff --git a/components/sessions/serialized_navigation_entry.h b/components/sessions/serialized_navigation_entry.h index bbc3d7a..7db46c0 100644 --- a/components/sessions/serialized_navigation_entry.h +++ b/components/sessions/serialized_navigation_entry.h @@ -20,11 +20,6 @@ class Pickle; class PickleIterator; -namespace content { -class BrowserContext; -class NavigationEntry; -} - namespace sync_pb { class TabNavigation; } @@ -54,12 +49,6 @@ class SESSIONS_EXPORT SerializedNavigationEntry { SerializedNavigationEntry(); ~SerializedNavigationEntry(); - // Construct a SerializedNavigationEntry for a particular index from the given - // NavigationEntry. - static SerializedNavigationEntry FromNavigationEntry( - int index, - const content::NavigationEntry& entry); - // Construct a SerializedNavigationEntry for a particular index from a sync // protocol buffer. Note that the sync protocol buffer doesn't contain all // SerializedNavigationEntry fields. Also, the timestamp of the returned @@ -74,13 +63,6 @@ class SESSIONS_EXPORT SerializedNavigationEntry { void WriteToPickle(int max_size, Pickle* pickle) const; bool ReadFromPickle(PickleIterator* iterator); - // Convert this SerializedNavigationEntry into a NavigationEntry with the - // given page ID and context. The NavigationEntry will have a transition type - // of PAGE_TRANSITION_RELOAD and a new unique ID. - scoped_ptr<content::NavigationEntry> ToNavigationEntry( - int page_id, - content::BrowserContext* browser_context) const; - // Convert this navigation into its sync protocol buffer equivalent. Note // that the protocol buffer doesn't contain all SerializedNavigationEntry // fields. @@ -123,27 +105,11 @@ class SESSIONS_EXPORT SerializedNavigationEntry { } const std::vector<GURL>& redirect_chain() const { return redirect_chain_; } - // Converts a set of SerializedNavigationEntrys into a list of - // NavigationEntrys with sequential page IDs and the given context. The caller - // owns the returned NavigationEntrys. - static std::vector<content::NavigationEntry*> ToNavigationEntries( - const std::vector<SerializedNavigationEntry>& navigations, - content::BrowserContext* browser_context); - private: + friend class ContentSerializedNavigationBuilder; + friend class ContentSerializedNavigationDriver; friend class SerializedNavigationEntryTestHelper; - // Returns the default referrer policy. - int GetDefaultReferrerPolicy() const; - - // Returns a sanitized version of |encoded_page_state_| suitable for writing - // to disk. - std::string GetSanitizedPageStateForPickle() const; - - // Sanitizes the data in this class to be more robust against faulty data - // written by older versions. - void Sanitize(); - // Index in the NavigationController. int index_; diff --git a/components/sessions/serialized_navigation_entry_test_helper.cc b/components/sessions/serialized_navigation_entry_test_helper.cc index 030db0b..708346b 100644 --- a/components/sessions/serialized_navigation_entry_test_helper.cc +++ b/components/sessions/serialized_navigation_entry_test_helper.cc @@ -7,13 +7,41 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "components/sessions/serialized_navigation_entry.h" -#include "content/public/common/page_state.h" +#include "sync/util/time.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/platform/WebReferrerPolicy.h" #include "url/gurl.h" namespace sessions { +namespace test_data { + +const int kIndex = 3; +const int kUniqueID = 50; +const GURL kReferrerURL = GURL("http://www.referrer.com"); +const int kReferrerPolicy = 0; +const GURL kVirtualURL= GURL("http://www.virtual-url.com"); +const base::string16 kTitle = base::ASCIIToUTF16("title"); +const std::string kEncodedPageState = "page state"; +const ui::PageTransition kTransitionType = + ui::PageTransitionFromInt( + ui::PAGE_TRANSITION_AUTO_SUBFRAME | + ui::PAGE_TRANSITION_HOME_PAGE | + ui::PAGE_TRANSITION_CLIENT_REDIRECT); +const bool kHasPostData = true; +const int64 kPostID = 100; +const GURL kOriginalRequestURL = GURL("http://www.original-request.com"); +const bool kIsOverridingUserAgent = true; +const base::Time kTimestamp = syncer::ProtoTimeToTime(100); +const base::string16 kSearchTerms = base::ASCIIToUTF16("my search terms"); +const GURL kFaviconURL = GURL("http://virtual-url.com/favicon.ico"); +const int kHttpStatusCode = 404; +const GURL kRedirectURL0 = GURL("http://go/redirect0"); +const GURL kRedirectURL1 = GURL("http://go/redirect1"); +const GURL kOtherURL = GURL("http://other.com"); +const int kPageID = 10; + +} // namespace test_data + // static void SerializedNavigationEntryTestHelper::ExpectNavigationEquals( const SerializedNavigationEntry& expected, @@ -37,7 +65,6 @@ SerializedNavigationEntry SerializedNavigationEntryTestHelper::CreateNavigation( SerializedNavigationEntry navigation; navigation.index_ = 0; navigation.referrer_url_ = GURL("http://www.referrer.com"); - navigation.referrer_policy_ = blink::WebReferrerPolicyDefault; navigation.virtual_url_ = GURL(virtual_url); navigation.title_ = base::UTF8ToUTF16(title); navigation.encoded_page_state_ = "fake state"; @@ -47,10 +74,58 @@ SerializedNavigationEntry SerializedNavigationEntryTestHelper::CreateNavigation( } // static -void SerializedNavigationEntryTestHelper::SetPageState( - const content::PageState& page_state, +SerializedNavigationEntry +SerializedNavigationEntryTestHelper::CreateNavigationForTest() { + SerializedNavigationEntry navigation; + navigation.index_ = test_data::kIndex; + navigation.unique_id_ = test_data::kUniqueID; + navigation.referrer_url_ = test_data::kReferrerURL; + navigation.referrer_policy_ = test_data::kReferrerPolicy; + navigation.virtual_url_ = test_data::kVirtualURL; + navigation.title_ = test_data::kTitle; + navigation.encoded_page_state_ = test_data::kEncodedPageState; + navigation.transition_type_ = test_data::kTransitionType; + navigation.has_post_data_ = test_data::kHasPostData; + navigation.post_id_ = test_data::kPostID; + navigation.original_request_url_ = test_data::kOriginalRequestURL; + navigation.is_overriding_user_agent_ = test_data::kIsOverridingUserAgent; + navigation.timestamp_ = test_data::kTimestamp; + navigation.search_terms_ = test_data::kSearchTerms; + navigation.favicon_url_ = test_data::kFaviconURL; + navigation.http_status_code_ = test_data::kHttpStatusCode; + + navigation.redirect_chain_.push_back(test_data::kRedirectURL0); + navigation.redirect_chain_.push_back(test_data::kRedirectURL1); + navigation.redirect_chain_.push_back(test_data::kVirtualURL); + return navigation; +} + +// static +void SerializedNavigationEntryTestHelper::SetReferrerPolicy( + int policy, + SerializedNavigationEntry* navigation) { + navigation->referrer_policy_ = policy; +} + +// static +void SerializedNavigationEntryTestHelper::SetVirtualURL( + const GURL& virtual_url, + SerializedNavigationEntry* navigation) { + navigation->virtual_url_ = virtual_url; +} + +// static +void SerializedNavigationEntryTestHelper::SetEncodedPageState( + const std::string& encoded_page_state, + SerializedNavigationEntry* navigation) { + navigation->encoded_page_state_ = encoded_page_state; +} + +// static +void SerializedNavigationEntryTestHelper::SetTransitionType( + ui::PageTransition transition_type, SerializedNavigationEntry* navigation) { - navigation->encoded_page_state_ = page_state.ToEncodedData(); + navigation->transition_type_ = transition_type; } // static diff --git a/components/sessions/serialized_navigation_entry_test_helper.h b/components/sessions/serialized_navigation_entry_test_helper.h index 1044b0c..54f070f 100644 --- a/components/sessions/serialized_navigation_entry_test_helper.h +++ b/components/sessions/serialized_navigation_entry_test_helper.h @@ -8,6 +8,9 @@ #include <string> #include "base/basictypes.h" +#include "base/strings/string16.h" +#include "base/time/time.h" +#include "ui/base/page_transition_types.h" class GURL; @@ -15,15 +18,35 @@ namespace base { class Time; } -namespace content { -class PageState; -struct Referrer; -} - namespace sessions { class SerializedNavigationEntry; +namespace test_data { + +extern const int kIndex; +extern const int kUniqueID; +extern const GURL kReferrerURL; +extern const int kReferrerPolicy; +extern const GURL kVirtualURL; +extern const base::string16 kTitle; +extern const std::string kEncodedPageState; +extern const ui::PageTransition kTransitionType; +extern const bool kHasPostData; +extern const int64 kPostID; +extern const GURL kOriginalRequestURL; +extern const bool kIsOverridingUserAgent; +extern const base::Time kTimestamp; +extern const base::string16 kSearchTerms; +extern const GURL kFaviconURL; +extern const int kHttpStatusCode; +extern const GURL kRedirectURL0; +extern const GURL kRedirectURL1; +extern const GURL kOtherURL; +extern const int kPageID; + +} // namespace test_data + // Set of test functions to manipulate a SerializedNavigationEntry. class SerializedNavigationEntryTestHelper { public: @@ -32,14 +55,26 @@ class SerializedNavigationEntryTestHelper { static void ExpectNavigationEquals(const SerializedNavigationEntry& expected, const SerializedNavigationEntry& actual); - // Create a SerializedNavigationEntry with the given URL and title and some + // Creates a SerializedNavigationEntry with the given URL and title and some // common values for the other fields. static SerializedNavigationEntry CreateNavigation( const std::string& virtual_url, const std::string& title); - static void SetPageState(const content::PageState& page_state, - SerializedNavigationEntry* navigation); + // Creates a SerializedNavigationEntry using the |test_data| constants above. + static SerializedNavigationEntry CreateNavigationForTest(); + + static void SetReferrerPolicy(int policy, + SerializedNavigationEntry* navigation); + + static void SetVirtualURL(const GURL& virtual_url, + SerializedNavigationEntry* navigation); + + static void SetEncodedPageState(const std::string& encoded_page_state, + SerializedNavigationEntry* navigation); + + static void SetTransitionType(ui::PageTransition transition_type, + SerializedNavigationEntry* navigation); static void SetHasPostData(bool has_post_data, SerializedNavigationEntry* navigation); diff --git a/components/sessions/serialized_navigation_entry_unittest.cc b/components/sessions/serialized_navigation_entry_unittest.cc index f14321a..70a3086 100644 --- a/components/sessions/serialized_navigation_entry_unittest.cc +++ b/components/sessions/serialized_navigation_entry_unittest.cc @@ -14,92 +14,34 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" -#include "content/public/browser/favicon_status.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/common/page_state.h" -#include "content/public/common/referrer.h" +#include "components/sessions/core/serialized_navigation_driver.h" +#include "components/sessions/serialized_navigation_entry_test_helper.h" #include "sync/protocol/session_specifics.pb.h" #include "sync/util/time.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/platform/WebReferrerPolicy.h" #include "ui/base/page_transition_types.h" #include "url/gurl.h" namespace sessions { namespace { -const int kIndex = 3; -const int kUniqueID = 50; -const GURL kReferrerURL = GURL("http://www.referrer.com"); -const int kReferrerPolicy = blink::WebReferrerPolicyAlways; -const GURL kVirtualURL("http://www.virtual-url.com"); -const base::string16 kTitle = base::ASCIIToUTF16("title"); -const std::string kEncodedPageState = "page state"; -const ui::PageTransition kTransitionType = - ui::PageTransitionFromInt( - ui::PAGE_TRANSITION_AUTO_SUBFRAME | - ui::PAGE_TRANSITION_HOME_PAGE | - ui::PAGE_TRANSITION_CLIENT_REDIRECT); -const bool kHasPostData = true; -const int64 kPostID = 100; -const GURL kOriginalRequestURL("http://www.original-request.com"); -const bool kIsOverridingUserAgent = true; -const base::Time kTimestamp = syncer::ProtoTimeToTime(100); -const base::string16 kSearchTerms = base::ASCIIToUTF16("my search terms"); -const GURL kFaviconURL("http://virtual-url.com/favicon.ico"); -const int kHttpStatusCode = 404; -const GURL kRedirectURL0("http://go/redirect0"); -const GURL kRedirectURL1("http://go/redirect1"); -const GURL kOtherURL("http://other.com"); - -const int kPageID = 10; - -// Create a NavigationEntry from the constants above. -scoped_ptr<content::NavigationEntry> MakeNavigationEntryForTest() { - scoped_ptr<content::NavigationEntry> navigation_entry( - content::NavigationEntry::Create()); - navigation_entry->SetReferrer(content::Referrer( - kReferrerURL, - static_cast<blink::WebReferrerPolicy>(kReferrerPolicy))); - navigation_entry->SetVirtualURL(kVirtualURL); - navigation_entry->SetTitle(kTitle); - navigation_entry->SetPageState( - content::PageState::CreateFromEncodedData(kEncodedPageState)); - navigation_entry->SetTransitionType(kTransitionType); - navigation_entry->SetHasPostData(kHasPostData); - navigation_entry->SetPostID(kPostID); - navigation_entry->SetOriginalRequestURL(kOriginalRequestURL); - navigation_entry->SetIsOverridingUserAgent(kIsOverridingUserAgent); - navigation_entry->SetTimestamp(kTimestamp); - navigation_entry->SetExtraData(kSearchTermsKey, kSearchTerms); - navigation_entry->GetFavicon().valid = true; - navigation_entry->GetFavicon().url = kFaviconURL; - navigation_entry->SetHttpStatusCode(kHttpStatusCode); - std::vector<GURL> redirect_chain; - redirect_chain.push_back(kRedirectURL0); - redirect_chain.push_back(kRedirectURL1); - redirect_chain.push_back(kVirtualURL); - navigation_entry->SetRedirectChain(redirect_chain); - return navigation_entry.Pass(); -} - // Create a sync_pb::TabNavigation from the constants above. sync_pb::TabNavigation MakeSyncDataForTest() { sync_pb::TabNavigation sync_data; - sync_data.set_virtual_url(kVirtualURL.spec()); - sync_data.set_referrer(kReferrerURL.spec()); - sync_data.set_referrer_policy(blink::WebReferrerPolicyOrigin); - sync_data.set_title(base::UTF16ToUTF8(kTitle)); - sync_data.set_state(kEncodedPageState); + sync_data.set_virtual_url(test_data::kVirtualURL.spec()); + sync_data.set_referrer(test_data::kReferrerURL.spec()); + sync_data.set_referrer_policy(test_data::kReferrerPolicy); + sync_data.set_title(base::UTF16ToUTF8(test_data::kTitle)); + sync_data.set_state(test_data::kEncodedPageState); sync_data.set_page_transition( sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME); - sync_data.set_unique_id(kUniqueID); - sync_data.set_timestamp_msec(syncer::TimeToProtoTime(kTimestamp)); + sync_data.set_unique_id(test_data::kUniqueID); + sync_data.set_timestamp_msec(syncer::TimeToProtoTime(test_data::kTimestamp)); sync_data.set_redirect_type(sync_pb::SyncEnums::CLIENT_REDIRECT); sync_data.set_navigation_home_page(true); - sync_data.set_search_terms(base::UTF16ToUTF8(kSearchTerms)); - sync_data.set_favicon_url(kFaviconURL.spec()); - sync_data.set_http_status_code(kHttpStatusCode); + sync_data.set_search_terms(base::UTF16ToUTF8(test_data::kSearchTerms)); + sync_data.set_favicon_url(test_data::kFaviconURL.spec()); + sync_data.set_http_status_code(test_data::kHttpStatusCode); // The redirect chain only syncs one way. return sync_data; } @@ -111,7 +53,9 @@ TEST(SerializedNavigationEntryTest, DefaultInitializer) { EXPECT_EQ(-1, navigation.index()); EXPECT_EQ(0, navigation.unique_id()); EXPECT_EQ(GURL(), navigation.referrer_url()); - EXPECT_EQ(blink::WebReferrerPolicyDefault, navigation.referrer_policy()); + EXPECT_EQ( + SerializedNavigationDriver::Get()->GetDefaultReferrerPolicy(), + navigation.referrer_policy()); EXPECT_EQ(GURL(), navigation.virtual_url()); EXPECT_TRUE(navigation.title().empty()); EXPECT_EQ(std::string(), navigation.encoded_page_state()); @@ -127,37 +71,6 @@ TEST(SerializedNavigationEntryTest, DefaultInitializer) { EXPECT_EQ(0U, navigation.redirect_chain().size()); } -// Create a SerializedNavigationEntry from a NavigationEntry. All its fields -// should match the NavigationEntry's. -TEST(SerializedNavigationEntryTest, FromNavigationEntry) { - const scoped_ptr<content::NavigationEntry> navigation_entry( - MakeNavigationEntryForTest()); - - const SerializedNavigationEntry& navigation = - SerializedNavigationEntry::FromNavigationEntry(kIndex, *navigation_entry); - - EXPECT_EQ(kIndex, navigation.index()); - - EXPECT_EQ(navigation_entry->GetUniqueID(), navigation.unique_id()); - EXPECT_EQ(kReferrerURL, navigation.referrer_url()); - EXPECT_EQ(kReferrerPolicy, navigation.referrer_policy()); - EXPECT_EQ(kVirtualURL, navigation.virtual_url()); - EXPECT_EQ(kTitle, navigation.title()); - EXPECT_EQ(kEncodedPageState, navigation.encoded_page_state()); - EXPECT_EQ(kTransitionType, navigation.transition_type()); - EXPECT_EQ(kHasPostData, navigation.has_post_data()); - EXPECT_EQ(kPostID, navigation.post_id()); - EXPECT_EQ(kOriginalRequestURL, navigation.original_request_url()); - EXPECT_EQ(kIsOverridingUserAgent, navigation.is_overriding_user_agent()); - EXPECT_EQ(kTimestamp, navigation.timestamp()); - EXPECT_EQ(kFaviconURL, navigation.favicon_url()); - EXPECT_EQ(kHttpStatusCode, navigation.http_status_code()); - ASSERT_EQ(3U, navigation.redirect_chain().size()); - EXPECT_EQ(kRedirectURL0, navigation.redirect_chain()[0]); - EXPECT_EQ(kRedirectURL1, navigation.redirect_chain()[1]); - EXPECT_EQ(kVirtualURL, navigation.redirect_chain()[2]); -} - // Create a SerializedNavigationEntry from a sync_pb::TabNavigation. All its // fields should match the protocol buffer's if it exists there, and // sbould be set to the default value otherwise. @@ -165,24 +78,24 @@ TEST(SerializedNavigationEntryTest, FromSyncData) { const sync_pb::TabNavigation sync_data = MakeSyncDataForTest(); const SerializedNavigationEntry& navigation = - SerializedNavigationEntry::FromSyncData(kIndex, sync_data); - - EXPECT_EQ(kIndex, navigation.index()); - EXPECT_EQ(kUniqueID, navigation.unique_id()); - EXPECT_EQ(kReferrerURL, navigation.referrer_url()); - EXPECT_EQ(blink::WebReferrerPolicyOrigin, navigation.referrer_policy()); - EXPECT_EQ(kVirtualURL, navigation.virtual_url()); - EXPECT_EQ(kTitle, navigation.title()); - EXPECT_EQ(kEncodedPageState, navigation.encoded_page_state()); - EXPECT_EQ(kTransitionType, navigation.transition_type()); + SerializedNavigationEntry::FromSyncData(test_data::kIndex, sync_data); + + EXPECT_EQ(test_data::kIndex, navigation.index()); + EXPECT_EQ(test_data::kUniqueID, navigation.unique_id()); + EXPECT_EQ(test_data::kReferrerURL, navigation.referrer_url()); + EXPECT_EQ(test_data::kReferrerPolicy, navigation.referrer_policy()); + EXPECT_EQ(test_data::kVirtualURL, navigation.virtual_url()); + EXPECT_EQ(test_data::kTitle, navigation.title()); + EXPECT_EQ(test_data::kEncodedPageState, navigation.encoded_page_state()); + EXPECT_EQ(test_data::kTransitionType, navigation.transition_type()); EXPECT_FALSE(navigation.has_post_data()); EXPECT_EQ(-1, navigation.post_id()); EXPECT_EQ(GURL(), navigation.original_request_url()); EXPECT_FALSE(navigation.is_overriding_user_agent()); EXPECT_TRUE(navigation.timestamp().is_null()); - EXPECT_EQ(kSearchTerms, navigation.search_terms()); - EXPECT_EQ(kFaviconURL, navigation.favicon_url()); - EXPECT_EQ(kHttpStatusCode, navigation.http_status_code()); + EXPECT_EQ(test_data::kSearchTerms, navigation.search_terms()); + EXPECT_EQ(test_data::kFaviconURL, navigation.favicon_url()); + EXPECT_EQ(test_data::kHttpStatusCode, navigation.http_status_code()); // The redirect chain only syncs one way. } @@ -190,9 +103,8 @@ TEST(SerializedNavigationEntryTest, FromSyncData) { // unpickling. The new one should match the old one except for fields // that aren't pickled, which should be set to default values. TEST(SerializedNavigationEntryTest, Pickle) { - const SerializedNavigationEntry& old_navigation = - SerializedNavigationEntry::FromNavigationEntry( - kIndex, *MakeNavigationEntryForTest()); + const SerializedNavigationEntry old_navigation = + SerializedNavigationEntryTestHelper::CreateNavigationForTest(); Pickle pickle; old_navigation.WriteToPickle(30000, &pickle); @@ -201,131 +113,89 @@ TEST(SerializedNavigationEntryTest, Pickle) { PickleIterator pickle_iterator(pickle); EXPECT_TRUE(new_navigation.ReadFromPickle(&pickle_iterator)); - EXPECT_EQ(kIndex, new_navigation.index()); - + // Fields that are written to the pickle. + EXPECT_EQ(test_data::kIndex, new_navigation.index()); + EXPECT_EQ(test_data::kReferrerURL, new_navigation.referrer_url()); + EXPECT_EQ(test_data::kReferrerPolicy, new_navigation.referrer_policy()); + EXPECT_EQ(test_data::kVirtualURL, new_navigation.virtual_url()); + EXPECT_EQ(test_data::kTitle, new_navigation.title()); + EXPECT_EQ(test_data::kTransitionType, new_navigation.transition_type()); + EXPECT_EQ(test_data::kHasPostData, new_navigation.has_post_data()); + EXPECT_EQ(test_data::kOriginalRequestURL, + new_navigation.original_request_url()); + EXPECT_EQ(test_data::kIsOverridingUserAgent, + new_navigation.is_overriding_user_agent()); + EXPECT_EQ(test_data::kTimestamp, new_navigation.timestamp()); + EXPECT_EQ(test_data::kSearchTerms, new_navigation.search_terms()); + EXPECT_EQ(test_data::kHttpStatusCode, new_navigation.http_status_code()); + + // Fields that are not written to the pickle. EXPECT_EQ(0, new_navigation.unique_id()); - EXPECT_EQ(kReferrerURL, new_navigation.referrer_url()); - EXPECT_EQ(kReferrerPolicy, new_navigation.referrer_policy()); - EXPECT_EQ(kVirtualURL, new_navigation.virtual_url()); - EXPECT_EQ(kTitle, new_navigation.title()); EXPECT_EQ(std::string(), new_navigation.encoded_page_state()); - EXPECT_EQ(kTransitionType, new_navigation.transition_type()); - EXPECT_EQ(kHasPostData, new_navigation.has_post_data()); EXPECT_EQ(-1, new_navigation.post_id()); - EXPECT_EQ(kOriginalRequestURL, new_navigation.original_request_url()); - EXPECT_EQ(kIsOverridingUserAgent, new_navigation.is_overriding_user_agent()); - EXPECT_EQ(kTimestamp, new_navigation.timestamp()); - EXPECT_EQ(kSearchTerms, new_navigation.search_terms()); - EXPECT_EQ(kHttpStatusCode, new_navigation.http_status_code()); EXPECT_EQ(0U, new_navigation.redirect_chain().size()); } -// Create a NavigationEntry, then create another one by converting to -// a SerializedNavigationEntry and back. The new one should match the old one -// except for fields that aren't preserved, which should be set to -// expected values. -TEST(SerializedNavigationEntryTest, ToNavigationEntry) { - const scoped_ptr<content::NavigationEntry> old_navigation_entry( - MakeNavigationEntryForTest()); - - const SerializedNavigationEntry& navigation = - SerializedNavigationEntry::FromNavigationEntry(kIndex, - *old_navigation_entry); - - const scoped_ptr<content::NavigationEntry> new_navigation_entry( - navigation.ToNavigationEntry(kPageID, NULL)); - - EXPECT_EQ(kReferrerURL, new_navigation_entry->GetReferrer().url); - EXPECT_EQ(kReferrerPolicy, new_navigation_entry->GetReferrer().policy); - EXPECT_EQ(kVirtualURL, new_navigation_entry->GetVirtualURL()); - EXPECT_EQ(kTitle, new_navigation_entry->GetTitle()); - EXPECT_EQ(kEncodedPageState, - new_navigation_entry->GetPageState().ToEncodedData()); - EXPECT_EQ(kPageID, new_navigation_entry->GetPageID()); - EXPECT_EQ(ui::PAGE_TRANSITION_RELOAD, - new_navigation_entry->GetTransitionType()); - EXPECT_EQ(kHasPostData, new_navigation_entry->GetHasPostData()); - EXPECT_EQ(kPostID, new_navigation_entry->GetPostID()); - EXPECT_EQ(kOriginalRequestURL, - new_navigation_entry->GetOriginalRequestURL()); - EXPECT_EQ(kIsOverridingUserAgent, - new_navigation_entry->GetIsOverridingUserAgent()); - base::string16 search_terms; - new_navigation_entry->GetExtraData(kSearchTermsKey, &search_terms); - EXPECT_EQ(kSearchTerms, search_terms); - EXPECT_EQ(kHttpStatusCode, new_navigation_entry->GetHttpStatusCode()); - ASSERT_EQ(3U, new_navigation_entry->GetRedirectChain().size()); - EXPECT_EQ(kRedirectURL0, new_navigation_entry->GetRedirectChain()[0]); - EXPECT_EQ(kRedirectURL1, new_navigation_entry->GetRedirectChain()[1]); - EXPECT_EQ(kVirtualURL, new_navigation_entry->GetRedirectChain()[2]); -} - -// Create a NavigationEntry, convert it to a SerializedNavigationEntry, then -// create a sync protocol buffer from it. The protocol buffer should -// have matching fields to the NavigationEntry (when applicable). +// Create a SerializedNavigationEntry, then create a sync protocol buffer from +// it. The protocol buffer should have matching fields to the +// SerializedNavigationEntry (when applicable). TEST(SerializedNavigationEntryTest, ToSyncData) { - const scoped_ptr<content::NavigationEntry> navigation_entry( - MakeNavigationEntryForTest()); - - const SerializedNavigationEntry& navigation = - SerializedNavigationEntry::FromNavigationEntry(kIndex, *navigation_entry); - + const SerializedNavigationEntry navigation = + SerializedNavigationEntryTestHelper::CreateNavigationForTest(); const sync_pb::TabNavigation sync_data = navigation.ToSyncData(); - EXPECT_EQ(kVirtualURL.spec(), sync_data.virtual_url()); - EXPECT_EQ(kReferrerURL.spec(), sync_data.referrer()); - EXPECT_EQ(kTitle, base::ASCIIToUTF16(sync_data.title())); + EXPECT_EQ(test_data::kVirtualURL.spec(), sync_data.virtual_url()); + EXPECT_EQ(test_data::kReferrerURL.spec(), sync_data.referrer()); + EXPECT_EQ(test_data::kTitle, base::ASCIIToUTF16(sync_data.title())); EXPECT_TRUE(sync_data.state().empty()); EXPECT_EQ(sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME, sync_data.page_transition()); EXPECT_TRUE(sync_data.has_redirect_type()); - EXPECT_EQ(navigation_entry->GetUniqueID(), sync_data.unique_id()); - EXPECT_EQ(syncer::TimeToProtoTime(kTimestamp), sync_data.timestamp_msec()); - EXPECT_EQ(kTimestamp.ToInternalValue(), sync_data.global_id()); - EXPECT_EQ(kFaviconURL.spec(), sync_data.favicon_url()); - EXPECT_EQ(kHttpStatusCode, sync_data.http_status_code()); + EXPECT_EQ(test_data::kUniqueID, sync_data.unique_id()); + EXPECT_EQ(syncer::TimeToProtoTime(test_data::kTimestamp), + sync_data.timestamp_msec()); + EXPECT_EQ(test_data::kTimestamp.ToInternalValue(), sync_data.global_id()); + EXPECT_EQ(test_data::kFaviconURL.spec(), sync_data.favicon_url()); + EXPECT_EQ(test_data::kHttpStatusCode, sync_data.http_status_code()); // The proto navigation redirects don't include the final chain entry // (because it didn't redirect) so the lengths should differ by 1. ASSERT_EQ(3, sync_data.navigation_redirect_size() + 1); - EXPECT_EQ(navigation_entry->GetRedirectChain()[0].spec(), + EXPECT_EQ(test_data::kRedirectURL0.spec(), sync_data.navigation_redirect(0).url()); - EXPECT_EQ(navigation_entry->GetRedirectChain()[1].spec(), + EXPECT_EQ(test_data::kRedirectURL1.spec(), sync_data.navigation_redirect(1).url()); EXPECT_FALSE(sync_data.has_last_navigation_redirect_url()); } -// Test that the last_navigation_redirect_url is set when needed. -// This test is just like the above, but with a different virtual_url. -// Create a NavigationEntry, convert it to a SerializedNavigationEntry, then -// create a sync protocol buffer from it. The protocol buffer should -// have a last_navigation_redirect_url. +// Test that the last_navigation_redirect_url is set when needed. This test is +// just like the above, but with a different virtual_url. Create a +// SerializedNavigationEntry, then create a sync protocol buffer from it. The +// protocol buffer should have a last_navigation_redirect_url. TEST(SerializedNavigationEntryTest, LastNavigationRedirectUrl) { - const scoped_ptr<content::NavigationEntry> navigation_entry( - MakeNavigationEntryForTest()); - - navigation_entry->SetVirtualURL(kOtherURL); - - const SerializedNavigationEntry& navigation = - SerializedNavigationEntry::FromNavigationEntry(kIndex, *navigation_entry); + SerializedNavigationEntry navigation = + SerializedNavigationEntryTestHelper::CreateNavigationForTest(); + SerializedNavigationEntryTestHelper::SetVirtualURL( + test_data::kOtherURL, &navigation); const sync_pb::TabNavigation sync_data = navigation.ToSyncData(); - EXPECT_TRUE(sync_data.has_last_navigation_redirect_url()); - EXPECT_EQ(kVirtualURL.spec(), sync_data.last_navigation_redirect_url()); + EXPECT_EQ(test_data::kVirtualURL.spec(), + sync_data.last_navigation_redirect_url()); // The redirect chain should be the same as in the above test. ASSERT_EQ(3, sync_data.navigation_redirect_size() + 1); - EXPECT_EQ(navigation_entry->GetRedirectChain()[0].spec(), + EXPECT_EQ(test_data::kRedirectURL0.spec(), sync_data.navigation_redirect(0).url()); - EXPECT_EQ(navigation_entry->GetRedirectChain()[1].spec(), + EXPECT_EQ(test_data::kRedirectURL1.spec(), sync_data.navigation_redirect(1).url()); } // Ensure all transition types and qualifiers are converted to/from the sync // SerializedNavigationEntry representation properly. TEST(SerializedNavigationEntryTest, TransitionTypes) { - scoped_ptr<content::NavigationEntry> navigation_entry( - MakeNavigationEntryForTest()); + SerializedNavigationEntry navigation = + SerializedNavigationEntryTestHelper::CreateNavigationForTest(); + for (uint32 core_type = ui::PAGE_TRANSITION_LINK; core_type != ui::PAGE_TRANSITION_LAST_CORE; ++core_type) { // Because qualifier is a uint32, left shifting will eventually overflow @@ -338,14 +208,12 @@ TEST(SerializedNavigationEntryTest, TransitionTypes) { continue; // 0x08000000 is not a valid qualifier. ui::PageTransition transition = ui::PageTransitionFromInt(core_type | qualifier); + SerializedNavigationEntryTestHelper::SetTransitionType( + transition, &navigation); - navigation_entry->SetTransitionType(transition); - const SerializedNavigationEntry& navigation = - SerializedNavigationEntry::FromNavigationEntry(kIndex, - *navigation_entry); const sync_pb::TabNavigation& sync_data = navigation.ToSyncData(); const SerializedNavigationEntry& constructed_nav = - SerializedNavigationEntry::FromSyncData(kIndex, sync_data); + SerializedNavigationEntry::FromSyncData(test_data::kIndex, sync_data); const ui::PageTransition constructed_transition = constructed_nav.transition_type(); @@ -354,39 +222,5 @@ TEST(SerializedNavigationEntryTest, TransitionTypes) { } } -// Tests that the input data is sanitized when a SerializedNavigationEntry -// is created from a pickle format. -TEST(SerializedNavigationEntryTest, Sanitize) { - sync_pb::TabNavigation sync_data = MakeSyncDataForTest(); - - sync_data.set_referrer_policy(blink::WebReferrerPolicyNever); - content::PageState page_state = - content::PageState::CreateFromURL(kVirtualURL); - sync_data.set_state(page_state.ToEncodedData()); - - const SerializedNavigationEntry& navigation = - SerializedNavigationEntry::FromSyncData(kIndex, sync_data); - - EXPECT_EQ(kIndex, navigation.index()); - EXPECT_EQ(kUniqueID, navigation.unique_id()); - EXPECT_EQ(GURL(), navigation.referrer_url()); - EXPECT_EQ(blink::WebReferrerPolicyDefault, navigation.referrer_policy()); - EXPECT_EQ(kVirtualURL, navigation.virtual_url()); - EXPECT_EQ(kTitle, navigation.title()); - EXPECT_EQ(page_state.ToEncodedData(), navigation.encoded_page_state()); - EXPECT_EQ(kTransitionType, navigation.transition_type()); - EXPECT_FALSE(navigation.has_post_data()); - EXPECT_EQ(-1, navigation.post_id()); - EXPECT_EQ(GURL(), navigation.original_request_url()); - EXPECT_FALSE(navigation.is_overriding_user_agent()); - EXPECT_TRUE(navigation.timestamp().is_null()); - EXPECT_EQ(kSearchTerms, navigation.search_terms()); - EXPECT_EQ(kFaviconURL, navigation.favicon_url()); - EXPECT_EQ(kHttpStatusCode, navigation.http_status_code()); - - content::PageState empty_state; - EXPECT_TRUE(empty_state.Equals(empty_state.RemoveReferrer())); -} - } // namespace } // namespace sessions diff --git a/components/sessions/sessions_export.h b/components/sessions/sessions_export.h index 66ac822..f307101 100644 --- a/components/sessions/sessions_export.h +++ b/components/sessions/sessions_export.h @@ -10,20 +10,25 @@ #if defined(SESSIONS_IMPLEMENTATION) #define SESSIONS_EXPORT __declspec(dllexport) +#define SESSIONS_EXPORT_PRIVATE __declspec(dllexport) #else #define SESSIONS_EXPORT __declspec(dllimport) -#endif // defined(BASE_PREFS_IMPLEMENTATION) +#define SESSIONS_EXPORT_PRIVATE __declspec(dllimport) +#endif // defined(SESSIONS_IMPLEMENTATION) #else // defined(WIN32) #if defined(SESSIONS_IMPLEMENTATION) #define SESSIONS_EXPORT __attribute__((visibility("default"))) +#define SESSIONS_EXPORT_PRIVATE __attribute__((visibility("default"))) #else #define SESSIONS_EXPORT +#define SESSIONS_EXPORT_PRIVATE #endif #endif #else // defined(COMPONENT_BUILD) #define SESSIONS_EXPORT +#define SESSIONS_EXPORT_PRIVATE #endif #endif // COMPONENTS_SESSIONS_SESSIONS_EXPORT_H_ |