• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Create(const std::string & source_name)18 WebUIDataSource* WebUIDataSource::Create(const std::string& source_name) {
19   return new WebUIDataSourceImpl(source_name);
20 }
21 
Add(BrowserContext * browser_context,WebUIDataSource * source)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:
InternalDataSource(WebUIDataSourceImpl * parent)31   InternalDataSource(WebUIDataSourceImpl* parent) : parent_(parent) {
32   }
33 
~InternalDataSource()34   virtual ~InternalDataSource() {
35   }
36 
37   // URLDataSource implementation.
GetSource() const38   virtual std::string GetSource() const OVERRIDE {
39     return parent_->GetSource();
40   }
GetMimeType(const std::string & path) const41   virtual std::string GetMimeType(const std::string& path) const OVERRIDE {
42     return parent_->GetMimeType(path);
43   }
StartDataRequest(const std::string & path,int render_process_id,int render_view_id,const URLDataSource::GotDataCallback & callback)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   }
ShouldReplaceExistingSource() const52   virtual bool ShouldReplaceExistingSource() const OVERRIDE {
53     return parent_->replace_existing_source_;
54   }
AllowCaching() const55   virtual bool AllowCaching() const OVERRIDE {
56     return false;
57   }
ShouldAddContentSecurityPolicy() const58   virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE {
59     return parent_->add_csp_;
60   }
GetContentSecurityPolicyObjectSrc() const61   virtual std::string GetContentSecurityPolicyObjectSrc() const OVERRIDE {
62     if (parent_->object_src_set_)
63       return parent_->object_src_;
64     return URLDataSource::GetContentSecurityPolicyObjectSrc();
65   }
GetContentSecurityPolicyFrameSrc() const66   virtual std::string GetContentSecurityPolicyFrameSrc() const OVERRIDE {
67     if (parent_->frame_src_set_)
68       return parent_->frame_src_;
69     return URLDataSource::GetContentSecurityPolicyFrameSrc();
70   }
ShouldDenyXFrameOptions() const71   virtual bool ShouldDenyXFrameOptions() const OVERRIDE {
72     return parent_->deny_xframe_options_;
73   }
74 
75  private:
76   WebUIDataSourceImpl* parent_;
77 };
78 
WebUIDataSourceImpl(const std::string & source_name)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 
~WebUIDataSourceImpl()94 WebUIDataSourceImpl::~WebUIDataSourceImpl() {
95 }
96 
AddString(const std::string & name,const base::string16 & value)97 void WebUIDataSourceImpl::AddString(const std::string& name,
98                                     const base::string16& value) {
99   localized_strings_.SetString(name, value);
100 }
101 
AddString(const std::string & name,const std::string & value)102 void WebUIDataSourceImpl::AddString(const std::string& name,
103                                     const std::string& value) {
104   localized_strings_.SetString(name, value);
105 }
106 
AddLocalizedString(const std::string & name,int ids)107 void WebUIDataSourceImpl::AddLocalizedString(const std::string& name,
108                                              int ids) {
109   localized_strings_.SetString(
110       name, GetContentClient()->GetLocalizedString(ids));
111 }
112 
AddLocalizedStrings(const base::DictionaryValue & localized_strings)113 void WebUIDataSourceImpl::AddLocalizedStrings(
114     const base::DictionaryValue& localized_strings) {
115   localized_strings_.MergeDictionary(&localized_strings);
116 }
117 
AddBoolean(const std::string & name,bool value)118 void WebUIDataSourceImpl::AddBoolean(const std::string& name, bool value) {
119   localized_strings_.SetBoolean(name, value);
120 }
121 
SetJsonPath(const std::string & path)122 void WebUIDataSourceImpl::SetJsonPath(const std::string& path) {
123   json_path_ = path;
124 }
125 
SetUseJsonJSFormatV2()126 void WebUIDataSourceImpl::SetUseJsonJSFormatV2() {
127   json_js_format_v2_ = true;
128 }
129 
AddResourcePath(const std::string & path,int resource_id)130 void WebUIDataSourceImpl::AddResourcePath(const std::string &path,
131                                           int resource_id) {
132   path_to_idr_map_[path] = resource_id;
133 }
134 
SetDefaultResource(int resource_id)135 void WebUIDataSourceImpl::SetDefaultResource(int resource_id) {
136   default_resource_ = resource_id;
137 }
138 
SetRequestFilter(const WebUIDataSource::HandleRequestCallback & callback)139 void WebUIDataSourceImpl::SetRequestFilter(
140     const WebUIDataSource::HandleRequestCallback& callback) {
141   filter_callback_ = callback;
142 }
143 
DisableReplaceExistingSource()144 void WebUIDataSourceImpl::DisableReplaceExistingSource() {
145   replace_existing_source_ = false;
146 }
147 
DisableContentSecurityPolicy()148 void WebUIDataSourceImpl::DisableContentSecurityPolicy() {
149   add_csp_ = false;
150 }
151 
OverrideContentSecurityPolicyObjectSrc(const std::string & data)152 void WebUIDataSourceImpl::OverrideContentSecurityPolicyObjectSrc(
153     const std::string& data) {
154   object_src_set_ = true;
155   object_src_ = data;
156 }
157 
OverrideContentSecurityPolicyFrameSrc(const std::string & data)158 void WebUIDataSourceImpl::OverrideContentSecurityPolicyFrameSrc(
159     const std::string& data) {
160   frame_src_set_ = true;
161   frame_src_ = data;
162 }
163 
DisableDenyXFrameOptions()164 void WebUIDataSourceImpl::DisableDenyXFrameOptions() {
165   deny_xframe_options_ = false;
166 }
167 
GetSource() const168 std::string WebUIDataSourceImpl::GetSource() const {
169   return source_name_;
170 }
171 
GetMimeType(const std::string & path) const172 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 
StartDataRequest(const std::string & path,int render_process_id,int render_view_id,const URLDataSource::GotDataCallback & callback)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 
SendLocalizedStringsAsJSON(const URLDataSource::GotDataCallback & callback)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 
SendFromResourceBundle(const URLDataSource::GotDataCallback & callback,int idr)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