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