| 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 "content/browser/loader/detachable_resource_handler.h" | 5 #include "content/browser/loader/detachable_resource_handler.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 namespace content { | 22 namespace content { |
| 23 | 23 |
| 24 DetachableResourceHandler::DetachableResourceHandler( | 24 DetachableResourceHandler::DetachableResourceHandler( |
| 25 net::URLRequest* request, | 25 net::URLRequest* request, |
| 26 base::TimeDelta cancel_delay, | 26 base::TimeDelta cancel_delay, |
| 27 std::unique_ptr<ResourceHandler> next_handler) | 27 std::unique_ptr<ResourceHandler> next_handler) |
| 28 : ResourceHandler(request), | 28 : ResourceHandler(request), |
| 29 next_handler_(std::move(next_handler)), | 29 next_handler_(std::move(next_handler)), |
| 30 cancel_delay_(cancel_delay), | 30 cancel_delay_(cancel_delay), |
| 31 is_deferred_(false), | 31 is_deferred_(false), |
| 32 is_finished_(false) { | 32 is_finished_(false), |
| 33 is_canceled_(false) { |
| 33 GetRequestInfo()->set_detachable_handler(this); | 34 GetRequestInfo()->set_detachable_handler(this); |
| 34 } | 35 } |
| 35 | 36 |
| 36 DetachableResourceHandler::~DetachableResourceHandler() { | 37 DetachableResourceHandler::~DetachableResourceHandler() { |
| 37 // Cleanup back-pointer stored on the request info. | 38 // Cleanup back-pointer stored on the request info. |
| 38 GetRequestInfo()->set_detachable_handler(NULL); | 39 GetRequestInfo()->set_detachable_handler(NULL); |
| 39 } | 40 } |
| 40 | 41 |
| 41 void DetachableResourceHandler::Detach() { | 42 void DetachableResourceHandler::Detach() { |
| 42 if (is_detached()) | 43 if (is_detached()) |
| 43 return; | 44 return; |
| 44 | 45 |
| 45 if (!is_finished_) { | 46 if (!is_finished_) { |
| 46 // Simulate a cancel on the next handler before destroying it. | 47 // Simulate a cancel on the next handler before destroying it. |
| 47 net::URLRequestStatus status(net::URLRequestStatus::CANCELED, | 48 net::URLRequestStatus status(net::URLRequestStatus::CANCELED, |
| 48 net::ERR_ABORTED); | 49 net::ERR_ABORTED); |
| 49 bool defer_ignored = false; | 50 bool defer_or_cancel_ignored = false; |
| 50 next_handler_->OnResponseCompleted(status, &defer_ignored); | 51 next_handler_->OnResponseCompleted(status, &defer_or_cancel_ignored); |
| 51 DCHECK(!defer_ignored); | 52 DCHECK(!defer_or_cancel_ignored); |
| 52 // If |next_handler_| were to defer its shutdown in OnResponseCompleted, | 53 // If |next_handler_| were to defer its shutdown in OnResponseCompleted, |
| 53 // this would destroy it anyway. Fortunately, AsyncResourceHandler never | 54 // this would destroy it anyway. Fortunately, AsyncResourceHandler never |
| 54 // does this anyway, so DCHECK it. MimeTypeResourceHandler and RVH shutdown | 55 // does this anyway, so DCHECK it. MimeTypeResourceHandler and RVH shutdown |
| 55 // already ignore deferred ResourceHandler shutdown, but | 56 // already ignore deferred ResourceHandler shutdown, but |
| 56 // DetachableResourceHandler and the detach-on-renderer-cancel logic | 57 // DetachableResourceHandler and the detach-on-renderer-cancel logic |
| 57 // introduces a case where this occurs when the renderer cancels a resource. | 58 // introduces a case where this occurs when the renderer cancels a resource. |
| 58 } | 59 } |
| 59 // A OnWillRead / OnReadCompleted pair may still be in progress, but | 60 // A OnWillRead / OnReadCompleted pair may still be in progress, but |
| 60 // OnWillRead passes back a scoped_refptr, so downstream handler's buffer will | 61 // OnWillRead passes back a scoped_refptr, so downstream handler's buffer will |
| 61 // survive long enough to complete that read. From there, future reads will | 62 // survive long enough to complete that read. From there, future reads will |
| (...skipping 20 matching lines...) Expand all Loading... |
| 82 | 83 |
| 83 void DetachableResourceHandler::SetController(ResourceController* controller) { | 84 void DetachableResourceHandler::SetController(ResourceController* controller) { |
| 84 ResourceHandler::SetController(controller); | 85 ResourceHandler::SetController(controller); |
| 85 | 86 |
| 86 // Intercept the ResourceController for downstream handlers to keep track of | 87 // Intercept the ResourceController for downstream handlers to keep track of |
| 87 // whether the request is deferred. | 88 // whether the request is deferred. |
| 88 if (next_handler_) | 89 if (next_handler_) |
| 89 next_handler_->SetController(this); | 90 next_handler_->SetController(this); |
| 90 } | 91 } |
| 91 | 92 |
| 92 bool DetachableResourceHandler::OnRequestRedirected( | 93 void DetachableResourceHandler::OnRequestRedirected( |
| 93 const net::RedirectInfo& redirect_info, | 94 const net::RedirectInfo& redirect_info, |
| 94 ResourceResponse* response, | 95 ResourceResponse* response, |
| 95 bool* defer) { | 96 bool* defer_or_cancel) { |
| 96 DCHECK(!is_deferred_); | 97 DCHECK(!is_deferred_); |
| 97 | 98 |
| 98 if (!next_handler_) | 99 if (!next_handler_) |
| 99 return true; | 100 return; |
| 100 | 101 |
| 101 bool ret = next_handler_->OnRequestRedirected( | 102 bool is_deferred_or_canceled = false; |
| 102 redirect_info, response, &is_deferred_); | 103 next_handler_->OnRequestRedirected(redirect_info, response, |
| 103 *defer = is_deferred_; | 104 &is_deferred_or_canceled); |
| 104 return ret; | 105 *defer_or_cancel = is_deferred_or_canceled; |
| 106 if (is_deferred_or_canceled && !is_canceled_) |
| 107 is_deferred_ = true; |
| 105 } | 108 } |
| 106 | 109 |
| 107 bool DetachableResourceHandler::OnResponseStarted(ResourceResponse* response, | 110 void DetachableResourceHandler::OnResponseStarted(ResourceResponse* response, |
| 108 bool* defer) { | 111 bool* defer_or_cancel) { |
| 109 DCHECK(!is_deferred_); | 112 DCHECK(!is_deferred_); |
| 110 | 113 |
| 111 if (!next_handler_) | 114 if (!next_handler_) |
| 112 return true; | 115 return; |
| 113 | 116 |
| 114 bool ret = | 117 bool is_deferred_or_canceled = false; |
| 115 next_handler_->OnResponseStarted(response, &is_deferred_); | 118 next_handler_->OnResponseStarted(response, &is_deferred_or_canceled); |
| 116 *defer = is_deferred_; | 119 *defer_or_cancel = is_deferred_or_canceled; |
| 117 return ret; | 120 if (is_deferred_or_canceled && !is_canceled_) |
| 121 is_deferred_ = true; |
| 118 } | 122 } |
| 119 | 123 |
| 120 bool DetachableResourceHandler::OnWillStart(const GURL& url, bool* defer) { | 124 void DetachableResourceHandler::OnWillStart(const GURL& url, |
| 125 bool* defer_or_cancel) { |
| 121 DCHECK(!is_deferred_); | 126 DCHECK(!is_deferred_); |
| 122 | 127 |
| 123 if (!next_handler_) | 128 if (!next_handler_) |
| 124 return true; | 129 return; |
| 125 | 130 |
| 126 bool ret = next_handler_->OnWillStart(url, &is_deferred_); | 131 bool is_deferred_or_canceled = false; |
| 127 *defer = is_deferred_; | 132 next_handler_->OnWillStart(url, &is_deferred_or_canceled); |
| 128 return ret; | 133 *defer_or_cancel = is_deferred_or_canceled; |
| 134 if (is_deferred_or_canceled && !is_canceled_) |
| 135 is_deferred_ = true; |
| 129 } | 136 } |
| 130 | 137 |
| 131 bool DetachableResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, | 138 bool DetachableResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
| 132 int* buf_size, | 139 int* buf_size, |
| 133 int min_size) { | 140 int min_size) { |
| 134 if (!next_handler_) { | 141 if (!next_handler_) { |
| 135 DCHECK_EQ(-1, min_size); | 142 DCHECK_EQ(-1, min_size); |
| 136 if (!read_buffer_.get()) | 143 if (!read_buffer_.get()) |
| 137 read_buffer_ = new net::IOBuffer(kReadBufSize); | 144 read_buffer_ = new net::IOBuffer(kReadBufSize); |
| 138 *buf = read_buffer_; | 145 *buf = read_buffer_; |
| 139 *buf_size = kReadBufSize; | 146 *buf_size = kReadBufSize; |
| 140 return true; | 147 return true; |
| 141 } | 148 } |
| 142 | 149 |
| 143 return next_handler_->OnWillRead(buf, buf_size, min_size); | 150 return next_handler_->OnWillRead(buf, buf_size, min_size); |
| 144 } | 151 } |
| 145 | 152 |
| 146 bool DetachableResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { | 153 void DetachableResourceHandler::OnReadCompleted(int bytes_read, |
| 154 bool* defer_or_cancel) { |
| 147 DCHECK(!is_deferred_); | 155 DCHECK(!is_deferred_); |
| 148 | 156 |
| 149 if (!next_handler_) | 157 if (!next_handler_) |
| 150 return true; | 158 return; |
| 151 | 159 |
| 152 bool ret = | 160 bool is_deferred_or_canceled = false; |
| 153 next_handler_->OnReadCompleted(bytes_read, &is_deferred_); | 161 next_handler_->OnReadCompleted(bytes_read, &is_deferred_or_canceled); |
| 154 *defer = is_deferred_; | 162 *defer_or_cancel = is_deferred_or_canceled; |
| 155 return ret; | 163 if (is_deferred_or_canceled && !is_canceled_) |
| 164 is_deferred_ = true; |
| 156 } | 165 } |
| 157 | 166 |
| 158 void DetachableResourceHandler::OnResponseCompleted( | 167 void DetachableResourceHandler::OnResponseCompleted( |
| 159 const net::URLRequestStatus& status, | 168 const net::URLRequestStatus& status, |
| 160 bool* defer) { | 169 bool* defer) { |
| 161 // No DCHECK(!is_deferred_) as the request may have been cancelled while | 170 // No DCHECK(!is_deferred_or_canceled_) as the request may have been cancelled |
| 171 // while |
| 162 // deferred. | 172 // deferred. |
| 163 | 173 |
| 164 if (!next_handler_) | 174 if (!next_handler_) |
| 165 return; | 175 return; |
| 166 | 176 |
| 167 is_finished_ = true; | 177 is_finished_ = true; |
| 168 | 178 |
| 169 next_handler_->OnResponseCompleted(status, &is_deferred_); | 179 next_handler_->OnResponseCompleted(status, &is_deferred_); |
| 170 *defer = is_deferred_; | 180 *defer = is_deferred_; |
| 171 } | 181 } |
| 172 | 182 |
| 173 void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) { | 183 void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) { |
| 174 if (!next_handler_) | 184 if (!next_handler_) |
| 175 return; | 185 return; |
| 176 | 186 |
| 177 next_handler_->OnDataDownloaded(bytes_downloaded); | 187 next_handler_->OnDataDownloaded(bytes_downloaded); |
| 178 } | 188 } |
| 179 | 189 |
| 180 void DetachableResourceHandler::Resume() { | 190 void DetachableResourceHandler::Resume() { |
| 181 DCHECK(is_deferred_); | 191 DCHECK(is_deferred_); |
| 182 is_deferred_ = false; | 192 is_deferred_ = false; |
| 183 controller()->Resume(); | 193 controller()->Resume(); |
| 184 } | 194 } |
| 185 | 195 |
| 186 void DetachableResourceHandler::Cancel() { | 196 void DetachableResourceHandler::Cancel() { |
| 197 is_canceled_ = true; |
| 187 controller()->Cancel(); | 198 controller()->Cancel(); |
| 188 } | 199 } |
| 189 | 200 |
| 190 void DetachableResourceHandler::CancelAndIgnore() { | 201 void DetachableResourceHandler::CancelAndIgnore() { |
| 191 controller()->CancelAndIgnore(); | 202 controller()->CancelAndIgnore(); |
| 192 } | 203 } |
| 193 | 204 |
| 194 void DetachableResourceHandler::CancelWithError(int error_code) { | 205 void DetachableResourceHandler::CancelWithError(int error_code) { |
| 195 controller()->CancelWithError(error_code); | 206 controller()->CancelWithError(error_code); |
| 196 } | 207 } |
| 197 | 208 |
| 198 } // namespace content | 209 } // namespace content |
| OLD | NEW |