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