Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/search/local_ntp_source.h" | 5 #include "chrome/browser/search/local_ntp_source.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| 11 #include "base/base64.h" | |
| 11 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 12 #include "base/json/json_string_value_serializer.h" | 13 #include "base/json/json_string_value_serializer.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 15 #include "base/memory/ref_counted_memory.h" | 16 #include "base/memory/ref_counted_memory.h" |
| 16 #include "base/metrics/field_trial.h" | 17 #include "base/metrics/field_trial.h" |
| 17 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 18 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 19 #include "base/values.h" | 20 #include "base/values.h" |
| 20 #include "build/build_config.h" | 21 #include "build/build_config.h" |
| 21 #include "chrome/browser/search/instant_io_context.h" | 22 #include "chrome/browser/search/instant_io_context.h" |
| 22 #include "chrome/browser/search/local_files_ntp_source.h" | 23 #include "chrome/browser/search/local_files_ntp_source.h" |
| 23 #include "chrome/browser/search_engines/template_url_service_factory.h" | 24 #include "chrome/browser/search_engines/template_url_service_factory.h" |
| 24 #include "chrome/browser/themes/theme_properties.h" | 25 #include "chrome/browser/themes/theme_properties.h" |
| 25 #include "chrome/browser/themes/theme_service.h" | 26 #include "chrome/browser/themes/theme_service.h" |
| 26 #include "chrome/browser/themes/theme_service_factory.h" | 27 #include "chrome/browser/themes/theme_service_factory.h" |
| 27 #include "chrome/common/chrome_switches.h" | 28 #include "chrome/common/chrome_switches.h" |
| 28 #include "chrome/common/url_constants.h" | 29 #include "chrome/common/url_constants.h" |
| 29 #include "chrome/grit/browser_resources.h" | 30 #include "chrome/grit/browser_resources.h" |
| 30 #include "chrome/grit/generated_resources.h" | 31 #include "chrome/grit/generated_resources.h" |
| 31 #include "chrome/grit/theme_resources.h" | 32 #include "chrome/grit/theme_resources.h" |
| 32 #include "components/search_engines/template_url_service.h" | 33 #include "components/search_engines/template_url_service.h" |
| 33 #include "components/strings/grit/components_strings.h" | 34 #include "components/strings/grit/components_strings.h" |
| 35 #include "crypto/secure_hash.h" | |
| 36 #include "net/base/hash_value.h" | |
| 34 #include "net/url_request/url_request.h" | 37 #include "net/url_request/url_request.h" |
| 35 #include "third_party/skia/include/core/SkColor.h" | 38 #include "third_party/skia/include/core/SkColor.h" |
| 36 #include "ui/base/l10n/l10n_util.h" | 39 #include "ui/base/l10n/l10n_util.h" |
| 37 #include "ui/base/resource/resource_bundle.h" | 40 #include "ui/base/resource/resource_bundle.h" |
| 38 #include "ui/base/webui/web_ui_util.h" | 41 #include "ui/base/webui/web_ui_util.h" |
| 39 #include "ui/resources/grit/ui_resources.h" | 42 #include "ui/resources/grit/ui_resources.h" |
| 40 #include "url/gurl.h" | 43 #include "url/gurl.h" |
| 41 | 44 |
| 42 namespace { | 45 namespace { |
| 43 | 46 |
| 44 // Signifies a locally constructed resource, i.e. not from grit/. | 47 // Signifies a locally constructed resource, i.e. not from grit/. |
| 45 const int kLocalResource = -1; | 48 const int kLocalResource = -1; |
| 46 | 49 |
| 47 const char kConfigDataFilename[] = "config.js"; | 50 const char kConfigDataFilename[] = "config.js"; |
| 48 const char kThemeCSSFilename[] = "theme.css"; | 51 const char kThemeCSSFilename[] = "theme.css"; |
| 52 const char kMainHtmlFilename[] = "local-ntp.html"; | |
| 49 | 53 |
| 50 const struct Resource{ | 54 const struct Resource{ |
| 51 const char* filename; | 55 const char* filename; |
| 52 int identifier; | 56 int identifier; |
| 53 const char* mime_type; | 57 const char* mime_type; |
| 54 } kResources[] = { | 58 } kResources[] = { |
| 55 {"local-ntp.html", IDR_LOCAL_NTP_HTML, "text/html"}, | 59 {kMainHtmlFilename, kLocalResource, "text/html"}, |
| 56 {"local-ntp.js", IDR_LOCAL_NTP_JS, "application/javascript"}, | 60 {"local-ntp.js", IDR_LOCAL_NTP_JS, "application/javascript"}, |
| 57 {kConfigDataFilename, kLocalResource, "application/javascript"}, | 61 {kConfigDataFilename, kLocalResource, "application/javascript"}, |
| 58 {kThemeCSSFilename, kLocalResource, "text/css"}, | 62 {kThemeCSSFilename, kLocalResource, "text/css"}, |
| 59 {"local-ntp.css", IDR_LOCAL_NTP_CSS, "text/css"}, | 63 {"local-ntp.css", IDR_LOCAL_NTP_CSS, "text/css"}, |
| 60 {"images/close_3_mask.png", IDR_CLOSE_3_MASK, "image/png"}, | 64 {"images/close_3_mask.png", IDR_CLOSE_3_MASK, "image/png"}, |
| 61 {"images/close_4_button.png", IDR_CLOSE_4_BUTTON, "image/png"}, | 65 {"images/close_4_button.png", IDR_CLOSE_4_BUTTON, "image/png"}, |
| 62 {"images/ntp_default_favicon.png", IDR_NTP_DEFAULT_FAVICON, "image/png"}, | 66 {"images/ntp_default_favicon.png", IDR_NTP_DEFAULT_FAVICON, "image/png"}, |
| 63 }; | 67 }; |
| 64 | 68 |
| 65 // Strips any query parameters from the specified path. | 69 // Strips any query parameters from the specified path. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 JSONStringValueSerializer serializer(&js_text); | 131 JSONStringValueSerializer serializer(&js_text); |
| 128 serializer.Serialize(config_data); | 132 serializer.Serialize(config_data); |
| 129 | 133 |
| 130 std::string config_data_js; | 134 std::string config_data_js; |
| 131 config_data_js.append("var configData = "); | 135 config_data_js.append("var configData = "); |
| 132 config_data_js.append(js_text); | 136 config_data_js.append(js_text); |
| 133 config_data_js.append(";"); | 137 config_data_js.append(";"); |
| 134 return config_data_js; | 138 return config_data_js; |
| 135 } | 139 } |
| 136 | 140 |
| 141 std::string GetIntegritySha256Value(const std::string& data) { | |
| 142 // Compute the sha256 hash. | |
| 143 net::SHA256HashValue hash_value; | |
| 144 std::unique_ptr<crypto::SecureHash> hash( | |
| 145 crypto::SecureHash::Create(crypto::SecureHash::SHA256)); | |
| 146 hash->Update(data.data(), data.size()); | |
| 147 hash->Finish(&hash_value, sizeof(hash_value)); | |
| 148 | |
| 149 // Base64-encode it. | |
| 150 base::StringPiece hash_value_str(reinterpret_cast<char*>(hash_value.data), | |
| 151 sizeof(hash_value)); | |
| 152 std::string result; | |
| 153 base::Base64Encode(hash_value_str, &result); | |
| 154 return result; | |
| 155 } | |
| 156 | |
| 137 std::string GetThemeCSS(Profile* profile) { | 157 std::string GetThemeCSS(Profile* profile) { |
| 138 SkColor background_color = | 158 SkColor background_color = |
| 139 ThemeService::GetThemeProviderForProfile(profile) | 159 ThemeService::GetThemeProviderForProfile(profile) |
| 140 .GetColor(ThemeProperties::COLOR_NTP_BACKGROUND); | 160 .GetColor(ThemeProperties::COLOR_NTP_BACKGROUND); |
| 141 | 161 |
| 142 return base::StringPrintf("body { background-color: #%02X%02X%02X; }", | 162 return base::StringPrintf("body { background-color: #%02X%02X%02X; }", |
| 143 SkColorGetR(background_color), | 163 SkColorGetR(background_color), |
| 144 SkColorGetG(background_color), | 164 SkColorGetG(background_color), |
| 145 SkColorGetB(background_color)); | 165 SkColorGetB(background_color)); |
| 146 } | 166 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 174 std::string theme_css = GetThemeCSS(profile_); | 194 std::string theme_css = GetThemeCSS(profile_); |
| 175 callback.Run(base::RefCountedString::TakeString(&theme_css)); | 195 callback.Run(base::RefCountedString::TakeString(&theme_css)); |
| 176 return; | 196 return; |
| 177 } | 197 } |
| 178 | 198 |
| 179 #if !defined(GOOGLE_CHROME_BUILD) | 199 #if !defined(GOOGLE_CHROME_BUILD) |
| 180 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 200 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 181 if (command_line->HasSwitch(switches::kLocalNtpReload)) { | 201 if (command_line->HasSwitch(switches::kLocalNtpReload)) { |
| 182 if (stripped_path == "local-ntp.html" || stripped_path == "local-ntp.js" || | 202 if (stripped_path == "local-ntp.html" || stripped_path == "local-ntp.js" || |
| 183 stripped_path == "local-ntp.css") { | 203 stripped_path == "local-ntp.css") { |
| 204 // TODO(treib): This is now broken for the html file - need to insert the | |
| 205 // config hash. | |
|
Marc Treib
2017/04/07 16:46:15
...which would be somewhat annoying in terms of pl
sfiera
2017/04/10 08:53:21
What's it actually for? Live-editing the files in
Marc Treib
2017/04/10 10:11:18
Yup, it's for live-editing.
Good idea, I'll turn o
| |
| 184 base::ReplaceChars(stripped_path, "-", "_", &stripped_path); | 206 base::ReplaceChars(stripped_path, "-", "_", &stripped_path); |
| 185 local_ntp::SendLocalFileResource(stripped_path, callback); | 207 local_ntp::SendLocalFileResource(stripped_path, callback); |
| 186 return; | 208 return; |
| 187 } | 209 } |
| 188 } | 210 } |
| 189 #endif // !defined(GOOGLE_CHROME_BUILD) | 211 #endif // !defined(GOOGLE_CHROME_BUILD) |
| 190 | 212 |
| 213 if (stripped_path == kMainHtmlFilename) { | |
| 214 std::string html = ResourceBundle::GetSharedInstance() | |
| 215 .GetRawDataResource(IDR_LOCAL_NTP_HTML) | |
| 216 .as_string(); | |
| 217 std::string config_sha256 = | |
| 218 "sha256-" + GetIntegritySha256Value(GetConfigData(profile_)); | |
| 219 base::ReplaceFirstSubstringAfterOffset(&html, 0, "{{CONFIG_INTEGRITY}}", | |
| 220 config_sha256); | |
| 221 callback.Run(base::RefCountedString::TakeString(&html)); | |
| 222 return; | |
| 223 } | |
| 224 | |
| 191 float scale = 1.0f; | 225 float scale = 1.0f; |
| 192 std::string filename; | 226 std::string filename; |
| 193 webui::ParsePathAndScale( | 227 webui::ParsePathAndScale( |
| 194 GURL(GetLocalNtpPath() + stripped_path), &filename, &scale); | 228 GURL(GetLocalNtpPath() + stripped_path), &filename, &scale); |
| 195 ui::ScaleFactor scale_factor = ui::GetSupportedScaleFactor(scale); | 229 ui::ScaleFactor scale_factor = ui::GetSupportedScaleFactor(scale); |
| 196 | 230 |
| 197 for (size_t i = 0; i < arraysize(kResources); ++i) { | 231 for (size_t i = 0; i < arraysize(kResources); ++i) { |
| 198 if (filename == kResources[i].filename) { | 232 if (filename == kResources[i].filename) { |
| 199 scoped_refptr<base::RefCountedMemory> response( | 233 scoped_refptr<base::RefCountedMemory> response( |
| 200 ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale( | 234 ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale( |
| 201 kResources[i].identifier, scale_factor)); | 235 kResources[i].identifier, scale_factor)); |
| 202 callback.Run(response.get()); | 236 callback.Run(response.get()); |
| 203 return; | 237 return; |
| 204 } | 238 } |
| 205 } | 239 } |
| 206 callback.Run(NULL); | 240 callback.Run(nullptr); |
| 207 } | 241 } |
| 208 | 242 |
| 209 std::string LocalNtpSource::GetMimeType( | 243 std::string LocalNtpSource::GetMimeType( |
| 210 const std::string& path) const { | 244 const std::string& path) const { |
| 211 const std::string stripped_path = StripParameters(path); | 245 const std::string stripped_path = StripParameters(path); |
| 212 for (size_t i = 0; i < arraysize(kResources); ++i) { | 246 for (size_t i = 0; i < arraysize(kResources); ++i) { |
| 213 if (stripped_path == kResources[i].filename) | 247 if (stripped_path == kResources[i].filename) |
| 214 return kResources[i].mime_type; | 248 return kResources[i].mime_type; |
| 215 } | 249 } |
| 216 return std::string(); | 250 return std::string(); |
| 217 } | 251 } |
| 218 | 252 |
| 219 bool LocalNtpSource::AllowCaching() const { | 253 bool LocalNtpSource::AllowCaching() const { |
| 220 // Some resources served by LocalNtpSource, i.e. config.js, are dynamically | 254 // Some resources served by LocalNtpSource, i.e. config.js, are dynamically |
| 221 // generated and could differ on each access. To avoid using old cached | 255 // generated and could differ on each access. To avoid using old cached |
| 222 // content on reload, disallow caching here. Otherwise, it fails to reflect | 256 // content on reload, disallow caching here. Otherwise, it fails to reflect |
| 223 // newly revised user configurations in the page. | 257 // newly revised user configurations in the page. |
| 224 return false; | 258 return false; |
| 225 } | 259 } |
| 226 | 260 |
| 227 bool LocalNtpSource::ShouldServiceRequest( | 261 bool LocalNtpSource::ShouldServiceRequest( |
| 228 const net::URLRequest* request) const { | 262 const net::URLRequest* request) const { |
| 229 DCHECK(request->url().host_piece() == chrome::kChromeSearchLocalNtpHost); | 263 DCHECK(request->url().host_piece() == chrome::kChromeSearchLocalNtpHost); |
| 230 if (!InstantIOContext::ShouldServiceRequest(request)) | 264 if (!InstantIOContext::ShouldServiceRequest(request)) |
| 231 return false; | 265 return false; |
| 232 | 266 |
| 233 if (request->url().SchemeIs(chrome::kChromeSearchScheme)) { | 267 if (request->url().SchemeIs(chrome::kChromeSearchScheme)) { |
| 234 std::string filename; | 268 std::string filename; |
| 235 webui::ParsePathAndScale(request->url(), &filename, NULL); | 269 webui::ParsePathAndScale(request->url(), &filename, nullptr); |
| 236 for (size_t i = 0; i < arraysize(kResources); ++i) { | 270 for (size_t i = 0; i < arraysize(kResources); ++i) { |
| 237 if (filename == kResources[i].filename) | 271 if (filename == kResources[i].filename) |
| 238 return true; | 272 return true; |
| 239 } | 273 } |
| 240 } | 274 } |
| 241 return false; | 275 return false; |
| 242 } | 276 } |
| 243 | 277 |
| 278 std::string LocalNtpSource::GetContentSecurityPolicyScriptSrc() const { | |
| 279 return "script-src 'strict-dynamic' " | |
|
Marc Treib
2017/04/07 16:46:15
Could hide this behind a (default-enabled) feature
sfiera
2017/04/10 08:53:21
Right now, users only land on the local NTP if the
Marc Treib
2017/04/10 10:11:18
Even while offline, there should usually be a cach
| |
| 280 "'sha256-" + | |
| 281 GetIntegritySha256Value(GetConfigData(profile_)) + | |
|
sfiera
2017/04/10 08:53:21
Are we going to be computing this hash multiple ti
Marc Treib
2017/04/10 10:11:18
Yes; twice at the very least, probably even more o
sfiera
2017/04/10 10:28:53
I was thinking about computing once when the HTML
Marc Treib
2017/04/10 11:44:03
The CSP is served through HTTP headers, so that ac
| |
| 282 "' " | |
| 283 "'sha256-g38WaUaxnOIWY7E2LtLZ5ff9r5sn1dBj80jevt/kmx0=';"; | |
| 284 } | |
| 285 | |
| 244 std::string LocalNtpSource::GetContentSecurityPolicyChildSrc() const { | 286 std::string LocalNtpSource::GetContentSecurityPolicyChildSrc() const { |
| 245 // Allow embedding of most visited iframes. | 287 // Allow embedding of most visited iframes. |
| 246 return base::StringPrintf("child-src %s;", | 288 return base::StringPrintf("child-src %s;", |
| 247 chrome::kChromeSearchMostVisitedUrl); | 289 chrome::kChromeSearchMostVisitedUrl); |
| 248 } | 290 } |
| OLD | NEW |