diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 22:40:57 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 22:40:57 +0000 |
commit | 7b384676855d858d37ce3da1e4472413f86314d2 (patch) | |
tree | ab5048f73a45796a79818db33ab15c7c12beb942 /chrome/browser | |
parent | ac20559299eb260dc32f8e85839d4ba77585dac6 (diff) | |
download | chromium_src-7b384676855d858d37ce3da1e4472413f86314d2.zip chromium_src-7b384676855d858d37ce3da1e4472413f86314d2.tar.gz chromium_src-7b384676855d858d37ce3da1e4472413f86314d2.tar.bz2 |
Fix the crash if a download starts before we have the plugin list. The fix is to make ResourceDispatcherHost support a handler pausing a request in its OnResponseStarted callback.
Note I didn't find any way of testing the resource handler code, so I didn't know how to add a good test for this.
BUG=19414
Review URL: http://codereview.chromium.org/173037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23769 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/renderer_host/resource_dispatcher_host.cc | 38 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_dispatcher_host.h | 7 |
2 files changed, 34 insertions, 11 deletions
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc index 9b32684..7e5cded 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc @@ -1054,15 +1054,13 @@ void ResourceDispatcherHost::OnResponseStarted(URLRequest* request) { if (!CompleteResponseStarted(request)) { CancelRequest(info->process_id, info->request_id, false); } else { - // Start reading. - int bytes_read = 0; - if (Read(request, &bytes_read)) { - OnReadCompleted(request, bytes_read); - } else if (!request->status().is_io_pending()) { - DCHECK(!info->is_paused); - // If the error is not an IO pending, then we're done reading. - OnResponseCompleted(request); + // Check if the handler paused the request in their OnResponseStarted. + if (PauseRequestIfNeeded(info)) { + RESOURCE_LOG("OnResponseStarted pausing2: " << request->url().spec()); + return; } + + StartReading(request); } } else { OnResponseCompleted(request); @@ -1102,6 +1100,7 @@ bool ResourceDispatcherHost::CompleteResponseStarted(URLRequest* request) { } NotifyResponseStarted(request, info->process_id); + info->called_on_response_started = true; return info->resource_handler->OnResponseStarted(info->request_id, response.get()); } @@ -1278,10 +1277,27 @@ void ResourceDispatcherHost::ResumeRequest(const GlobalRequestID& request_id) { info->is_paused = false; - if (info->has_started_reading) - OnReadCompleted(i->second, info->paused_read_bytes); - else + if (info->called_on_response_started) { + if (info->has_started_reading) { + OnReadCompleted(i->second, info->paused_read_bytes); + } else { + StartReading(request); + } + } else { OnResponseStarted(i->second); + } +} + +void ResourceDispatcherHost::StartReading(URLRequest* request) { + // Start reading. + int bytes_read = 0; + if (Read(request, &bytes_read)) { + OnReadCompleted(request, bytes_read); + } else if (!request->status().is_io_pending()) { + DCHECK(!ExtraInfoForRequest(request)->is_paused); + // If the error is not an IO pending, then we're done reading. + OnResponseCompleted(request); + } } bool ResourceDispatcherHost::Read(URLRequest* request, int* bytes_read) { diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.h b/chrome/browser/renderer_host/resource_dispatcher_host.h index e36e97f..f7dc92e 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.h +++ b/chrome/browser/renderer_host/resource_dispatcher_host.h @@ -105,6 +105,7 @@ class ResourceDispatcherHost : public URLRequest::Delegate { waiting_for_upload_progress_ack(false), memory_cost(0), is_paused(false), + called_on_response_started(false), has_started_reading(false), paused_read_bytes(0) { } @@ -175,6 +176,9 @@ class ResourceDispatcherHost : public URLRequest::Delegate { // by the ResourceDispatcherHost, not the event handlers. bool is_paused; + // Whether we called OnResponseStarted for this request or not. + bool called_on_response_started; + // Whether this request has started reading any bytes from the response // yet. Will be true after the first (unpaused) call to Read. bool has_started_reading; @@ -413,6 +417,9 @@ class ResourceDispatcherHost : public URLRequest::Delegate { // Resumes the given request by calling OnResponseStarted or OnReadCompleted. void ResumeRequest(const GlobalRequestID& request_id); + // Internal function to start reading for the first time. + void StartReading(URLRequest* request); + // Reads data from the response using our internal buffer as async IO. // Returns true if data is available immediately, false otherwise. If the // return value is false, we will receive a OnReadComplete() callback later. |