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/webui/jstemplate_builder.h" 14 #include "ui/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 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 73 WebUIDataSourceImpl::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 87 WebUIDataSourceImpl::~WebUIDataSourceImpl() { 88 } 89 90 void WebUIDataSourceImpl::AddString(const std::string& name, 91 const string16& value) { 92 localized_strings_.SetString(name, value); 93 } 94 95 void WebUIDataSourceImpl::AddString(const std::string& name, 96 const std::string& value) { 97 localized_strings_.SetString(name, value); 98 } 99 100 void WebUIDataSourceImpl::AddLocalizedString(const std::string& name, 101 int ids) { 102 localized_strings_.SetString( 103 name, GetContentClient()->GetLocalizedString(ids)); 104 } 105 106 void WebUIDataSourceImpl::AddLocalizedStrings( 107 const base::DictionaryValue& localized_strings) { 108 localized_strings_.MergeDictionary(&localized_strings); 109 } 110 111 void WebUIDataSourceImpl::AddBoolean(const std::string& name, bool value) { 112 localized_strings_.SetBoolean(name, value); 113 } 114 115 void WebUIDataSourceImpl::SetJsonPath(const std::string& path) { 116 json_path_ = path; 117 } 118 119 void WebUIDataSourceImpl::SetUseJsonJSFormatV2() { 120 json_js_format_v2_ = true; 121 } 122 123 void WebUIDataSourceImpl::AddResourcePath(const std::string &path, 124 int resource_id) { 125 path_to_idr_map_[path] = resource_id; 126 } 127 128 void WebUIDataSourceImpl::SetDefaultResource(int resource_id) { 129 default_resource_ = resource_id; 130 } 131 132 void WebUIDataSourceImpl::SetRequestFilter( 133 const WebUIDataSource::HandleRequestCallback& callback) { 134 filter_callback_ = callback; 135 } 136 137 void WebUIDataSourceImpl::DisableContentSecurityPolicy() { 138 add_csp_ = false; 139 } 140 141 void WebUIDataSourceImpl::OverrideContentSecurityPolicyObjectSrc( 142 const std::string& data) { 143 object_src_set_ = true; 144 object_src_ = data; 145 } 146 147 void WebUIDataSourceImpl::OverrideContentSecurityPolicyFrameSrc( 148 const std::string& data) { 149 frame_src_set_ = true; 150 frame_src_ = data; 151 } 152 153 void WebUIDataSourceImpl::DisableDenyXFrameOptions() { 154 deny_xframe_options_ = false; 155 } 156 157 std::string WebUIDataSourceImpl::GetSource() const { 158 return source_name_; 159 } 160 161 std::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 174 void 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 198 void 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 212 void WebUIDataSourceImpl::SendFromResourceBundle( 213 const URLDataSource::GotDataCallback& callback, int idr) { 214 scoped_refptr<base::RefCountedStaticMemory> response( 215 GetContentClient()->GetDataResourceBytes(idr)); 216 callback.Run(response.get()); 217 } 218 219 } // namespace content 220