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 11 namespace content { 12 namespace { 13 14 base::NullableString16 ToNullableString16(const std::string& utf8) { 15 return base::NullableString16(base::UTF8ToUTF16(utf8), false); 16 } 17 18 base::FilePath ToFilePath(const base::NullableString16& s) { 19 return base::FilePath::FromUTF16Unsafe(s.string()); 20 } 21 22 void 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 30 PageState 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 38 void RecursivelyRemovePasswordData(ExplodedFrameState* state) { 39 if (state->http_body.contains_passwords) 40 state->http_body = ExplodedHttpBody(); 41 } 42 43 void RecursivelyRemoveScrollOffset(ExplodedFrameState* state) { 44 state->scroll_offset = gfx::Point(); 45 state->pinch_viewport_scroll_offset = gfx::PointF(); 46 } 47 48 void 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 61 PageState PageState::CreateFromEncodedData(const std::string& data) { 62 return PageState(data); 63 } 64 65 // static 66 PageState 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 75 PageState 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 107 PageState::PageState() { 108 } 109 110 bool PageState::IsValid() const { 111 return !data_.empty(); 112 } 113 114 bool PageState::Equals(const PageState& other) const { 115 return data_ == other.data_; 116 } 117 118 const std::string& PageState::ToEncodedData() const { 119 return data_; 120 } 121 122 std::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 132 PageState 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 142 PageState 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 152 PageState 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 165 PageState::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