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