Commit 5584eab1 authored by jkarlin@chromium.org's avatar jkarlin@chromium.org

Adds the new URLRequest::OnBeforeNetworkStart hook to the

ResourceThrottle so that the ResourceScheduler can eventually throttle
closer to the start of network usage.

This is the second step in the design doc:
https://docs.google.com/document/d/1TSI3jwozVB_nueWJxzi8uKbgDfsGZRZqw8tvtD-P1Iw/edit?usp=sharing

The third step is to create the new ResourceScheduler.

BUG=328741

Review URL: https://codereview.chromium.org/129173002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243994 0039d316-1c4b-4281-b951-d872f2087c98
parent aa52489e
...@@ -222,6 +222,12 @@ bool DownloadResourceHandler::OnWillStart(int request_id, ...@@ -222,6 +222,12 @@ bool DownloadResourceHandler::OnWillStart(int request_id,
return true; return true;
} }
bool DownloadResourceHandler::OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) {
return true;
}
// Create a new buffer, which will be handed to the download thread for file // Create a new buffer, which will be handed to the download thread for file
// writing and deletion. // writing and deletion.
bool DownloadResourceHandler::OnWillRead(int request_id, bool DownloadResourceHandler::OnWillRead(int request_id,
......
...@@ -64,6 +64,11 @@ class CONTENT_EXPORT DownloadResourceHandler ...@@ -64,6 +64,11 @@ class CONTENT_EXPORT DownloadResourceHandler
const GURL& url, const GURL& url,
bool* defer) OVERRIDE; bool* defer) OVERRIDE;
// Pass-through implementation.
virtual bool OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) OVERRIDE;
// Create a new buffer, which will be handed to the download thread for file // Create a new buffer, which will be handed to the download thread for file
// writing and deletion. // writing and deletion.
virtual bool OnWillRead(int request_id, virtual bool OnWillRead(int request_id,
......
...@@ -74,6 +74,12 @@ bool SaveFileResourceHandler::OnWillStart(int request_id, ...@@ -74,6 +74,12 @@ bool SaveFileResourceHandler::OnWillStart(int request_id,
return true; return true;
} }
bool SaveFileResourceHandler::OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) {
return true;
}
bool SaveFileResourceHandler::OnWillRead(int request_id, bool SaveFileResourceHandler::OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
int* buf_size, int* buf_size,
......
...@@ -45,6 +45,11 @@ class SaveFileResourceHandler : public ResourceHandler { ...@@ -45,6 +45,11 @@ class SaveFileResourceHandler : public ResourceHandler {
const GURL& url, const GURL& url,
bool* defer) OVERRIDE; bool* defer) OVERRIDE;
// Pass-through implementation.
virtual bool OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) OVERRIDE;
// Creates a new buffer, which will be handed to the download thread for file // Creates a new buffer, which will be handed to the download thread for file
// writing and deletion. // writing and deletion.
virtual bool OnWillRead(int request_id, virtual bool OnWillRead(int request_id,
......
...@@ -220,6 +220,12 @@ bool AsyncResourceHandler::OnWillStart(int request_id, ...@@ -220,6 +220,12 @@ bool AsyncResourceHandler::OnWillStart(int request_id,
return true; return true;
} }
bool AsyncResourceHandler::OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) {
return true;
}
bool AsyncResourceHandler::OnWillRead(int request_id, bool AsyncResourceHandler::OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
int* buf_size, int* buf_size,
......
...@@ -49,6 +49,9 @@ class AsyncResourceHandler : public ResourceHandler, ...@@ -49,6 +49,9 @@ class AsyncResourceHandler : public ResourceHandler,
virtual bool OnWillStart(int request_id, virtual bool OnWillStart(int request_id,
const GURL& url, const GURL& url,
bool* defer) OVERRIDE; bool* defer) OVERRIDE;
virtual bool OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) OVERRIDE;
virtual bool OnWillRead(int request_id, virtual bool OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
int* buf_size, int* buf_size,
......
...@@ -56,6 +56,12 @@ bool CertificateResourceHandler::OnWillStart(int request_id, ...@@ -56,6 +56,12 @@ bool CertificateResourceHandler::OnWillStart(int request_id,
return true; return true;
} }
bool CertificateResourceHandler::OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) {
return true;
}
bool CertificateResourceHandler::OnWillRead(int request_id, bool CertificateResourceHandler::OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
int* buf_size, int* buf_size,
......
...@@ -54,6 +54,11 @@ class CertificateResourceHandler : public ResourceHandler { ...@@ -54,6 +54,11 @@ class CertificateResourceHandler : public ResourceHandler {
const GURL& url, const GURL& url,
bool* defer) OVERRIDE; bool* defer) OVERRIDE;
// Pass-through implementation.
virtual bool OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) OVERRIDE;
// Create a new buffer to store received data. // Create a new buffer to store received data.
virtual bool OnWillRead(int request_id, virtual bool OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
......
...@@ -133,6 +133,20 @@ bool DetachableResourceHandler::OnWillStart(int request_id, const GURL& url, ...@@ -133,6 +133,20 @@ bool DetachableResourceHandler::OnWillStart(int request_id, const GURL& url,
return ret; return ret;
} }
bool DetachableResourceHandler::OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) {
DCHECK(!is_deferred_);
if (!next_handler_)
return true;
bool ret =
next_handler_->OnBeforeNetworkStart(request_id, url, &is_deferred_);
*defer = is_deferred_;
return ret;
}
bool DetachableResourceHandler::OnWillRead(int request_id, bool DetachableResourceHandler::OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
int* buf_size, int* buf_size,
......
...@@ -58,6 +58,9 @@ class DetachableResourceHandler : public ResourceHandler, ...@@ -58,6 +58,9 @@ class DetachableResourceHandler : public ResourceHandler,
bool* defer) OVERRIDE; bool* defer) OVERRIDE;
virtual bool OnWillStart(int request_id, const GURL& url, virtual bool OnWillStart(int request_id, const GURL& url,
bool* defer) OVERRIDE; bool* defer) OVERRIDE;
virtual bool OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) OVERRIDE;
virtual bool OnWillRead(int request_id, virtual bool OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
int* buf_size, int* buf_size,
......
...@@ -56,6 +56,13 @@ bool LayeredResourceHandler::OnWillStart(int request_id, const GURL& url, ...@@ -56,6 +56,13 @@ bool LayeredResourceHandler::OnWillStart(int request_id, const GURL& url,
return next_handler_->OnWillStart(request_id, url, defer); return next_handler_->OnWillStart(request_id, url, defer);
} }
bool LayeredResourceHandler::OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) {
DCHECK(next_handler_.get());
return next_handler_->OnBeforeNetworkStart(request_id, url, defer);
}
bool LayeredResourceHandler::OnWillRead(int request_id, bool LayeredResourceHandler::OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
int* buf_size, int* buf_size,
......
...@@ -35,6 +35,9 @@ class CONTENT_EXPORT LayeredResourceHandler : public ResourceHandler { ...@@ -35,6 +35,9 @@ class CONTENT_EXPORT LayeredResourceHandler : public ResourceHandler {
bool* defer) OVERRIDE; bool* defer) OVERRIDE;
virtual bool OnWillStart(int request_id, const GURL& url, virtual bool OnWillStart(int request_id, const GURL& url,
bool* defer) OVERRIDE; bool* defer) OVERRIDE;
virtual bool OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) OVERRIDE;
virtual bool OnWillRead(int request_id, virtual bool OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
int* buf_size, int* buf_size,
......
...@@ -210,6 +210,33 @@ class ForwardingFilter : public ResourceMessageFilter { ...@@ -210,6 +210,33 @@ class ForwardingFilter : public ResourceMessageFilter {
DISALLOW_COPY_AND_ASSIGN(ForwardingFilter); DISALLOW_COPY_AND_ASSIGN(ForwardingFilter);
}; };
// This class is a variation on URLRequestTestJob that will call
// URLRequest::OnBeforeNetworkStart before starting.
class URLRequestTestDelayedNetworkJob : public net::URLRequestTestJob {
public:
URLRequestTestDelayedNetworkJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate)
: net::URLRequestTestJob(request, network_delegate) {}
// Only start if not deferred for network start.
virtual void Start() OVERRIDE {
bool defer = false;
NotifyBeforeNetworkStart(&defer);
if (defer)
return;
net::URLRequestTestJob::Start();
}
virtual void ResumeNetworkStart() OVERRIDE {
net::URLRequestTestJob::StartAsync();
}
private:
virtual ~URLRequestTestDelayedNetworkJob() {}
DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedNetworkJob);
};
// This class is a variation on URLRequestTestJob in that it does // This class is a variation on URLRequestTestJob in that it does
// not complete start upon entry, only when specifically told to. // not complete start upon entry, only when specifically told to.
class URLRequestTestDelayedStartJob : public net::URLRequestTestJob { class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
...@@ -394,7 +421,8 @@ enum GenericResourceThrottleFlags { ...@@ -394,7 +421,8 @@ enum GenericResourceThrottleFlags {
NONE = 0, NONE = 0,
DEFER_STARTING_REQUEST = 1 << 0, DEFER_STARTING_REQUEST = 1 << 0,
DEFER_PROCESSING_RESPONSE = 1 << 1, DEFER_PROCESSING_RESPONSE = 1 << 1,
CANCEL_BEFORE_START = 1 << 2 CANCEL_BEFORE_START = 1 << 2,
DEFER_NETWORK_START = 1 << 3
}; };
// Throttle that tracks the current throttle blocking a request. Only one // Throttle that tracks the current throttle blocking a request. Only one
...@@ -441,6 +469,15 @@ class GenericResourceThrottle : public ResourceThrottle { ...@@ -441,6 +469,15 @@ class GenericResourceThrottle : public ResourceThrottle {
} }
} }
virtual void OnBeforeNetworkStart(bool* defer) OVERRIDE {
ASSERT_EQ(NULL, active_throttle_);
if (flags_ & DEFER_NETWORK_START) {
active_throttle_ = this;
*defer = true;
}
}
virtual const char* GetNameForLogging() const OVERRIDE { virtual const char* GetNameForLogging() const OVERRIDE {
return "GenericResourceThrottle"; return "GenericResourceThrottle";
} }
...@@ -573,6 +610,7 @@ class ResourceDispatcherHostTest : public testing::Test, ...@@ -573,6 +610,7 @@ class ResourceDispatcherHostTest : public testing::Test,
EnsureTestSchemeIsAllowed(); EnsureTestSchemeIsAllowed();
delay_start_ = false; delay_start_ = false;
delay_complete_ = false; delay_complete_ = false;
network_start_notification_ = false;
url_request_jobs_created_count_ = 0; url_request_jobs_created_count_ = 0;
} }
...@@ -670,6 +708,8 @@ class ResourceDispatcherHostTest : public testing::Test, ...@@ -670,6 +708,8 @@ class ResourceDispatcherHostTest : public testing::Test,
} else if (delay_complete_) { } else if (delay_complete_) {
return new URLRequestTestDelayedCompletionJob(request, return new URLRequestTestDelayedCompletionJob(request,
network_delegate); network_delegate);
} else if (network_start_notification_) {
return new URLRequestTestDelayedNetworkJob(request, network_delegate);
} else if (scheme == "big-job") { } else if (scheme == "big-job") {
return new URLRequestBigJob(request, network_delegate); return new URLRequestBigJob(request, network_delegate);
} else { } else {
...@@ -703,6 +743,10 @@ class ResourceDispatcherHostTest : public testing::Test, ...@@ -703,6 +743,10 @@ class ResourceDispatcherHostTest : public testing::Test,
delay_complete_ = delay_job_complete; delay_complete_ = delay_job_complete;
} }
void SetNetworkStartNotificationJobGeneration(bool notification) {
network_start_notification_ = notification;
}
void GenerateDataReceivedACK(const IPC::Message& msg) { void GenerateDataReceivedACK(const IPC::Message& msg) {
EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type()); EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type());
...@@ -736,12 +780,14 @@ class ResourceDispatcherHostTest : public testing::Test, ...@@ -736,12 +780,14 @@ class ResourceDispatcherHostTest : public testing::Test,
static ResourceDispatcherHostTest* test_fixture_; static ResourceDispatcherHostTest* test_fixture_;
static bool delay_start_; static bool delay_start_;
static bool delay_complete_; static bool delay_complete_;
static bool network_start_notification_;
static int url_request_jobs_created_count_; static int url_request_jobs_created_count_;
}; };
// Static. // Static.
ResourceDispatcherHostTest* ResourceDispatcherHostTest::test_fixture_ = NULL; ResourceDispatcherHostTest* ResourceDispatcherHostTest::test_fixture_ = NULL;
bool ResourceDispatcherHostTest::delay_start_ = false; bool ResourceDispatcherHostTest::delay_start_ = false;
bool ResourceDispatcherHostTest::delay_complete_ = false; bool ResourceDispatcherHostTest::delay_complete_ = false;
bool ResourceDispatcherHostTest::network_start_notification_ = false;
int ResourceDispatcherHostTest::url_request_jobs_created_count_ = 0; int ResourceDispatcherHostTest::url_request_jobs_created_count_ = 0;
void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id, void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id,
...@@ -1228,6 +1274,33 @@ TEST_F(ResourceDispatcherHostTest, PausedStartError) { ...@@ -1228,6 +1274,33 @@ TEST_F(ResourceDispatcherHostTest, PausedStartError) {
EXPECT_EQ(0, host_.pending_requests()); EXPECT_EQ(0, host_.pending_requests());
} }
// Test the OnBeforeNetworkStart throttle.
TEST_F(ResourceDispatcherHostTest, ThrottleNetworkStart) {
// Arrange to have requests deferred before processing response headers.
TestResourceDispatcherHostDelegate delegate;
delegate.set_flags(DEFER_NETWORK_START);
host_.SetDelegate(&delegate);
SetNetworkStartNotificationJobGeneration(true);
MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_2());
// Should have deferred for network start.
GenericResourceThrottle* first_throttle =
GenericResourceThrottle::active_throttle();
ASSERT_TRUE(first_throttle);
EXPECT_EQ(0, network_delegate()->completed_requests());
EXPECT_EQ(1, host_.pending_requests());
first_throttle->Resume();
// Flush all the pending requests.
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(1, network_delegate()->completed_requests());
EXPECT_EQ(0, host_.pending_requests());
}
TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) { TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
// Arrange to have requests deferred before starting. // Arrange to have requests deferred before starting.
TestResourceDispatcherHostDelegate delegate; TestResourceDispatcherHostDelegate delegate;
......
...@@ -73,6 +73,15 @@ class CONTENT_EXPORT ResourceHandler ...@@ -73,6 +73,15 @@ class CONTENT_EXPORT ResourceHandler
// until someone calls ResourceDispatcherHost::StartDeferredRequest(). // until someone calls ResourceDispatcherHost::StartDeferredRequest().
virtual bool OnWillStart(int request_id, const GURL& url, bool* defer) = 0; virtual bool OnWillStart(int request_id, const GURL& url, bool* defer) = 0;
// Called before the net::URLRequest for |request_id| (whose url is |url|}
// uses the network for the first time to load the resource. If the handler
// returns false, then the request is cancelled. Otherwise if the return value
// is true, the ResourceHandler can delay the request from starting by setting
// |*defer = true|. Call controller()->Resume() to continue if deferred.
virtual bool OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) = 0;
// Data will be read for the response. Upon success, this method places the // Data will be read for the response. Upon success, this method places the
// size and address of the buffer where the data is to be written in its // size and address of the buffer where the data is to be written in its
// out-params. This call will be followed by either OnReadCompleted or // out-params. This call will be followed by either OnReadCompleted or
......
...@@ -289,6 +289,20 @@ void ResourceLoader::OnSSLCertificateError(net::URLRequest* request, ...@@ -289,6 +289,20 @@ void ResourceLoader::OnSSLCertificateError(net::URLRequest* request,
fatal); fatal);
} }
void ResourceLoader::OnBeforeNetworkStart(net::URLRequest* unused,
bool* defer) {
DCHECK_EQ(request_.get(), unused);
// Give the handler a chance to delay the URLRequest from using the network.
if (!handler_->OnBeforeNetworkStart(
GetRequestInfo()->GetRequestID(), request_->url(), defer)) {
Cancel();
return;
} else if (*defer) {
deferred_stage_ = DEFERRED_NETWORK_START;
}
}
void ResourceLoader::OnResponseStarted(net::URLRequest* unused) { void ResourceLoader::OnResponseStarted(net::URLRequest* unused) {
DCHECK_EQ(request_.get(), unused); DCHECK_EQ(request_.get(), unused);
...@@ -391,6 +405,9 @@ void ResourceLoader::Resume() { ...@@ -391,6 +405,9 @@ void ResourceLoader::Resume() {
case DEFERRED_START: case DEFERRED_START:
StartRequestInternal(); StartRequestInternal();
break; break;
case DEFERRED_NETWORK_START:
request_->ResumeNetworkStart();
break;
case DEFERRED_REDIRECT: case DEFERRED_REDIRECT:
request_->FollowDeferredRedirect(); request_->FollowDeferredRedirect();
break; break;
......
...@@ -66,6 +66,8 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate, ...@@ -66,6 +66,8 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate,
virtual void OnSSLCertificateError(net::URLRequest* request, virtual void OnSSLCertificateError(net::URLRequest* request,
const net::SSLInfo& info, const net::SSLInfo& info,
bool fatal) OVERRIDE; bool fatal) OVERRIDE;
virtual void OnBeforeNetworkStart(net::URLRequest* request,
bool* defer) OVERRIDE;
virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE; virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE;
virtual void OnReadCompleted(net::URLRequest* request, virtual void OnReadCompleted(net::URLRequest* request,
int bytes_read) OVERRIDE; int bytes_read) OVERRIDE;
...@@ -117,6 +119,7 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate, ...@@ -117,6 +119,7 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate,
enum DeferredStage { enum DeferredStage {
DEFERRED_NONE, DEFERRED_NONE,
DEFERRED_START, DEFERRED_START,
DEFERRED_NETWORK_START,
DEFERRED_REDIRECT, DEFERRED_REDIRECT,
DEFERRED_READ, DEFERRED_READ,
DEFERRED_FINISH DEFERRED_FINISH
......
...@@ -94,6 +94,12 @@ class ResourceHandlerStub : public ResourceHandler { ...@@ -94,6 +94,12 @@ class ResourceHandlerStub : public ResourceHandler {
return true; return true;
} }
virtual bool OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) OVERRIDE {
return true;
}
virtual bool OnWillRead(int request_id, virtual bool OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
int* buf_size, int* buf_size,
......
...@@ -57,6 +57,12 @@ bool StreamResourceHandler::OnWillStart(int request_id, ...@@ -57,6 +57,12 @@ bool StreamResourceHandler::OnWillStart(int request_id,
return true; return true;
} }
bool StreamResourceHandler::OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) {
return true;
}
bool StreamResourceHandler::OnWillRead(int request_id, bool StreamResourceHandler::OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
int* buf_size, int* buf_size,
......
...@@ -49,6 +49,10 @@ class StreamResourceHandler : public StreamWriteObserver, ...@@ -49,6 +49,10 @@ class StreamResourceHandler : public StreamWriteObserver,
const GURL& url, const GURL& url,
bool* defer) OVERRIDE; bool* defer) OVERRIDE;
virtual bool OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) OVERRIDE;
// Create a new buffer to store received data. // Create a new buffer to store received data.
virtual bool OnWillRead(int request_id, virtual bool OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
......
...@@ -101,6 +101,12 @@ bool SyncResourceHandler::OnWillStart(int request_id, ...@@ -101,6 +101,12 @@ bool SyncResourceHandler::OnWillStart(int request_id,
return true; return true;
} }
bool SyncResourceHandler::OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) {
return true;
}
bool SyncResourceHandler::OnWillRead(int request_id, bool SyncResourceHandler::OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
int* buf_size, int* buf_size,
......
...@@ -46,6 +46,9 @@ class SyncResourceHandler : public ResourceHandler { ...@@ -46,6 +46,9 @@ class SyncResourceHandler : public ResourceHandler {
virtual bool OnWillStart(int request_id, virtual bool OnWillStart(int request_id,
const GURL& url, const GURL& url,
bool* defer) OVERRIDE; bool* defer) OVERRIDE;
virtual bool OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) OVERRIDE;
virtual bool OnWillRead(int request_id, virtual bool OnWillRead(int request_id,
scoped_refptr<net::IOBuffer>* buf, scoped_refptr<net::IOBuffer>* buf,
int* buf_size, int* buf_size,
......
...@@ -84,6 +84,31 @@ bool ThrottlingResourceHandler::OnWillStart(int request_id, ...@@ -84,6 +84,31 @@ bool ThrottlingResourceHandler::OnWillStart(int request_id,
return next_handler_->OnWillStart(request_id, url, defer); return next_handler_->OnWillStart(request_id, url, defer);
} }
bool ThrottlingResourceHandler::OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) {
DCHECK(!cancelled_by_resource_throttle_);
*defer = false;
while (next_index_ < throttles_.size()) {
int index = next_index_;
throttles_[index]->OnBeforeNetworkStart(defer);
next_index_++;
if (cancelled_by_resource_throttle_)
return false;
if (*defer) {
OnRequestDefered(index);
deferred_stage_ = DEFERRED_NETWORK_START;
deferred_url_ = url;
return true; // Do not cancel.
}
}
next_index_ = 0; // Reset for next time.
return next_handler_->OnBeforeNetworkStart(request_id, url, defer);
}
bool ThrottlingResourceHandler::OnResponseStarted(int request_id, bool ThrottlingResourceHandler::OnResponseStarted(int request_id,
ResourceResponse* response, ResourceResponse* response,
bool* defer) { bool* defer) {
...@@ -137,6 +162,9 @@ void ThrottlingResourceHandler::Resume() { ...@@ -137,6 +162,9 @@ void ThrottlingResourceHandler::Resume() {
case DEFERRED_START: case DEFERRED_START:
ResumeStart(); ResumeStart();
break; break;
case DEFERRED_NETWORK_START:
ResumeNetworkStart();
break;
case DEFERRED_REDIRECT: case DEFERRED_REDIRECT:
ResumeRedirect(); ResumeRedirect();
break; break;
...@@ -160,6 +188,20 @@ void ThrottlingResourceHandler::ResumeStart() { ...@@ -160,6 +188,20 @@ void ThrottlingResourceHandler::ResumeStart() {
} }
} }
void ThrottlingResourceHandler::ResumeNetworkStart() {
DCHECK(!cancelled_by_resource_throttle_);
GURL url = deferred_url_;
deferred_url_ = GURL();
bool defer = false;
if (!OnBeforeNetworkStart(GetRequestID(), url, &defer)) {
controller()->Cancel();
} else if (!defer) {
controller()->Resume();
}
}
void ThrottlingResourceHandler::ResumeRedirect() { void ThrottlingResourceHandler::ResumeRedirect() {
DCHECK(!cancelled_by_resource_throttle_); DCHECK(!cancelled_by_resource_throttle_);
......
...@@ -39,6 +39,9 @@ class ThrottlingResourceHandler : public LayeredResourceHandler, ...@@ -39,6 +39,9 @@ class ThrottlingResourceHandler : public LayeredResourceHandler,
bool* defer) OVERRIDE; bool* defer) OVERRIDE;
virtual bool OnWillStart(int request_id, const GURL& url, virtual bool OnWillStart(int request_id, const GURL& url,
bool* defer) OVERRIDE; bool* defer) OVERRIDE;
virtual bool OnBeforeNetworkStart(int request_id,
const GURL& url,
bool* defer) OVERRIDE;
// ResourceController implementation: // ResourceController implementation:
virtual void Cancel() OVERRIDE; virtual void Cancel() OVERRIDE;
...@@ -48,6 +51,7 @@ class ThrottlingResourceHandler : public LayeredResourceHandler, ...@@ -48,6 +51,7 @@ class ThrottlingResourceHandler : public LayeredResourceHandler,
private: private:
void ResumeStart(); void ResumeStart();
void ResumeNetworkStart();
void ResumeRedirect(); void ResumeRedirect();
void ResumeResponse(); void ResumeResponse();
...@@ -58,6 +62,7 @@ class ThrottlingResourceHandler : public LayeredResourceHandler, ...@@ -58,6 +62,7 @@ class ThrottlingResourceHandler : public LayeredResourceHandler,
enum DeferredStage { enum DeferredStage {
DEFERRED_NONE, DEFERRED_NONE,
DEFERRED_START, DEFERRED_START,
DEFERRED_NETWORK_START,
DEFERRED_REDIRECT, DEFERRED_REDIRECT,
DEFERRED_RESPONSE DEFERRED_RESPONSE
}; };
......
...@@ -25,6 +25,7 @@ class ResourceThrottle { ...@@ -25,6 +25,7 @@ class ResourceThrottle {
virtual void WillStartRequest(bool* defer) {} virtual void WillStartRequest(bool* defer) {}
virtual void WillRedirectRequest(const GURL& new_url, bool* defer) {} virtual void WillRedirectRequest(const GURL& new_url, bool* defer) {}
virtual void WillProcessResponse(bool* defer) {} virtual void WillProcessResponse(bool* defer) {}
virtual void OnBeforeNetworkStart(bool* defer) {}
// Returns the name of the throttle, as a UTF-8 C-string, for logging // Returns the name of the throttle, as a UTF-8 C-string, for logging
// purposes. NULL is not allowed. Caller does *not* take ownership of the // purposes. NULL is not allowed. Caller does *not* take ownership of the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment