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