| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/extensions/extension_protocols.h" | 5 #include "chrome/browser/extensions/extension_protocols.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> |
| 9 #include <vector> |
| 8 | 10 |
| 9 #include "base/base64.h" | 11 #include "base/base64.h" |
| 10 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 11 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 12 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
| 13 #include "base/format_macros.h" | 15 #include "base/format_macros.h" |
| 14 #include "base/logging.h" | 16 #include "base/logging.h" |
| 15 #include "base/memory/weak_ptr.h" | 17 #include "base/memory/weak_ptr.h" |
| 16 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
| 19 #include "base/metrics/field_trial.h" |
| 17 #include "base/metrics/histogram.h" | 20 #include "base/metrics/histogram.h" |
| 18 #include "base/path_service.h" | 21 #include "base/path_service.h" |
| 19 #include "base/sha1.h" | 22 #include "base/sha1.h" |
| 20 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
| 21 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
| 22 #include "base/strings/stringprintf.h" | 25 #include "base/strings/stringprintf.h" |
| 23 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
| 24 #include "base/threading/sequenced_worker_pool.h" | 27 #include "base/threading/sequenced_worker_pool.h" |
| 25 #include "base/threading/thread_restrictions.h" | 28 #include "base/threading/thread_restrictions.h" |
| 26 #include "base/timer/elapsed_timer.h" | 29 #include "base/timer/elapsed_timer.h" |
| 27 #include "build/build_config.h" | 30 #include "build/build_config.h" |
| 28 #include "chrome/browser/extensions/extension_renderer_state.h" | 31 #include "chrome/browser/extensions/extension_renderer_state.h" |
| 29 #include "chrome/browser/extensions/image_loader.h" | 32 #include "chrome/browser/extensions/image_loader.h" |
| 30 #include "chrome/common/chrome_paths.h" | 33 #include "chrome/common/chrome_paths.h" |
| 31 #include "chrome/common/extensions/manifest_handlers/icons_handler.h" | 34 #include "chrome/common/extensions/manifest_handlers/icons_handler.h" |
| 32 #include "chrome/common/extensions/manifest_url_handler.h" | 35 #include "chrome/common/extensions/manifest_url_handler.h" |
| 33 #include "chrome/common/url_constants.h" | 36 #include "chrome/common/url_constants.h" |
| 34 #include "content/public/browser/browser_thread.h" | 37 #include "content/public/browser/browser_thread.h" |
| 35 #include "content/public/browser/resource_request_info.h" | 38 #include "content/public/browser/resource_request_info.h" |
| 39 #include "crypto/secure_hash.h" |
| 40 #include "crypto/sha2.h" |
| 36 #include "extensions/browser/info_map.h" | 41 #include "extensions/browser/info_map.h" |
| 37 #include "extensions/common/constants.h" | 42 #include "extensions/common/constants.h" |
| 38 #include "extensions/common/extension.h" | 43 #include "extensions/common/extension.h" |
| 39 #include "extensions/common/extension_resource.h" | 44 #include "extensions/common/extension_resource.h" |
| 40 #include "extensions/common/file_util.h" | 45 #include "extensions/common/file_util.h" |
| 41 #include "extensions/common/manifest_handlers/background_info.h" | 46 #include "extensions/common/manifest_handlers/background_info.h" |
| 42 #include "extensions/common/manifest_handlers/csp_info.h" | 47 #include "extensions/common/manifest_handlers/csp_info.h" |
| 43 #include "extensions/common/manifest_handlers/incognito_info.h" | 48 #include "extensions/common/manifest_handlers/incognito_info.h" |
| 44 #include "extensions/common/manifest_handlers/shared_module_info.h" | 49 #include "extensions/common/manifest_handlers/shared_module_info.h" |
| 45 #include "extensions/common/manifest_handlers/web_accessible_resources_info.h" | 50 #include "extensions/common/manifest_handlers/web_accessible_resources_info.h" |
| 46 #include "extensions/common/manifest_handlers/webview_info.h" | 51 #include "extensions/common/manifest_handlers/webview_info.h" |
| 47 #include "grit/component_extension_resources_map.h" | 52 #include "grit/component_extension_resources_map.h" |
| 53 #include "net/base/io_buffer.h" |
| 48 #include "net/base/mime_util.h" | 54 #include "net/base/mime_util.h" |
| 49 #include "net/base/net_errors.h" | 55 #include "net/base/net_errors.h" |
| 50 #include "net/http/http_request_headers.h" | 56 #include "net/http/http_request_headers.h" |
| 51 #include "net/http/http_response_headers.h" | 57 #include "net/http/http_response_headers.h" |
| 52 #include "net/http/http_response_info.h" | 58 #include "net/http/http_response_info.h" |
| 53 #include "net/url_request/url_request_error_job.h" | 59 #include "net/url_request/url_request_error_job.h" |
| 54 #include "net/url_request/url_request_file_job.h" | 60 #include "net/url_request/url_request_file_job.h" |
| 55 #include "net/url_request/url_request_simple_job.h" | 61 #include "net/url_request/url_request_simple_job.h" |
| 56 #include "ui/base/resource/resource_bundle.h" | 62 #include "ui/base/resource/resource_bundle.h" |
| 57 #include "url/url_util.h" | 63 #include "url/url_util.h" |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 class URLRequestExtensionJob : public net::URLRequestFileJob { | 284 class URLRequestExtensionJob : public net::URLRequestFileJob { |
| 279 public: | 285 public: |
| 280 URLRequestExtensionJob(net::URLRequest* request, | 286 URLRequestExtensionJob(net::URLRequest* request, |
| 281 net::NetworkDelegate* network_delegate, | 287 net::NetworkDelegate* network_delegate, |
| 282 const std::string& extension_id, | 288 const std::string& extension_id, |
| 283 const base::FilePath& directory_path, | 289 const base::FilePath& directory_path, |
| 284 const base::FilePath& relative_path, | 290 const base::FilePath& relative_path, |
| 285 const std::string& content_security_policy, | 291 const std::string& content_security_policy, |
| 286 bool send_cors_header, | 292 bool send_cors_header, |
| 287 bool follow_symlinks_anywhere) | 293 bool follow_symlinks_anywhere) |
| 288 : net::URLRequestFileJob( | 294 : net::URLRequestFileJob( |
| 289 request, network_delegate, base::FilePath(), | 295 request, |
| 290 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( | 296 network_delegate, |
| 291 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), | 297 base::FilePath(), |
| 292 directory_path_(directory_path), | 298 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( |
| 293 // TODO(tc): Move all of these files into resources.pak so we don't break | 299 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), |
| 294 // when updating on Linux. | 300 seek_position_(0), |
| 295 resource_(extension_id, directory_path, relative_path), | 301 bytes_read_(0), |
| 296 content_security_policy_(content_security_policy), | 302 directory_path_(directory_path), |
| 297 send_cors_header_(send_cors_header), | 303 // TODO(tc): Move all of these files into resources.pak so we don't |
| 298 weak_factory_(this) { | 304 // break when updating on Linux. |
| 305 resource_(extension_id, directory_path, relative_path), |
| 306 content_security_policy_(content_security_policy), |
| 307 send_cors_header_(send_cors_header), |
| 308 weak_factory_(this) { |
| 299 if (follow_symlinks_anywhere) { | 309 if (follow_symlinks_anywhere) { |
| 300 resource_.set_follow_symlinks_anywhere(); | 310 resource_.set_follow_symlinks_anywhere(); |
| 301 } | 311 } |
| 312 const std::string& group = |
| 313 base::FieldTrialList::FindFullName("ExtensionContentHashMeasurement"); |
| 314 if (group == "Yes") { |
| 315 base::ElapsedTimer timer; |
| 316 hash_.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256)); |
| 317 hashing_time_ = timer.Elapsed(); |
| 318 } |
| 302 } | 319 } |
| 303 | 320 |
| 304 virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE { | 321 virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE { |
| 305 *info = response_info_; | 322 *info = response_info_; |
| 306 } | 323 } |
| 307 | 324 |
| 308 virtual void Start() OVERRIDE { | 325 virtual void Start() OVERRIDE { |
| 309 base::FilePath* read_file_path = new base::FilePath; | 326 base::FilePath* read_file_path = new base::FilePath; |
| 310 base::Time* last_modified_time = new base::Time(); | 327 base::Time* last_modified_time = new base::Time(); |
| 311 bool posted = BrowserThread::PostBlockingPoolTaskAndReply( | 328 bool posted = BrowserThread::PostBlockingPoolTaskAndReply( |
| 312 FROM_HERE, | 329 FROM_HERE, |
| 313 base::Bind(&ReadResourceFilePathAndLastModifiedTime, resource_, | 330 base::Bind(&ReadResourceFilePathAndLastModifiedTime, |
| 331 resource_, |
| 314 directory_path_, | 332 directory_path_, |
| 315 base::Unretained(read_file_path), | 333 base::Unretained(read_file_path), |
| 316 base::Unretained(last_modified_time)), | 334 base::Unretained(last_modified_time)), |
| 317 base::Bind(&URLRequestExtensionJob::OnFilePathAndLastModifiedTimeRead, | 335 base::Bind(&URLRequestExtensionJob::OnFilePathAndLastModifiedTimeRead, |
| 318 weak_factory_.GetWeakPtr(), | 336 weak_factory_.GetWeakPtr(), |
| 319 base::Owned(read_file_path), | 337 base::Owned(read_file_path), |
| 320 base::Owned(last_modified_time))); | 338 base::Owned(last_modified_time))); |
| 321 DCHECK(posted); | 339 DCHECK(posted); |
| 322 } | 340 } |
| 323 | 341 |
| 342 virtual void OnSeekComplete(int64 result) OVERRIDE { |
| 343 DCHECK_EQ(seek_position_, 0); |
| 344 seek_position_ = result; |
| 345 } |
| 346 |
| 347 virtual void OnReadComplete(net::IOBuffer* buffer, int result) OVERRIDE { |
| 348 UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.OnReadCompleteResult", result); |
| 349 if (result > 0) { |
| 350 bytes_read_ += result; |
| 351 if (hash_.get()) { |
| 352 base::ElapsedTimer timer; |
| 353 hash_->Update(buffer->data(), result); |
| 354 hashing_time_ += timer.Elapsed(); |
| 355 } |
| 356 } |
| 357 } |
| 358 |
| 324 private: | 359 private: |
| 325 virtual ~URLRequestExtensionJob() {} | 360 virtual ~URLRequestExtensionJob() { |
| 361 if (hash_.get()) { |
| 362 base::ElapsedTimer timer; |
| 363 std::string hash_bytes(crypto::kSHA256Length, 0); |
| 364 hash_->Finish(string_as_array(&hash_bytes), hash_bytes.size()); |
| 365 hashing_time_ += timer.Elapsed(); |
| 366 UMA_HISTOGRAM_TIMES("ExtensionUrlRequest.HashTimeMs", hashing_time_); |
| 367 } |
| 368 UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.TotalKbRead", bytes_read_ / 1024); |
| 369 UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.SeekPosition", seek_position_); |
| 370 } |
| 326 | 371 |
| 327 void OnFilePathAndLastModifiedTimeRead(base::FilePath* read_file_path, | 372 void OnFilePathAndLastModifiedTimeRead(base::FilePath* read_file_path, |
| 328 base::Time* last_modified_time) { | 373 base::Time* last_modified_time) { |
| 329 file_path_ = *read_file_path; | 374 file_path_ = *read_file_path; |
| 330 response_info_.headers = BuildHttpHeaders( | 375 response_info_.headers = BuildHttpHeaders( |
| 331 content_security_policy_, | 376 content_security_policy_, |
| 332 send_cors_header_, | 377 send_cors_header_, |
| 333 *last_modified_time); | 378 *last_modified_time); |
| 334 URLRequestFileJob::Start(); | 379 URLRequestFileJob::Start(); |
| 335 } | 380 } |
| 336 | 381 |
| 382 // A hash of the contents we've read from the file. |
| 383 scoped_ptr<crypto::SecureHash> hash_; |
| 384 |
| 385 // The position we seeked to in the file. |
| 386 int64 seek_position_; |
| 387 |
| 388 // The number of bytes of content we read from the file. |
| 389 int bytes_read_; |
| 390 |
| 391 // Used to count the total time it takes to do hashing operations. |
| 392 base::TimeDelta hashing_time_; |
| 393 |
| 337 net::HttpResponseInfo response_info_; | 394 net::HttpResponseInfo response_info_; |
| 338 base::FilePath directory_path_; | 395 base::FilePath directory_path_; |
| 339 extensions::ExtensionResource resource_; | 396 extensions::ExtensionResource resource_; |
| 340 std::string content_security_policy_; | 397 std::string content_security_policy_; |
| 341 bool send_cors_header_; | 398 bool send_cors_header_; |
| 342 base::WeakPtrFactory<URLRequestExtensionJob> weak_factory_; | 399 base::WeakPtrFactory<URLRequestExtensionJob> weak_factory_; |
| 343 }; | 400 }; |
| 344 | 401 |
| 345 bool ExtensionCanLoadInIncognito(const ResourceRequestInfo* info, | 402 bool ExtensionCanLoadInIncognito(const ResourceRequestInfo* info, |
| 346 const std::string& extension_id, | 403 const std::string& extension_id, |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 follow_symlinks_anywhere); | 693 follow_symlinks_anywhere); |
| 637 } | 694 } |
| 638 | 695 |
| 639 } // namespace | 696 } // namespace |
| 640 | 697 |
| 641 net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler( | 698 net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler( |
| 642 Profile::ProfileType profile_type, | 699 Profile::ProfileType profile_type, |
| 643 extensions::InfoMap* extension_info_map) { | 700 extensions::InfoMap* extension_info_map) { |
| 644 return new ExtensionProtocolHandler(profile_type, extension_info_map); | 701 return new ExtensionProtocolHandler(profile_type, extension_info_map); |
| 645 } | 702 } |
| OLD | NEW |