summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-19 22:40:57 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-19 22:40:57 +0000
commit7b384676855d858d37ce3da1e4472413f86314d2 (patch)
treeab5048f73a45796a79818db33ab15c7c12beb942 /chrome/browser
parentac20559299eb260dc32f8e85839d4ba77585dac6 (diff)
downloadchromium_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.cc38
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.h7
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.