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