| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/renderer_host/offline_resource_handler.h" | 5 #include "chrome/browser/renderer_host/offline_resource_handler.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 render_view_id_(route_id), | 38 render_view_id_(route_id), |
| 39 rdh_(rdh), | 39 rdh_(rdh), |
| 40 request_(request), | 40 request_(request), |
| 41 appcache_service_(appcache_service), | 41 appcache_service_(appcache_service), |
| 42 deferred_request_id_(-1) { | 42 deferred_request_id_(-1) { |
| 43 DCHECK(appcache_service_); | 43 DCHECK(appcache_service_); |
| 44 } | 44 } |
| 45 | 45 |
| 46 OfflineResourceHandler::~OfflineResourceHandler() { | 46 OfflineResourceHandler::~OfflineResourceHandler() { |
| 47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 48 DCHECK(!appcache_completion_callback_.get()); | 48 DCHECK(appcache_completion_callback_.IsCancelled()); |
| 49 } | 49 } |
| 50 | 50 |
| 51 bool OfflineResourceHandler::OnUploadProgress(int request_id, | 51 bool OfflineResourceHandler::OnUploadProgress(int request_id, |
| 52 uint64 position, | 52 uint64 position, |
| 53 uint64 size) { | 53 uint64 size) { |
| 54 return next_handler_->OnUploadProgress(request_id, position, size); | 54 return next_handler_->OnUploadProgress(request_id, position, size); |
| 55 } | 55 } |
| 56 | 56 |
| 57 bool OfflineResourceHandler::OnRequestRedirected( | 57 bool OfflineResourceHandler::OnRequestRedirected( |
| 58 int request_id, | 58 int request_id, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 70 } | 70 } |
| 71 | 71 |
| 72 bool OfflineResourceHandler::OnResponseCompleted( | 72 bool OfflineResourceHandler::OnResponseCompleted( |
| 73 int request_id, | 73 int request_id, |
| 74 const net::URLRequestStatus& status, | 74 const net::URLRequestStatus& status, |
| 75 const std::string& security_info) { | 75 const std::string& security_info) { |
| 76 return next_handler_->OnResponseCompleted(request_id, status, security_info); | 76 return next_handler_->OnResponseCompleted(request_id, status, security_info); |
| 77 } | 77 } |
| 78 | 78 |
| 79 void OfflineResourceHandler::OnRequestClosed() { | 79 void OfflineResourceHandler::OnRequestClosed() { |
| 80 if (appcache_completion_callback_) { | 80 if (!appcache_completion_callback_.IsCancelled()) |
| 81 appcache_completion_callback_->Cancel(); | 81 appcache_completion_callback_.Cancel(); |
| 82 appcache_completion_callback_.release(); | 82 |
| 83 Release(); // Balanced with OnWillStart | |
| 84 } | |
| 85 next_handler_->OnRequestClosed(); | 83 next_handler_->OnRequestClosed(); |
| 86 } | 84 } |
| 87 | 85 |
| 88 void OfflineResourceHandler::OnCanHandleOfflineComplete(int rv) { | 86 void OfflineResourceHandler::OnCanHandleOfflineComplete(int rv) { |
| 89 CHECK(appcache_completion_callback_); | 87 // Cancel() to break the circular reference cycle. |
| 90 appcache_completion_callback_ = NULL; | 88 appcache_completion_callback_.Cancel(); |
| 89 |
| 91 if (deferred_request_id_ == -1) { | 90 if (deferred_request_id_ == -1) { |
| 92 LOG(WARNING) << "OnCanHandleOfflineComplete called after completion: " | 91 DLOG(FATAL) << "OnCanHandleOfflineComplete called after completion: " |
| 93 << " this=" << this; | 92 << " this=" << this; |
| 94 NOTREACHED(); | |
| 95 return; | 93 return; |
| 96 } | 94 } |
| 95 |
| 97 if (rv == net::OK) { | 96 if (rv == net::OK) { |
| 98 Resume(); | 97 Resume(); |
| 99 Release(); // Balanced with OnWillStart | |
| 100 } else { | 98 } else { |
| 101 BrowserThread::PostTask( | 99 BrowserThread::PostTask( |
| 102 BrowserThread::UI, FROM_HERE, | 100 BrowserThread::UI, FROM_HERE, |
| 103 base::Bind(&OfflineResourceHandler::ShowOfflinePage, this)); | 101 base::Bind(&OfflineResourceHandler::ShowOfflinePage, this)); |
| 104 } | 102 } |
| 105 } | 103 } |
| 106 | 104 |
| 107 bool OfflineResourceHandler::OnWillStart(int request_id, | 105 bool OfflineResourceHandler::OnWillStart(int request_id, |
| 108 const GURL& url, | 106 const GURL& url, |
| 109 bool* defer) { | 107 bool* defer) { |
| 110 if (ShouldShowOfflinePage(url)) { | 108 if (!ShouldShowOfflinePage(url)) |
| 111 deferred_request_id_ = request_id; | 109 return next_handler_->OnWillStart(request_id, url, defer); |
| 112 deferred_url_ = url; | |
| 113 DVLOG(1) << "OnWillStart: this=" << this << ", request id=" << request_id | |
| 114 << ", url=" << url; | |
| 115 AddRef(); // Balanced with OnCanHandleOfflineComplete | |
| 116 DCHECK(!appcache_completion_callback_); | |
| 117 appcache_completion_callback_ = | |
| 118 new net::CancelableOldCompletionCallback<OfflineResourceHandler>( | |
| 119 this, &OfflineResourceHandler::OnCanHandleOfflineComplete); | |
| 120 appcache_service_->CanHandleMainResourceOffline( | |
| 121 url, request_->first_party_for_cookies(), | |
| 122 appcache_completion_callback_); | |
| 123 | 110 |
| 124 *defer = true; | 111 deferred_request_id_ = request_id; |
| 125 return true; | 112 deferred_url_ = url; |
| 126 } | 113 DVLOG(1) << "OnWillStart: this=" << this << ", request id=" << request_id |
| 127 return next_handler_->OnWillStart(request_id, url, defer); | 114 << ", url=" << url; |
| 115 |
| 116 DCHECK(appcache_completion_callback_.IsCancelled()); |
| 117 |
| 118 // |appcache_completion_callback_| holds a reference to |this|, so there is a |
| 119 // circular reference; however, either |
| 120 // OfflineResourceHandler::OnCanHandleOfflineComplete cancels the callback |
| 121 // (thus dropping the reference), or CanHandleMainResourceOffline calls the |
| 122 // callback which Resets it. |
| 123 appcache_completion_callback_.Reset( |
| 124 base::Bind(&OfflineResourceHandler::OnCanHandleOfflineComplete, this)); |
| 125 appcache_service_->CanHandleMainResourceOffline( |
| 126 url, request_->first_party_for_cookies(), |
| 127 appcache_completion_callback_.callback()); |
| 128 |
| 129 *defer = true; |
| 130 return true; |
| 128 } | 131 } |
| 129 | 132 |
| 130 // We'll let the original event handler provide a buffer, and reuse it for | 133 // We'll let the original event handler provide a buffer, and reuse it for |
| 131 // subsequent reads until we're done buffering. | 134 // subsequent reads until we're done buffering. |
| 132 bool OfflineResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, | 135 bool OfflineResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, |
| 133 int* buf_size, int min_size) { | 136 int* buf_size, int min_size) { |
| 134 return next_handler_->OnWillRead(request_id, buf, buf_size, min_size); | 137 return next_handler_->OnWillRead(request_id, buf, buf_size, min_size); |
| 135 } | 138 } |
| 136 | 139 |
| 137 bool OfflineResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { | 140 bool OfflineResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 154 NOTREACHED(); | 157 NOTREACHED(); |
| 155 return; | 158 return; |
| 156 } | 159 } |
| 157 if (proceed) { | 160 if (proceed) { |
| 158 Resume(); | 161 Resume(); |
| 159 } else { | 162 } else { |
| 160 int request_id = deferred_request_id_; | 163 int request_id = deferred_request_id_; |
| 161 ClearRequestInfo(); | 164 ClearRequestInfo(); |
| 162 rdh_->CancelRequest(process_host_id_, request_id, false); | 165 rdh_->CancelRequest(process_host_id_, request_id, false); |
| 163 } | 166 } |
| 164 Release(); // Balanced with OnWillStart | |
| 165 } | 167 } |
| 166 | 168 |
| 167 void OfflineResourceHandler::ClearRequestInfo() { | 169 void OfflineResourceHandler::ClearRequestInfo() { |
| 168 deferred_url_ = GURL(); | 170 deferred_url_ = GURL(); |
| 169 deferred_request_id_ = -1; | 171 deferred_request_id_ = -1; |
| 170 } | 172 } |
| 171 | 173 |
| 172 bool OfflineResourceHandler::IsRemote(const GURL& url) const { | 174 bool OfflineResourceHandler::IsRemote(const GURL& url) const { |
| 173 return url.SchemeIs(chrome::kFtpScheme) || | 175 return url.SchemeIs(chrome::kFtpScheme) || |
| 174 url.SchemeIs(chrome::kHttpScheme) || | 176 url.SchemeIs(chrome::kHttpScheme) || |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 TabContents* tab_contents = render_view_host ? | 209 TabContents* tab_contents = render_view_host ? |
| 208 render_view_host->delegate()->GetAsTabContents() : NULL; | 210 render_view_host->delegate()->GetAsTabContents() : NULL; |
| 209 // There is a chance that the tab closed after we decided to show | 211 // There is a chance that the tab closed after we decided to show |
| 210 // the offline page on the IO thread and before we actually show the | 212 // the offline page on the IO thread and before we actually show the |
| 211 // offline page here on the UI thread. | 213 // offline page here on the UI thread. |
| 212 if (tab_contents) | 214 if (tab_contents) |
| 213 (new chromeos::OfflineLoadPage(tab_contents, deferred_url_, this))-> | 215 (new chromeos::OfflineLoadPage(tab_contents, deferred_url_, this))-> |
| 214 Show(); | 216 Show(); |
| 215 } | 217 } |
| 216 } | 218 } |
| OLD | NEW |