page_state.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/public/common/page_state.h"
6
7#include "base/files/file_path.h"
8#include "base/strings/utf_string_conversions.h"
9#include "content/common/page_state_serialization.h"
10
11namespace content {
12namespace {
13
14base::NullableString16 ToNullableString16(const std::string& utf8) {
15  return base::NullableString16(base::UTF8ToUTF16(utf8), false);
16}
17
18base::FilePath ToFilePath(const base::NullableString16& s) {
19  return base::FilePath::FromUTF16Unsafe(s.string());
20}
21
22void ToFilePathVector(const std::vector<base::NullableString16>& input,
23                      std::vector<base::FilePath>* output) {
24  output->clear();
25  output->reserve(input.size());
26  for (size_t i = 0; i < input.size(); ++i)
27    output->push_back(ToFilePath(input[i]));
28}
29
30PageState ToPageState(const ExplodedPageState& state) {
31  std::string encoded_data;
32  if (!EncodePageState(state, &encoded_data))
33    return PageState();
34
35  return PageState::CreateFromEncodedData(encoded_data);
36}
37
38void RecursivelyRemovePasswordData(ExplodedFrameState* state) {
39  if (state->http_body.contains_passwords)
40    state->http_body = ExplodedHttpBody();
41}
42
43void RecursivelyRemoveScrollOffset(ExplodedFrameState* state) {
44  state->scroll_offset = gfx::Point();
45  state->pinch_viewport_scroll_offset = gfx::PointF();
46}
47
48void RecursivelyRemoveReferrer(ExplodedFrameState* state) {
49  state->referrer = base::NullableString16();
50  state->referrer_policy = blink::WebReferrerPolicyDefault;
51  for (std::vector<ExplodedFrameState>::iterator it = state->children.begin();
52       it != state->children.end();
53       ++it) {
54    RecursivelyRemoveReferrer(&*it);
55  }
56}
57
58}  // namespace
59
60// static
61PageState PageState::CreateFromEncodedData(const std::string& data) {
62  return PageState(data);
63}
64
65// static
66PageState PageState::CreateFromURL(const GURL& url) {
67  ExplodedPageState state;
68
69  state.top.url_string = ToNullableString16(url.possibly_invalid_spec());
70
71  return ToPageState(state);
72}
73
74// static
75PageState PageState::CreateForTesting(
76    const GURL& url,
77    bool body_contains_password_data,
78    const char* optional_body_data,
79    const base::FilePath* optional_body_file_path) {
80  ExplodedPageState state;
81
82  state.top.url_string = ToNullableString16(url.possibly_invalid_spec());
83
84  if (optional_body_data || optional_body_file_path) {
85    state.top.http_body.is_null = false;
86    if (optional_body_data) {
87      ExplodedHttpBodyElement element;
88      element.type = blink::WebHTTPBody::Element::TypeData;
89      element.data = optional_body_data;
90      state.top.http_body.elements.push_back(element);
91    }
92    if (optional_body_file_path) {
93      ExplodedHttpBodyElement element;
94      element.type = blink::WebHTTPBody::Element::TypeFile;
95      element.file_path =
96          ToNullableString16(optional_body_file_path->AsUTF8Unsafe());
97      state.top.http_body.elements.push_back(element);
98      state.referenced_files.push_back(element.file_path);
99    }
100    state.top.http_body.contains_passwords =
101        body_contains_password_data;
102  }
103
104  return ToPageState(state);
105}
106
107PageState::PageState() {
108}
109
110bool PageState::IsValid() const {
111  return !data_.empty();
112}
113
114bool PageState::Equals(const PageState& other) const {
115  return data_ == other.data_;
116}
117
118const std::string& PageState::ToEncodedData() const {
119  return data_;
120}
121
122std::vector<base::FilePath> PageState::GetReferencedFiles() const {
123  std::vector<base::FilePath> results;
124
125  ExplodedPageState state;
126  if (DecodePageState(data_, &state))
127    ToFilePathVector(state.referenced_files, &results);
128
129  return results;
130}
131
132PageState PageState::RemovePasswordData() const {
133  ExplodedPageState state;
134  if (!DecodePageState(data_, &state))
135    return PageState();  // Oops!
136
137  RecursivelyRemovePasswordData(&state.top);
138
139  return ToPageState(state);
140}
141
142PageState PageState::RemoveScrollOffset() const {
143  ExplodedPageState state;
144  if (!DecodePageState(data_, &state))
145    return PageState();  // Oops!
146
147  RecursivelyRemoveScrollOffset(&state.top);
148
149  return ToPageState(state);
150}
151
152PageState PageState::RemoveReferrer() const {
153  if (data_.empty())
154    return *this;
155
156  ExplodedPageState state;
157  if (!DecodePageState(data_, &state))
158    return PageState();  // Oops!
159
160  RecursivelyRemoveReferrer(&state.top);
161
162  return ToPageState(state);
163}
164
165PageState::PageState(const std::string& data)
166    : data_(data) {
167  // TODO(darin): Enable this DCHECK once tests have been fixed up to not pass
168  // bogus encoded data to CreateFromEncodedData.
169  //DCHECK(IsValid());
170}
171
172}  // namespace content
173