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