• 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 "grit/content_resources.h"
14 #include "mojo/public/js/bindings/constants.h"
15 #include "ui/base/webui/jstemplate_builder.h"
16 #include "ui/base/webui/web_ui_util.h"
17 
18 namespace content {
19 
20 // static
Create(const std::string & source_name)21 WebUIDataSource* WebUIDataSource::Create(const std::string& source_name) {
22   return new WebUIDataSourceImpl(source_name);
23 }
24 
25 // static
AddMojoDataSource(BrowserContext * browser_context)26 WebUIDataSource* WebUIDataSource::AddMojoDataSource(
27     BrowserContext* browser_context) {
28   WebUIDataSource* mojo_source = Create("mojo");
29 
30   static const struct {
31     const char* path;
32     int id;
33   } resources[] = {
34     { mojo::kCodecModuleName, IDR_MOJO_CODEC_JS },
35     { mojo::kConnectionModuleName, IDR_MOJO_CONNECTION_JS },
36     { mojo::kConnectorModuleName, IDR_MOJO_CONNECTOR_JS },
37     { mojo::kRouterModuleName, IDR_MOJO_ROUTER_JS },
38     { mojo::kUnicodeModuleName, IDR_MOJO_UNICODE_JS },
39   };
40   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(resources); ++i)
41     mojo_source->AddResourcePath(resources[i].path, resources[i].id);
42 
43   URLDataManager::AddWebUIDataSource(browser_context, mojo_source);
44   return mojo_source;
45 }
46 
47 // static
Add(BrowserContext * browser_context,WebUIDataSource * source)48 void WebUIDataSource::Add(BrowserContext* browser_context,
49                           WebUIDataSource* source) {
50   URLDataManager::AddWebUIDataSource(browser_context, source);
51 }
52 
53 // Internal class to hide the fact that WebUIDataSourceImpl implements
54 // URLDataSource.
55 class WebUIDataSourceImpl::InternalDataSource : public URLDataSource {
56  public:
InternalDataSource(WebUIDataSourceImpl * parent)57   InternalDataSource(WebUIDataSourceImpl* parent) : parent_(parent) {
58   }
59 
~InternalDataSource()60   virtual ~InternalDataSource() {
61   }
62 
63   // URLDataSource implementation.
GetSource() const64   virtual std::string GetSource() const OVERRIDE {
65     return parent_->GetSource();
66   }
GetMimeType(const std::string & path) const67   virtual std::string GetMimeType(const std::string& path) const OVERRIDE {
68     return parent_->GetMimeType(path);
69   }
StartDataRequest(const std::string & path,int render_process_id,int render_frame_id,const URLDataSource::GotDataCallback & callback)70   virtual void StartDataRequest(
71       const std::string& path,
72       int render_process_id,
73       int render_frame_id,
74       const URLDataSource::GotDataCallback& callback) OVERRIDE {
75     return parent_->StartDataRequest(path, render_process_id, render_frame_id,
76                                      callback);
77   }
ShouldReplaceExistingSource() const78   virtual bool ShouldReplaceExistingSource() const OVERRIDE {
79     return parent_->replace_existing_source_;
80   }
AllowCaching() const81   virtual bool AllowCaching() const OVERRIDE {
82     return false;
83   }
ShouldAddContentSecurityPolicy() const84   virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE {
85     return parent_->add_csp_;
86   }
GetContentSecurityPolicyObjectSrc() const87   virtual std::string GetContentSecurityPolicyObjectSrc() const OVERRIDE {
88     if (parent_->object_src_set_)
89       return parent_->object_src_;
90     return URLDataSource::GetContentSecurityPolicyObjectSrc();
91   }
GetContentSecurityPolicyFrameSrc() const92   virtual std::string GetContentSecurityPolicyFrameSrc() const OVERRIDE {
93     if (parent_->frame_src_set_)
94       return parent_->frame_src_;
95     return URLDataSource::GetContentSecurityPolicyFrameSrc();
96   }
ShouldDenyXFrameOptions() const97   virtual bool ShouldDenyXFrameOptions() const OVERRIDE {
98     return parent_->deny_xframe_options_;
99   }
100 
101  private:
102   WebUIDataSourceImpl* parent_;
103 };
104 
WebUIDataSourceImpl(const std::string & source_name)105 WebUIDataSourceImpl::WebUIDataSourceImpl(const std::string& source_name)
106     : URLDataSourceImpl(
107           source_name,
108           new InternalDataSource(this)),
109       source_name_(source_name),
110       default_resource_(-1),
111       json_js_format_v2_(false),
112       add_csp_(true),
113       object_src_set_(false),
114       frame_src_set_(false),
115       deny_xframe_options_(true),
116       disable_set_font_strings_(false),
117       replace_existing_source_(true) {
118 }
119 
~WebUIDataSourceImpl()120 WebUIDataSourceImpl::~WebUIDataSourceImpl() {
121 }
122 
AddString(const std::string & name,const base::string16 & value)123 void WebUIDataSourceImpl::AddString(const std::string& name,
124                                     const base::string16& value) {
125   localized_strings_.SetString(name, value);
126 }
127 
AddString(const std::string & name,const std::string & value)128 void WebUIDataSourceImpl::AddString(const std::string& name,
129                                     const std::string& value) {
130   localized_strings_.SetString(name, value);
131 }
132 
AddLocalizedString(const std::string & name,int ids)133 void WebUIDataSourceImpl::AddLocalizedString(const std::string& name,
134                                              int ids) {
135   localized_strings_.SetString(
136       name, GetContentClient()->GetLocalizedString(ids));
137 }
138 
AddLocalizedStrings(const base::DictionaryValue & localized_strings)139 void WebUIDataSourceImpl::AddLocalizedStrings(
140     const base::DictionaryValue& localized_strings) {
141   localized_strings_.MergeDictionary(&localized_strings);
142 }
143 
AddBoolean(const std::string & name,bool value)144 void WebUIDataSourceImpl::AddBoolean(const std::string& name, bool value) {
145   localized_strings_.SetBoolean(name, value);
146 }
147 
SetJsonPath(const std::string & path)148 void WebUIDataSourceImpl::SetJsonPath(const std::string& path) {
149   json_path_ = path;
150 }
151 
SetUseJsonJSFormatV2()152 void WebUIDataSourceImpl::SetUseJsonJSFormatV2() {
153   json_js_format_v2_ = true;
154 }
155 
AddResourcePath(const std::string & path,int resource_id)156 void WebUIDataSourceImpl::AddResourcePath(const std::string &path,
157                                           int resource_id) {
158   path_to_idr_map_[path] = resource_id;
159 }
160 
SetDefaultResource(int resource_id)161 void WebUIDataSourceImpl::SetDefaultResource(int resource_id) {
162   default_resource_ = resource_id;
163 }
164 
SetRequestFilter(const WebUIDataSource::HandleRequestCallback & callback)165 void WebUIDataSourceImpl::SetRequestFilter(
166     const WebUIDataSource::HandleRequestCallback& callback) {
167   filter_callback_ = callback;
168 }
169 
DisableReplaceExistingSource()170 void WebUIDataSourceImpl::DisableReplaceExistingSource() {
171   replace_existing_source_ = false;
172 }
173 
DisableContentSecurityPolicy()174 void WebUIDataSourceImpl::DisableContentSecurityPolicy() {
175   add_csp_ = false;
176 }
177 
OverrideContentSecurityPolicyObjectSrc(const std::string & data)178 void WebUIDataSourceImpl::OverrideContentSecurityPolicyObjectSrc(
179     const std::string& data) {
180   object_src_set_ = true;
181   object_src_ = data;
182 }
183 
OverrideContentSecurityPolicyFrameSrc(const std::string & data)184 void WebUIDataSourceImpl::OverrideContentSecurityPolicyFrameSrc(
185     const std::string& data) {
186   frame_src_set_ = true;
187   frame_src_ = data;
188 }
189 
DisableDenyXFrameOptions()190 void WebUIDataSourceImpl::DisableDenyXFrameOptions() {
191   deny_xframe_options_ = false;
192 }
193 
GetSource() const194 std::string WebUIDataSourceImpl::GetSource() const {
195   return source_name_;
196 }
197 
GetMimeType(const std::string & path) const198 std::string WebUIDataSourceImpl::GetMimeType(const std::string& path) const {
199   if (EndsWith(path, ".js", false))
200     return "application/javascript";
201 
202   if (EndsWith(path, ".json", false))
203     return "application/json";
204 
205   if (EndsWith(path, ".pdf", false))
206     return "application/pdf";
207 
208   if (EndsWith(path, ".svg", false))
209     return "image/svg+xml";
210 
211   return "text/html";
212 }
213 
StartDataRequest(const std::string & path,int render_process_id,int render_frame_id,const URLDataSource::GotDataCallback & callback)214 void WebUIDataSourceImpl::StartDataRequest(
215     const std::string& path,
216     int render_process_id,
217     int render_frame_id,
218     const URLDataSource::GotDataCallback& callback) {
219   if (!filter_callback_.is_null() &&
220       filter_callback_.Run(path, callback)) {
221     return;
222   }
223 
224   if (!json_path_.empty() && path == json_path_) {
225     SendLocalizedStringsAsJSON(callback);
226     return;
227   }
228 
229   int resource_id = default_resource_;
230   std::map<std::string, int>::iterator result;
231   result = path_to_idr_map_.find(path);
232   if (result != path_to_idr_map_.end())
233     resource_id = result->second;
234   DCHECK_NE(resource_id, -1);
235   SendFromResourceBundle(callback, resource_id);
236 }
237 
SendLocalizedStringsAsJSON(const URLDataSource::GotDataCallback & callback)238 void WebUIDataSourceImpl::SendLocalizedStringsAsJSON(
239     const URLDataSource::GotDataCallback& callback) {
240   std::string template_data;
241   if (!disable_set_font_strings_)
242     webui::SetFontAndTextDirection(&localized_strings_);
243 
244   scoped_ptr<webui::UseVersion2> version2;
245   if (json_js_format_v2_)
246     version2.reset(new webui::UseVersion2);
247 
248   webui::AppendJsonJS(&localized_strings_, &template_data);
249   callback.Run(base::RefCountedString::TakeString(&template_data));
250 }
251 
SendFromResourceBundle(const URLDataSource::GotDataCallback & callback,int idr)252 void WebUIDataSourceImpl::SendFromResourceBundle(
253     const URLDataSource::GotDataCallback& callback, int idr) {
254   scoped_refptr<base::RefCountedStaticMemory> response(
255       GetContentClient()->GetDataResourceBytes(idr));
256   callback.Run(response.get());
257 }
258 
259 }  // namespace content
260