Home | History | Annotate | Download | only in common
      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