Home | History | Annotate | Download | only in webui
      1 // Copyright (c) 2012 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/browser/webui/web_ui_data_source_impl.h"
      6 
      7 #include <string>
      8 
      9 #include "base/bind.h"
     10 #include "base/memory/ref_counted_memory.h"
     11 #include "base/strings/string_util.h"
     12 #include "content/public/common/content_client.h"
     13 #include "ui/base/webui/jstemplate_builder.h"
     14 #include "ui/base/webui/web_ui_util.h"
     15 
     16 namespace content {
     17 
     18 WebUIDataSource* WebUIDataSource::Create(const std::string& source_name) {
     19   return new WebUIDataSourceImpl(source_name);
     20 }
     21 
     22 void WebUIDataSource::Add(BrowserContext* browser_context,
     23                           WebUIDataSource* source) {
     24   URLDataManager::AddWebUIDataSource(browser_context, source);
     25 }
     26 
     27 // Internal class to hide the fact that WebUIDataSourceImpl implements
     28 // URLDataSource.
     29 class WebUIDataSourceImpl::InternalDataSource : public URLDataSource {
     30  public:
     31   InternalDataSource(WebUIDataSourceImpl* parent) : parent_(parent) {
     32   }
     33 
     34   virtual ~InternalDataSource() {
     35   }
     36 
     37   // URLDataSource implementation.
     38   virtual std::string GetSource() const OVERRIDE {
     39     return parent_->GetSource();
     40   }
     41   virtual std::string GetMimeType(const std::string& path) const OVERRIDE {
     42     return parent_->GetMimeType(path);
     43   }
     44   virtual void StartDataRequest(
     45       const std::string& path,
     46       int render_process_id,
     47       int render_view_id,
     48       const URLDataSource::GotDataCallback& callback) OVERRIDE {
     49     return parent_->StartDataRequest(path, render_process_id, render_view_id,
     50                                      callback);
     51   }
     52   virtual bool ShouldReplaceExistingSource() const OVERRIDE {
     53     return parent_->replace_existing_source_;
     54   }
     55   virtual bool AllowCaching() const OVERRIDE {
     56     return false;
     57   }
     58   virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE {
     59     return parent_->add_csp_;
     60   }
     61   virtual std::string GetContentSecurityPolicyObjectSrc() const OVERRIDE {
     62     if (parent_->object_src_set_)
     63       return parent_->object_src_;
     64     return URLDataSource::GetContentSecurityPolicyObjectSrc();
     65   }
     66   virtual std::string GetContentSecurityPolicyFrameSrc() const OVERRIDE {
     67     if (parent_->frame_src_set_)
     68       return parent_->frame_src_;
     69     return URLDataSource::GetContentSecurityPolicyFrameSrc();
     70   }
     71   virtual bool ShouldDenyXFrameOptions() const OVERRIDE {
     72     return parent_->deny_xframe_options_;
     73   }
     74 
     75  private:
     76   WebUIDataSourceImpl* parent_;
     77 };
     78 
     79 WebUIDataSourceImpl::WebUIDataSourceImpl(const std::string& source_name)
     80     : URLDataSourceImpl(
     81           source_name,
     82           new InternalDataSource(this)),
     83       source_name_(source_name),
     84       default_resource_(-1),
     85       json_js_format_v2_(false),
     86       add_csp_(true),
     87       object_src_set_(false),
     88       frame_src_set_(false),
     89       deny_xframe_options_(true),
     90       disable_set_font_strings_(false),
     91       replace_existing_source_(true) {
     92 }
     93 
     94 WebUIDataSourceImpl::~WebUIDataSourceImpl() {
     95 }
     96 
     97 void WebUIDataSourceImpl::AddString(const std::string& name,
     98                                     const base::string16& value) {
     99   localized_strings_.SetString(name, value);
    100 }
    101 
    102 void WebUIDataSourceImpl::AddString(const std::string& name,
    103                                     const std::string& value) {
    104   localized_strings_.SetString(name, value);
    105 }
    106 
    107 void WebUIDataSourceImpl::AddLocalizedString(const std::string& name,
    108                                              int ids) {
    109   localized_strings_.SetString(
    110       name, GetContentClient()->GetLocalizedString(ids));
    111 }
    112 
    113 void WebUIDataSourceImpl::AddLocalizedStrings(
    114     const base::DictionaryValue& localized_strings) {
    115   localized_strings_.MergeDictionary(&localized_strings);
    116 }
    117 
    118 void WebUIDataSourceImpl::AddBoolean(const std::string& name, bool value) {
    119   localized_strings_.SetBoolean(name, value);
    120 }
    121 
    122 void WebUIDataSourceImpl::SetJsonPath(const std::string& path) {
    123   json_path_ = path;
    124 }
    125 
    126 void WebUIDataSourceImpl::SetUseJsonJSFormatV2() {
    127   json_js_format_v2_ = true;
    128 }
    129 
    130 void WebUIDataSourceImpl::AddResourcePath(const std::string &path,
    131                                           int resource_id) {
    132   path_to_idr_map_[path] = resource_id;
    133 }
    134 
    135 void WebUIDataSourceImpl::SetDefaultResource(int resource_id) {
    136   default_resource_ = resource_id;
    137 }
    138 
    139 void WebUIDataSourceImpl::SetRequestFilter(
    140     const WebUIDataSource::HandleRequestCallback& callback) {
    141   filter_callback_ = callback;
    142 }
    143 
    144 void WebUIDataSourceImpl::DisableReplaceExistingSource() {
    145   replace_existing_source_ = false;
    146 }
    147 
    148 void WebUIDataSourceImpl::DisableContentSecurityPolicy() {
    149   add_csp_ = false;
    150 }
    151 
    152 void WebUIDataSourceImpl::OverrideContentSecurityPolicyObjectSrc(
    153     const std::string& data) {
    154   object_src_set_ = true;
    155   object_src_ = data;
    156 }
    157 
    158 void WebUIDataSourceImpl::OverrideContentSecurityPolicyFrameSrc(
    159     const std::string& data) {
    160   frame_src_set_ = true;
    161   frame_src_ = data;
    162 }
    163 
    164 void WebUIDataSourceImpl::DisableDenyXFrameOptions() {
    165   deny_xframe_options_ = false;
    166 }
    167 
    168 std::string WebUIDataSourceImpl::GetSource() const {
    169   return source_name_;
    170 }
    171 
    172 std::string WebUIDataSourceImpl::GetMimeType(const std::string& path) const {
    173   if (EndsWith(path, ".js", false))
    174     return "application/javascript";
    175 
    176   if (EndsWith(path, ".json", false))
    177     return "application/json";
    178 
    179   if (EndsWith(path, ".pdf", false))
    180     return "application/pdf";
    181 
    182   if (EndsWith(path, ".svg", false))
    183     return "image/svg+xml";
    184 
    185   return "text/html";
    186 }
    187 
    188 void WebUIDataSourceImpl::StartDataRequest(
    189     const std::string& path,
    190     int render_process_id,
    191     int render_view_id,
    192     const URLDataSource::GotDataCallback& callback) {
    193   if (!filter_callback_.is_null() &&
    194       filter_callback_.Run(path, callback)) {
    195     return;
    196   }
    197 
    198   if (!json_path_.empty() && path == json_path_) {
    199     SendLocalizedStringsAsJSON(callback);
    200     return;
    201   }
    202 
    203   int resource_id = default_resource_;
    204   std::map<std::string, int>::iterator result;
    205   result = path_to_idr_map_.find(path);
    206   if (result != path_to_idr_map_.end())
    207     resource_id = result->second;
    208   DCHECK_NE(resource_id, -1);
    209   SendFromResourceBundle(callback, resource_id);
    210 }
    211 
    212 void WebUIDataSourceImpl::SendLocalizedStringsAsJSON(
    213     const URLDataSource::GotDataCallback& callback) {
    214   std::string template_data;
    215   if (!disable_set_font_strings_)
    216     webui::SetFontAndTextDirection(&localized_strings_);
    217 
    218   scoped_ptr<webui::UseVersion2> version2;
    219   if (json_js_format_v2_)
    220     version2.reset(new webui::UseVersion2);
    221 
    222   webui::AppendJsonJS(&localized_strings_, &template_data);
    223   callback.Run(base::RefCountedString::TakeString(&template_data));
    224 }
    225 
    226 void WebUIDataSourceImpl::SendFromResourceBundle(
    227     const URLDataSource::GotDataCallback& callback, int idr) {
    228   scoped_refptr<base::RefCountedStaticMemory> response(
    229       GetContentClient()->GetDataResourceBytes(idr));
    230   callback.Run(response.get());
    231 }
    232 
    233 }  // namespace content
    234