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 // This file contains an implementation of the ResourceLoaderBridge class. | 5 // This file contains an implementation of the ResourceLoaderBridge class. |
6 // The class is implemented using net::URLRequest, meaning it is a "simple" | 6 // The class is implemented using net::URLRequest, meaning it is a "simple" |
7 // version that directly issues requests. The more complicated one used in the | 7 // version that directly issues requests. The more complicated one used in the |
8 // browser uses IPC. | 8 // browser uses IPC. |
9 // | 9 // |
10 // Because net::URLRequest only provides an asynchronous resource loading API, | 10 // Because net::URLRequest only provides an asynchronous resource loading API, |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 scoped_refptr<net::UploadData> upload; | 266 scoped_refptr<net::UploadData> upload; |
267 }; | 267 }; |
268 | 268 |
269 // The interval for calls to RequestProxy::MaybeUpdateUploadProgress | 269 // The interval for calls to RequestProxy::MaybeUpdateUploadProgress |
270 static const int kUpdateUploadProgressIntervalMsec = 100; | 270 static const int kUpdateUploadProgressIntervalMsec = 100; |
271 | 271 |
272 // The RequestProxy does most of its work on the IO thread. The Start and | 272 // The RequestProxy does most of its work on the IO thread. The Start and |
273 // Cancel methods are proxied over to the IO thread, where an net::URLRequest | 273 // Cancel methods are proxied over to the IO thread, where an net::URLRequest |
274 // object is instantiated. | 274 // object is instantiated. |
275 class RequestProxy : public net::URLRequest::Delegate, | 275 class RequestProxy : public net::URLRequest::Delegate, |
276 public base::RefCountedThreadSafe<RequestProxy> { | 276 public base::RefCountedThreadSafe<RequestProxy> { |
darin (slow to review)
2012/04/05 20:45:21
wouldn't it be simpler to just use a Traits class
Ami GONE FROM CHROMIUM
2012/04/05 22:14:31
Hell yes. That'd qualify as "a better way to expr
| |
277 public: | 277 public: |
278 // Takes ownership of the params. | 278 // Takes ownership of the params. |
279 RequestProxy() | 279 RequestProxy() |
280 : download_to_file_(false), | 280 : download_to_file_(false), |
281 file_stream_(NULL), | 281 file_stream_(NULL), |
282 buf_(new net::IOBuffer(kDataSize)), | 282 buf_(new net::IOBuffer(kDataSize)), |
283 last_upload_position_(0) { | 283 last_upload_position_(0) { |
284 } | 284 } |
285 | 285 |
286 void DropPeer() { | 286 void DropPeer() { |
287 peer_ = NULL; | 287 peer_ = NULL; |
288 } | 288 } |
289 | 289 |
290 void Start(ResourceLoaderBridge::Peer* peer, RequestParams* params) { | 290 void Start(ResourceLoaderBridge::Peer* peer, RequestParams* params) { |
291 peer_ = peer; | 291 peer_ = peer; |
292 owner_loop_ = MessageLoop::current(); | 292 owner_loop_ = base::MessageLoopProxy::current(); |
293 | 293 |
294 ConvertRequestParamsForFileOverHTTPIfNeeded(params); | 294 ConvertRequestParamsForFileOverHTTPIfNeeded(params); |
295 // proxy over to the io thread | 295 // proxy over to the io thread |
296 g_io_thread->message_loop()->PostTask( | 296 g_io_thread->message_loop()->PostTask( |
297 FROM_HERE, | 297 FROM_HERE, |
298 base::Bind(&RequestProxy::AsyncStart, this, params)); | 298 base::Bind(&RequestProxy::AsyncStart, this, params)); |
299 } | 299 } |
300 | 300 |
301 void Cancel() { | 301 void Cancel() { |
302 // proxy over to the io thread | 302 // proxy over to the io thread |
303 g_io_thread->message_loop()->PostTask( | 303 g_io_thread->message_loop()->PostTask( |
304 FROM_HERE, | 304 FROM_HERE, |
305 base::Bind(&RequestProxy::AsyncCancel, this)); | 305 base::Bind(&RequestProxy::AsyncCancel, this)); |
306 } | 306 } |
307 | 307 |
308 protected: | 308 protected: |
309 friend class base::RefCountedThreadSafe<RequestProxy>; | 309 friend class base::RefCountedThreadSafe<RequestProxy>; |
310 | 310 |
311 virtual ~RequestProxy() { | 311 virtual ~RequestProxy() { |
312 // If we have a request, then we'd better be on the io thread! | 312 // Ensure we are deleted on the IO thread because base::Timer requires that. |
313 DCHECK(!request_.get() || | 313 DCHECK(MessageLoop::current() == g_io_thread->message_loop()); |
314 MessageLoop::current() == g_io_thread->message_loop()); | |
315 } | 314 } |
316 | 315 |
317 // -------------------------------------------------------------------------- | 316 // -------------------------------------------------------------------------- |
318 // The following methods are called on the owner's thread in response to | 317 // The following methods are called on the owner's thread in response to |
319 // various net::URLRequest callbacks. The event hooks, defined below, trigger | 318 // various net::URLRequest callbacks. The event hooks, defined below, trigger |
320 // these methods asynchronously. | 319 // these methods asynchronously. |
321 | 320 |
322 void NotifyReceivedRedirect(const GURL& new_url, | 321 void NotifyReceivedRedirect(const GURL& new_url, |
323 const ResourceResponseInfo& info) { | 322 const ResourceResponseInfo& info) { |
324 bool has_new_first_party_for_cookies = false; | 323 bool has_new_first_party_for_cookies = false; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
472 } // else wait for OnReadCompleted | 471 } // else wait for OnReadCompleted |
473 } else { | 472 } else { |
474 Done(); | 473 Done(); |
475 } | 474 } |
476 } | 475 } |
477 | 476 |
478 // -------------------------------------------------------------------------- | 477 // -------------------------------------------------------------------------- |
479 // The following methods are event hooks (corresponding to net::URLRequest | 478 // The following methods are event hooks (corresponding to net::URLRequest |
480 // callbacks) that run on the IO thread. They are designed to be overridden | 479 // callbacks) that run on the IO thread. They are designed to be overridden |
481 // by the SyncRequestProxy subclass. | 480 // by the SyncRequestProxy subclass. |
481 // | |
482 // Note that since |this| must be ultimately destroyed on the IO thread, each | |
483 // of these uses a do-nothing reply closure to extend |this|'s lifetime long | |
484 // enough to avoid being deleted on the owner thread. | |
482 | 485 |
483 virtual void OnReceivedRedirect( | 486 virtual void OnReceivedRedirect( |
484 const GURL& new_url, | 487 const GURL& new_url, |
485 const ResourceResponseInfo& info, | 488 const ResourceResponseInfo& info, |
486 bool* defer_redirect) { | 489 bool* defer_redirect) { |
487 *defer_redirect = true; // See AsyncFollowDeferredRedirect | 490 *defer_redirect = true; // See AsyncFollowDeferredRedirect |
488 owner_loop_->PostTask( | 491 owner_loop_->PostTaskAndReply( |
489 FROM_HERE, | 492 FROM_HERE, |
490 base::Bind(&RequestProxy::NotifyReceivedRedirect, this, new_url, info)); | 493 base::Bind(&RequestProxy::NotifyReceivedRedirect, this, new_url, info), |
494 base::Bind(&RequestProxy::DoNothing, this)); | |
491 } | 495 } |
492 | 496 |
493 virtual void OnReceivedResponse( | 497 virtual void OnReceivedResponse( |
494 const ResourceResponseInfo& info) { | 498 const ResourceResponseInfo& info) { |
495 owner_loop_->PostTask( | 499 owner_loop_->PostTaskAndReply( |
496 FROM_HERE, | 500 FROM_HERE, |
497 base::Bind(&RequestProxy::NotifyReceivedResponse, this, info)); | 501 base::Bind(&RequestProxy::NotifyReceivedResponse, this, info), |
502 base::Bind(&RequestProxy::DoNothing, this)); | |
498 } | 503 } |
499 | 504 |
500 virtual void OnReceivedData(int bytes_read) { | 505 virtual void OnReceivedData(int bytes_read) { |
501 if (download_to_file_) { | 506 if (download_to_file_) { |
502 file_stream_.WriteSync(buf_->data(), bytes_read); | 507 file_stream_.WriteSync(buf_->data(), bytes_read); |
503 owner_loop_->PostTask( | 508 owner_loop_->PostTaskAndReply( |
504 FROM_HERE, | 509 FROM_HERE, |
505 base::Bind(&RequestProxy::NotifyDownloadedData, this, bytes_read)); | 510 base::Bind(&RequestProxy::NotifyDownloadedData, this, bytes_read), |
511 base::Bind(&RequestProxy::DoNothing, this)); | |
506 return; | 512 return; |
507 } | 513 } |
508 | 514 |
509 owner_loop_->PostTask( | 515 owner_loop_->PostTaskAndReply( |
510 FROM_HERE, | 516 FROM_HERE, |
511 base::Bind(&RequestProxy::NotifyReceivedData, this, bytes_read)); | 517 base::Bind(&RequestProxy::NotifyReceivedData, this, bytes_read), |
518 base::Bind(&RequestProxy::DoNothing, this)); | |
512 } | 519 } |
513 | 520 |
514 virtual void OnCompletedRequest(const net::URLRequestStatus& status, | 521 virtual void OnCompletedRequest(const net::URLRequestStatus& status, |
515 const std::string& security_info, | 522 const std::string& security_info, |
516 const base::TimeTicks& complete_time) { | 523 const base::TimeTicks& complete_time) { |
517 if (download_to_file_) | 524 if (download_to_file_) |
518 file_stream_.CloseSync(); | 525 file_stream_.CloseSync(); |
519 owner_loop_->PostTask( | 526 owner_loop_->PostTaskAndReply( |
520 FROM_HERE, | 527 FROM_HERE, |
521 base::Bind(&RequestProxy::NotifyCompletedRequest, this, status, | 528 base::Bind(&RequestProxy::NotifyCompletedRequest, this, status, |
522 security_info, complete_time)); | 529 security_info, complete_time), |
530 base::Bind(&RequestProxy::DoNothing, this)); | |
523 } | 531 } |
524 | 532 |
525 // -------------------------------------------------------------------------- | 533 // -------------------------------------------------------------------------- |
526 // net::URLRequest::Delegate implementation: | 534 // net::URLRequest::Delegate implementation: |
527 | 535 |
528 virtual void OnReceivedRedirect(net::URLRequest* request, | 536 virtual void OnReceivedRedirect(net::URLRequest* request, |
529 const GURL& new_url, | 537 const GURL& new_url, |
530 bool* defer_redirect) OVERRIDE { | 538 bool* defer_redirect) OVERRIDE { |
531 DCHECK(request->status().is_success()); | 539 DCHECK(request->status().is_success()); |
532 ResourceResponseInfo info; | 540 ResourceResponseInfo info; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
610 uint64 amt_since_last = position - last_upload_position_; | 618 uint64 amt_since_last = position - last_upload_position_; |
611 base::TimeDelta time_since_last = base::TimeTicks::Now() - | 619 base::TimeDelta time_since_last = base::TimeTicks::Now() - |
612 last_upload_ticks_; | 620 last_upload_ticks_; |
613 | 621 |
614 bool is_finished = (size == position); | 622 bool is_finished = (size == position); |
615 bool enough_new_progress = (amt_since_last > (size / | 623 bool enough_new_progress = (amt_since_last > (size / |
616 kHalfPercentIncrements)); | 624 kHalfPercentIncrements)); |
617 bool too_much_time_passed = time_since_last > kOneSecond; | 625 bool too_much_time_passed = time_since_last > kOneSecond; |
618 | 626 |
619 if (is_finished || enough_new_progress || too_much_time_passed) { | 627 if (is_finished || enough_new_progress || too_much_time_passed) { |
620 owner_loop_->PostTask( | 628 owner_loop_->PostTaskAndReply( |
621 FROM_HERE, | 629 FROM_HERE, |
622 base::Bind(&RequestProxy::NotifyUploadProgress, this, position, | 630 base::Bind(&RequestProxy::NotifyUploadProgress, this, position, size), |
623 size)); | 631 base::Bind(&RequestProxy::DoNothing, this)); |
624 last_upload_ticks_ = base::TimeTicks::Now(); | 632 last_upload_ticks_ = base::TimeTicks::Now(); |
625 last_upload_position_ = position; | 633 last_upload_position_ = position; |
626 } | 634 } |
627 } | 635 } |
628 | 636 |
629 void PopulateResponseInfo(net::URLRequest* request, | 637 void PopulateResponseInfo(net::URLRequest* request, |
630 ResourceResponseInfo* info) const { | 638 ResourceResponseInfo* info) const { |
631 info->request_time = request->request_time(); | 639 info->request_time = request->request_time(); |
632 info->response_time = request->response_time(); | 640 info->response_time = request->response_time(); |
633 info->headers = request->response_headers(); | 641 info->headers = request->response_headers(); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
724 bool download_to_file_; | 732 bool download_to_file_; |
725 net::FileStream file_stream_; | 733 net::FileStream file_stream_; |
726 scoped_refptr<ShareableFileReference> downloaded_file_; | 734 scoped_refptr<ShareableFileReference> downloaded_file_; |
727 | 735 |
728 // Size of our async IO data buffers | 736 // Size of our async IO data buffers |
729 static const int kDataSize = 16*1024; | 737 static const int kDataSize = 16*1024; |
730 | 738 |
731 // read buffer for async IO | 739 // read buffer for async IO |
732 scoped_refptr<net::IOBuffer> buf_; | 740 scoped_refptr<net::IOBuffer> buf_; |
733 | 741 |
734 MessageLoop* owner_loop_; | 742 scoped_refptr<base::MessageLoopProxy> owner_loop_; |
735 | 743 |
736 // This is our peer in WebKit (implemented as ResourceHandleInternal). We do | 744 // This is our peer in WebKit (implemented as ResourceHandleInternal). We do |
737 // not manage its lifetime, and we may only access it from the owner's | 745 // not manage its lifetime, and we may only access it from the owner's |
738 // message loop (owner_loop_). | 746 // message loop (owner_loop_). |
739 ResourceLoaderBridge::Peer* peer_; | 747 ResourceLoaderBridge::Peer* peer_; |
740 | 748 |
741 // Timer used to pull upload progress info. | 749 // Timer used to pull upload progress info. |
742 base::RepeatingTimer<RequestProxy> upload_progress_timer_; | 750 base::RepeatingTimer<RequestProxy> upload_progress_timer_; |
743 | 751 |
744 // Info used to determine whether or not to send an upload progress update. | 752 // Info used to determine whether or not to send an upload progress update. |
745 uint64 last_upload_position_; | 753 uint64 last_upload_position_; |
746 base::TimeTicks last_upload_ticks_; | 754 base::TimeTicks last_upload_ticks_; |
747 | 755 |
748 // Save the real FILE URL prefix for the FILE URL which converts to HTTP URL. | 756 // Save the real FILE URL prefix for the FILE URL which converts to HTTP URL. |
749 std::string file_url_prefix_; | 757 std::string file_url_prefix_; |
750 // Save a failed file request status to pass it to webkit. | 758 // Save a failed file request status to pass it to webkit. |
751 scoped_ptr<net::URLRequestStatus> failed_file_request_status_; | 759 scoped_ptr<net::URLRequestStatus> failed_file_request_status_; |
760 | |
761 private: | |
762 // Helper used to extend the lifetime of |this| to ensure deletion on the IO | |
763 // thread. | |
764 void DoNothing() {} | |
752 }; | 765 }; |
753 | 766 |
754 //----------------------------------------------------------------------------- | 767 //----------------------------------------------------------------------------- |
755 | 768 |
756 class SyncRequestProxy : public RequestProxy { | 769 class SyncRequestProxy : public RequestProxy { |
757 public: | 770 public: |
758 explicit SyncRequestProxy(ResourceLoaderBridge::SyncLoadResponse* result) | 771 explicit SyncRequestProxy(ResourceLoaderBridge::SyncLoadResponse* result) |
759 : result_(result), event_(true, false) { | 772 : result_(result), event_(true, false) { |
760 } | 773 } |
761 | 774 |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1100 (http_prefix.SchemeIs("http") || http_prefix.SchemeIs("https"))); | 1113 (http_prefix.SchemeIs("http") || http_prefix.SchemeIs("https"))); |
1101 g_file_over_http_params = new FileOverHTTPParams(file_path_template, | 1114 g_file_over_http_params = new FileOverHTTPParams(file_path_template, |
1102 http_prefix); | 1115 http_prefix); |
1103 } | 1116 } |
1104 | 1117 |
1105 // static | 1118 // static |
1106 webkit_glue::ResourceLoaderBridge* SimpleResourceLoaderBridge::Create( | 1119 webkit_glue::ResourceLoaderBridge* SimpleResourceLoaderBridge::Create( |
1107 const webkit_glue::ResourceLoaderBridge::RequestInfo& request_info) { | 1120 const webkit_glue::ResourceLoaderBridge::RequestInfo& request_info) { |
1108 return new ResourceLoaderBridgeImpl(request_info); | 1121 return new ResourceLoaderBridgeImpl(request_info); |
1109 } | 1122 } |
OLD | NEW |