| 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 "content/browser/loader/throttling_resource_handler.h" | 5 #include "content/browser/loader/throttling_resource_handler.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "content/browser/loader/resource_controller.h" | 9 #include "content/browser/loader/resource_controller.h" |
| 10 #include "content/public/common/resource_response.h" | 10 #include "content/public/common/resource_response.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 throttles_[i]->set_delegate(this); | 25 throttles_[i]->set_delegate(this); |
| 26 // Throttles must have a name, as otherwise, bugs where a throttle fails | 26 // Throttles must have a name, as otherwise, bugs where a throttle fails |
| 27 // to resume a request can be very difficult to debug. | 27 // to resume a request can be very difficult to debug. |
| 28 DCHECK(throttles_[i]->GetNameForLogging()); | 28 DCHECK(throttles_[i]->GetNameForLogging()); |
| 29 } | 29 } |
| 30 } | 30 } |
| 31 | 31 |
| 32 ThrottlingResourceHandler::~ThrottlingResourceHandler() { | 32 ThrottlingResourceHandler::~ThrottlingResourceHandler() { |
| 33 } | 33 } |
| 34 | 34 |
| 35 bool ThrottlingResourceHandler::OnRequestRedirected( | 35 void ThrottlingResourceHandler::OnRequestRedirected( |
| 36 const net::RedirectInfo& redirect_info, | 36 const net::RedirectInfo& redirect_info, |
| 37 ResourceResponse* response, | 37 ResourceResponse* response, |
| 38 bool* defer) { | 38 std::unique_ptr<ResourceController> controller) { |
| 39 DCHECK(!has_controller()); |
| 39 DCHECK(!cancelled_by_resource_throttle_); | 40 DCHECK(!cancelled_by_resource_throttle_); |
| 40 DCHECK(!*defer); | |
| 41 | 41 |
| 42 set_controller(std::move(controller)); |
| 42 while (next_index_ < throttles_.size()) { | 43 while (next_index_ < throttles_.size()) { |
| 43 int index = next_index_; | 44 int index = next_index_; |
| 44 throttles_[index]->WillRedirectRequest(redirect_info, defer); | 45 bool defer = false; |
| 46 throttles_[index]->WillRedirectRequest(redirect_info, &defer); |
| 45 next_index_++; | 47 next_index_++; |
| 46 if (cancelled_by_resource_throttle_) | 48 if (cancelled_by_resource_throttle_) |
| 47 return false; | 49 return; |
| 48 if (*defer) { | 50 |
| 51 if (defer) { |
| 49 OnRequestDeferred(index); | 52 OnRequestDeferred(index); |
| 50 deferred_stage_ = DEFERRED_REDIRECT; | 53 deferred_stage_ = DEFERRED_REDIRECT; |
| 51 deferred_redirect_ = redirect_info; | 54 deferred_redirect_ = redirect_info; |
| 52 deferred_response_ = response; | 55 deferred_response_ = response; |
| 53 return true; // Do not cancel. | 56 return; |
| 54 } | 57 } |
| 55 } | 58 } |
| 56 | 59 |
| 57 next_index_ = 0; // Reset for next time. | 60 next_index_ = 0; // Reset for next time. |
| 58 | 61 |
| 59 return next_handler_->OnRequestRedirected(redirect_info, response, defer); | 62 next_handler_->OnRequestRedirected(redirect_info, response, TakeController()); |
| 60 } | 63 } |
| 61 | 64 |
| 62 bool ThrottlingResourceHandler::OnWillStart(const GURL& url, bool* defer) { | 65 void ThrottlingResourceHandler::OnWillStart( |
| 66 const GURL& url, |
| 67 std::unique_ptr<ResourceController> controller) { |
| 63 DCHECK(!cancelled_by_resource_throttle_); | 68 DCHECK(!cancelled_by_resource_throttle_); |
| 64 DCHECK(!*defer); | 69 DCHECK(!has_controller()); |
| 65 | 70 |
| 71 set_controller(std::move(controller)); |
| 66 while (next_index_ < throttles_.size()) { | 72 while (next_index_ < throttles_.size()) { |
| 67 int index = next_index_; | 73 int index = next_index_; |
| 68 throttles_[index]->WillStartRequest(defer); | 74 bool defer = false; |
| 75 throttles_[index]->WillStartRequest(&defer); |
| 69 next_index_++; | 76 next_index_++; |
| 70 if (cancelled_by_resource_throttle_) | 77 if (cancelled_by_resource_throttle_) |
| 71 return false; | 78 return; |
| 72 if (*defer) { | 79 if (defer) { |
| 73 OnRequestDeferred(index); | 80 OnRequestDeferred(index); |
| 74 deferred_stage_ = DEFERRED_START; | 81 deferred_stage_ = DEFERRED_START; |
| 75 deferred_url_ = url; | 82 deferred_url_ = url; |
| 76 return true; // Do not cancel. | 83 return; |
| 77 } | 84 } |
| 78 } | 85 } |
| 79 | 86 |
| 80 next_index_ = 0; // Reset for next time. | 87 next_index_ = 0; // Reset for next time. |
| 81 | 88 |
| 82 return next_handler_->OnWillStart(url, defer); | 89 return next_handler_->OnWillStart(url, TakeController()); |
| 83 } | 90 } |
| 84 | 91 |
| 85 bool ThrottlingResourceHandler::OnResponseStarted(ResourceResponse* response, | 92 void ThrottlingResourceHandler::OnResponseStarted( |
| 86 bool* defer) { | 93 ResourceResponse* response, |
| 94 std::unique_ptr<ResourceController> controller) { |
| 87 DCHECK(!cancelled_by_resource_throttle_); | 95 DCHECK(!cancelled_by_resource_throttle_); |
| 88 DCHECK(!*defer); | 96 DCHECK(!has_controller()); |
| 89 | 97 |
| 98 set_controller(std::move(controller)); |
| 90 while (next_index_ < throttles_.size()) { | 99 while (next_index_ < throttles_.size()) { |
| 91 int index = next_index_; | 100 int index = next_index_; |
| 92 throttles_[index]->WillProcessResponse(defer); | 101 bool defer = false; |
| 102 throttles_[index]->WillProcessResponse(&defer); |
| 93 next_index_++; | 103 next_index_++; |
| 94 if (cancelled_by_resource_throttle_) | 104 if (cancelled_by_resource_throttle_) |
| 95 return false; | 105 return; |
| 96 if (*defer) { | 106 if (defer) { |
| 97 OnRequestDeferred(index); | 107 OnRequestDeferred(index); |
| 98 deferred_stage_ = DEFERRED_RESPONSE; | 108 deferred_stage_ = DEFERRED_RESPONSE; |
| 99 deferred_response_ = response; | 109 deferred_response_ = response; |
| 100 return true; // Do not cancel. | 110 return; |
| 101 } | 111 } |
| 102 } | 112 } |
| 103 | 113 |
| 104 next_index_ = 0; // Reset for next time. | 114 next_index_ = 0; // Reset for next time. |
| 105 | 115 |
| 106 return next_handler_->OnResponseStarted(response, defer); | 116 return next_handler_->OnResponseStarted(response, TakeController()); |
| 107 } | 117 } |
| 108 | 118 |
| 109 void ThrottlingResourceHandler::Cancel() { | 119 void ThrottlingResourceHandler::Cancel() { |
| 110 cancelled_by_resource_throttle_ = true; | 120 CancelWithError(net::ERR_ABORTED); |
| 111 controller()->Cancel(); | |
| 112 } | 121 } |
| 113 | 122 |
| 114 void ThrottlingResourceHandler::CancelAndIgnore() { | 123 void ThrottlingResourceHandler::CancelAndIgnore() { |
| 124 if (!has_controller()) { |
| 125 OutOfBandCancel(net::ERR_ABORTED, false); |
| 126 return; |
| 127 } |
| 115 cancelled_by_resource_throttle_ = true; | 128 cancelled_by_resource_throttle_ = true; |
| 116 controller()->CancelAndIgnore(); | 129 ResourceHandler::CancelAndIgnore(); |
| 117 } | 130 } |
| 118 | 131 |
| 119 void ThrottlingResourceHandler::CancelWithError(int error_code) { | 132 void ThrottlingResourceHandler::CancelWithError(int error_code) { |
| 133 if (!has_controller()) { |
| 134 OutOfBandCancel(error_code, false); |
| 135 return; |
| 136 } |
| 120 cancelled_by_resource_throttle_ = true; | 137 cancelled_by_resource_throttle_ = true; |
| 121 controller()->CancelWithError(error_code); | 138 ResourceHandler::CancelWithError(error_code); |
| 122 } | 139 } |
| 123 | 140 |
| 124 void ThrottlingResourceHandler::Resume() { | 141 void ThrottlingResourceHandler::Resume() { |
| 125 // Throttles expect to be able to cancel requests out-of-band, so just do | 142 // Throttles expect to be able to cancel requests out-of-band, so just do |
| 126 // nothing if one request resumes after another cancels. Can't even recognize | 143 // nothing if one request resumes after another cancels. Can't even recognize |
| 127 // out-of-band cancels and for synchronous teardown, since don't know if the | 144 // out-of-band cancels and for synchronous teardown, since don't know if the |
| 128 // currently active throttle called Cancel() or if it was another one. | 145 // currently active throttle called Cancel() or if it was another one. |
| 129 if (cancelled_by_resource_throttle_) | 146 if (cancelled_by_resource_throttle_) |
| 130 return; | 147 return; |
| 131 | 148 |
| 149 DCHECK(has_controller()); |
| 150 |
| 132 DeferredStage last_deferred_stage = deferred_stage_; | 151 DeferredStage last_deferred_stage = deferred_stage_; |
| 133 deferred_stage_ = DEFERRED_NONE; | 152 deferred_stage_ = DEFERRED_NONE; |
| 134 // Clear information about the throttle that delayed the request. | 153 // Clear information about the throttle that delayed the request. |
| 135 request()->LogUnblocked(); | 154 request()->LogUnblocked(); |
| 136 switch (last_deferred_stage) { | 155 switch (last_deferred_stage) { |
| 137 case DEFERRED_NONE: | 156 case DEFERRED_NONE: |
| 138 NOTREACHED(); | 157 NOTREACHED(); |
| 139 break; | 158 break; |
| 140 case DEFERRED_START: | 159 case DEFERRED_START: |
| 141 ResumeStart(); | 160 ResumeStart(); |
| 142 break; | 161 break; |
| 143 case DEFERRED_REDIRECT: | 162 case DEFERRED_REDIRECT: |
| 144 ResumeRedirect(); | 163 ResumeRedirect(); |
| 145 break; | 164 break; |
| 146 case DEFERRED_RESPONSE: | 165 case DEFERRED_RESPONSE: |
| 147 ResumeResponse(); | 166 ResumeResponse(); |
| 148 break; | 167 break; |
| 149 } | 168 } |
| 150 } | 169 } |
| 151 | 170 |
| 152 void ThrottlingResourceHandler::ResumeStart() { | 171 void ThrottlingResourceHandler::ResumeStart() { |
| 153 DCHECK(!cancelled_by_resource_throttle_); | 172 DCHECK(!cancelled_by_resource_throttle_); |
| 173 DCHECK(has_controller()); |
| 154 | 174 |
| 155 GURL url = deferred_url_; | 175 GURL url = deferred_url_; |
| 156 deferred_url_ = GURL(); | 176 deferred_url_ = GURL(); |
| 157 | 177 |
| 158 bool defer = false; | 178 OnWillStart(url, TakeController()); |
| 159 if (!OnWillStart(url, &defer)) { | |
| 160 controller()->Cancel(); | |
| 161 } else if (!defer) { | |
| 162 controller()->Resume(); | |
| 163 } | |
| 164 } | 179 } |
| 165 | 180 |
| 166 void ThrottlingResourceHandler::ResumeRedirect() { | 181 void ThrottlingResourceHandler::ResumeRedirect() { |
| 167 DCHECK(!cancelled_by_resource_throttle_); | 182 DCHECK(!cancelled_by_resource_throttle_); |
| 183 DCHECK(has_controller()); |
| 168 | 184 |
| 169 net::RedirectInfo redirect_info = deferred_redirect_; | 185 net::RedirectInfo redirect_info = deferred_redirect_; |
| 170 deferred_redirect_ = net::RedirectInfo(); | 186 deferred_redirect_ = net::RedirectInfo(); |
| 171 scoped_refptr<ResourceResponse> response; | 187 scoped_refptr<ResourceResponse> response; |
| 172 deferred_response_.swap(response); | 188 deferred_response_.swap(response); |
| 173 | 189 |
| 174 bool defer = false; | 190 OnRequestRedirected(redirect_info, response.get(), TakeController()); |
| 175 if (!OnRequestRedirected(redirect_info, response.get(), &defer)) { | |
| 176 controller()->Cancel(); | |
| 177 } else if (!defer) { | |
| 178 controller()->Resume(); | |
| 179 } | |
| 180 } | 191 } |
| 181 | 192 |
| 182 void ThrottlingResourceHandler::ResumeResponse() { | 193 void ThrottlingResourceHandler::ResumeResponse() { |
| 183 DCHECK(!cancelled_by_resource_throttle_); | 194 DCHECK(!cancelled_by_resource_throttle_); |
| 195 DCHECK(has_controller()); |
| 184 | 196 |
| 185 scoped_refptr<ResourceResponse> response; | 197 scoped_refptr<ResourceResponse> response; |
| 186 deferred_response_.swap(response); | 198 deferred_response_.swap(response); |
| 187 | 199 |
| 188 bool defer = false; | 200 OnResponseStarted(response.get(), TakeController()); |
| 189 if (!OnResponseStarted(response.get(), &defer)) { | |
| 190 controller()->Cancel(); | |
| 191 } else if (!defer) { | |
| 192 controller()->Resume(); | |
| 193 } | |
| 194 } | 201 } |
| 195 | 202 |
| 196 void ThrottlingResourceHandler::OnRequestDeferred(int throttle_index) { | 203 void ThrottlingResourceHandler::OnRequestDeferred(int throttle_index) { |
| 197 request()->LogBlockedBy(throttles_[throttle_index]->GetNameForLogging()); | 204 request()->LogBlockedBy(throttles_[throttle_index]->GetNameForLogging()); |
| 198 } | 205 } |
| 199 | 206 |
| 200 } // namespace content | 207 } // namespace content |
| OLD | NEW |