summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-22 20:49:13 +0000
committerdarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-22 20:49:13 +0000
commit39225fe24249035c01b5d87a1da3fdf18b7eb1e9 (patch)
tree5988bef2397b2c0c8e76483240f7fb0fb0151fb3
parentc5f0c9096c638661f472140abeb701acf6e02c40 (diff)
downloadchromium_src-39225fe24249035c01b5d87a1da3fdf18b7eb1e9.zip
chromium_src-39225fe24249035c01b5d87a1da3fdf18b7eb1e9.tar.gz
chromium_src-39225fe24249035c01b5d87a1da3fdf18b7eb1e9.tar.bz2
Revert r143458 (which re-applies r143341 and r142979). This CL also includes
unit tests for DataReceived and DataReceived_ACK messaging. Make ResourceHandlers that defer loading also be responsible for calling Resume on their ResourceController. What this does is avoid out-of-band calls to Resume the ResourceLoader, and that means that an intermediate ResourceHandler (for example the BufferedResourceHandler) will be able to implement ResourceController. Consider the problematic scenerio that happens today: 1- The BufferedResourceHandler consumes response headers and buffers network data, delaying notifications to its downstream ResourceHandler. 2- The BufferedResourceHandler decides if it is dealing with a download or not, and optionally installs a DownloadResourceHandler as the downstream handler. 3- The BufferedResourceHandler replays the OnResponseStarted and OnReadCompleted events to push data to its downstream handler. 4- The downstream handler might decide to defer processing. 5- When the downstream handler wants to resume processing, it needs to tell someone to Resume. At step 5, the complicated thing we do to ourselves today is we make that Resume step tell the ResourceLoader to resume instead of the BufferedResourceHandler. This causes problems for the BufferedResourceHandler as it may start receiving more network events before it has finished flushing its existing buffers to its downstream handler. This patch is a step toward fixing the above problem. It makes all handlers call Resume on their own controller when it is time to resume. A subsequent patch will leverage this to cleanup and simplify the BufferedResourceHandler as well as the overall pause/resume semantics of the ResourceLoader. Other cleanup in this patch: The {Async,Sync,CrossSite}ResourceHandler classes are now all constructed with an URLRequest. This avoids messy code to call ResourceDispatcherHostImpl::GetURLRequest(). Since the lifetime of ResourceHandlers is now bound to the lifetime of their associated URLRequest, this is a safe and simple change to make. Other ResourceHandlers, like the BufferedResourceHandler, were already holding onto their associated URLRequest. R=jam@chromium.org Review URL: https://chromiumcodereview.appspot.com/10644011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@143702 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/renderer_host/async_resource_handler.cc105
-rw-r--r--content/browser/renderer_host/async_resource_handler.h27
-rw-r--r--content/browser/renderer_host/buffered_resource_handler.cc7
-rw-r--r--content/browser/renderer_host/cross_site_resource_handler.cc44
-rw-r--r--content/browser/renderer_host/cross_site_resource_handler.h11
-rw-r--r--content/browser/renderer_host/resource_dispatcher_host_impl.cc176
-rw-r--r--content/browser/renderer_host/resource_dispatcher_host_impl.h10
-rw-r--r--content/browser/renderer_host/resource_dispatcher_host_unittest.cc153
-rw-r--r--content/browser/renderer_host/resource_loader.cc12
-rw-r--r--content/browser/renderer_host/resource_loader.h2
-rw-r--r--content/browser/renderer_host/resource_request_info_impl.cc2
-rw-r--r--content/browser/renderer_host/resource_request_info_impl.h21
-rw-r--r--content/browser/renderer_host/sync_resource_handler.cc21
-rw-r--r--content/browser/renderer_host/sync_resource_handler.h4
14 files changed, 360 insertions, 235 deletions
diff --git a/content/browser/renderer_host/async_resource_handler.cc b/content/browser/renderer_host/async_resource_handler.cc
index ac70a18..8177a5a 100644
--- a/content/browser/renderer_host/async_resource_handler.cc
+++ b/content/browser/renderer_host/async_resource_handler.cc
@@ -15,12 +15,12 @@
#include "content/browser/host_zoom_map_impl.h"
#include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
#include "content/browser/renderer_host/resource_message_filter.h"
+#include "content/browser/renderer_host/resource_request_info_impl.h"
#include "content/browser/resource_context_impl.h"
#include "content/common/resource_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/resource_dispatcher_host_delegate.h"
-#include "content/public/browser/resource_request_info.h"
#include "content/public/common/resource_response.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
@@ -44,6 +44,10 @@ const int kInitialReadBufSize = 32768;
// The maximum size of the shared memory buffer. (512 kilobytes).
const int kMaxReadBufSize = 524288;
+// Maximum number of pending data messages sent to the renderer at any
+// given time for a given request.
+const int kMaxPendingDataMessages = 20;
+
} // namespace
// Our version of IOBuffer that uses shared memory.
@@ -81,16 +85,50 @@ class SharedIOBuffer : public net::IOBuffer {
AsyncResourceHandler::AsyncResourceHandler(
ResourceMessageFilter* filter,
int routing_id,
- const GURL& url,
+ net::URLRequest* request,
ResourceDispatcherHostImpl* rdh)
: filter_(filter),
routing_id_(routing_id),
+ request_(request),
rdh_(rdh),
next_buffer_size_(kInitialReadBufSize),
- url_(url) {
+ pending_data_count_(0),
+ did_defer_(false) {
+ // Set a back-pointer from ResourceRequestInfoImpl to |this|, so that the
+ // ResourceDispatcherHostImpl can send us IPC messages.
+ // TODO(darin): Implement an IPC message filter instead?
+ ResourceRequestInfoImpl::ForRequest(request_)->set_async_handler(this);
}
AsyncResourceHandler::~AsyncResourceHandler() {
+ // Cleanup back-pointer stored on the request info.
+ ResourceRequestInfoImpl::ForRequest(request_)->set_async_handler(NULL);
+}
+
+void AsyncResourceHandler::OnFollowRedirect(
+ bool has_new_first_party_for_cookies,
+ const GURL& new_first_party_for_cookies) {
+ if (!request_->status().is_success()) {
+ DVLOG(1) << "OnFollowRedirect for invalid request";
+ return;
+ }
+
+ if (has_new_first_party_for_cookies)
+ request_->set_first_party_for_cookies(new_first_party_for_cookies);
+
+ ResumeIfDeferred();
+}
+
+void AsyncResourceHandler::OnDataReceivedACK() {
+ // If the pending data count was higher than the max, resume the request.
+ if (--pending_data_count_ == kMaxPendingDataMessages) {
+ // Decrement the pending data count one more time because we also
+ // incremented it before deferring the request.
+ --pending_data_count_;
+
+ // Resume the request.
+ ResumeIfDeferred();
+ }
}
bool AsyncResourceHandler::OnUploadProgress(int request_id,
@@ -104,14 +142,13 @@ bool AsyncResourceHandler::OnRequestRedirected(int request_id,
const GURL& new_url,
ResourceResponse* response,
bool* defer) {
- *defer = true;
- net::URLRequest* request = rdh_->GetURLRequest(
- GlobalRequestID(filter_->child_id(), request_id));
+ *defer = did_defer_ = true;
+
if (rdh_->delegate())
- rdh_->delegate()->OnRequestRedirected(request, response);
+ rdh_->delegate()->OnRequestRedirected(request_, response);
- DevToolsNetLogObserver::PopulateResponseInfo(request, response);
- response->request_start = request->creation_time();
+ DevToolsNetLogObserver::PopulateResponseInfo(request_, response);
+ response->request_start = request_->creation_time();
response->response_start = TimeTicks::Now();
return filter_->Send(new ResourceMsg_ReceivedRedirect(
routing_id_, request_id, new_url, *response));
@@ -125,36 +162,34 @@ bool AsyncResourceHandler::OnResponseStarted(int request_id,
// renderer will be able to set these precisely at the time the
// request commits, avoiding the possibility of e.g. zooming the old content
// or of having to layout the new content twice.
- net::URLRequest* request = rdh_->GetURLRequest(
- GlobalRequestID(filter_->child_id(), request_id));
if (rdh_->delegate())
- rdh_->delegate()->OnResponseStarted(request, response, filter_);
+ rdh_->delegate()->OnResponseStarted(request_, response, filter_);
- DevToolsNetLogObserver::PopulateResponseInfo(request, response);
+ DevToolsNetLogObserver::PopulateResponseInfo(request_, response);
ResourceContext* resource_context = filter_->resource_context();
HostZoomMap* host_zoom_map =
GetHostZoomMapForResourceContext(resource_context);
- const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
+ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
if (info->GetResourceType() == ResourceType::MAIN_FRAME && host_zoom_map) {
- GURL request_url(request->url());
+ const GURL& request_url = request_->url();
filter_->Send(new ViewMsg_SetZoomLevelForLoadingURL(
info->GetRouteID(),
request_url, host_zoom_map->GetZoomLevel(net::GetHostOrSpecFromURL(
request_url))));
}
- response->request_start = request->creation_time();
+ response->request_start = request_->creation_time();
response->response_start = TimeTicks::Now();
filter_->Send(new ResourceMsg_ReceivedResponse(
routing_id_, request_id, *response));
- if (request->response_info().metadata) {
- std::vector<char> copy(request->response_info().metadata->data(),
- request->response_info().metadata->data() +
- request->response_info().metadata->size());
+ if (request_->response_info().metadata) {
+ std::vector<char> copy(request_->response_info().metadata->data(),
+ request_->response_info().metadata->data() +
+ request_->response_info().metadata->size());
filter_->Send(new ResourceMsg_ReceivedCachedMetadata(
routing_id_, request_id, copy));
}
@@ -207,7 +242,7 @@ bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read,
next_buffer_size_ = std::min(next_buffer_size_ * 2, kMaxReadBufSize);
}
- if (!rdh_->WillSendData(filter_->child_id(), request_id, defer)) {
+ if (!WillSendData(defer)) {
// We should not send this data now, we have too many pending requests.
return true;
}
@@ -219,7 +254,8 @@ bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read,
// to fix this. We can't move this call above the WillSendData because
// it's killing our read_buffer_, and we don't want that when we pause
// the request.
- rdh_->DataReceivedACK(filter_->child_id(), request_id);
+ OnDataReceivedACK();
+
// We just unmapped the memory.
read_buffer_ = NULL;
return false;
@@ -227,10 +263,8 @@ bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read,
// We just unmapped the memory.
read_buffer_ = NULL;
- net::URLRequest* request = rdh_->GetURLRequest(
- GlobalRequestID(filter_->child_id(), request_id));
int encoded_data_length =
- DevToolsNetLogObserver::GetAndResetEncodedDataLength(request);
+ DevToolsNetLogObserver::GetAndResetEncodedDataLength(request_);
filter_->Send(new ResourceMsg_DataReceived(
routing_id_, request_id, handle, *bytes_read, encoded_data_length));
@@ -250,7 +284,7 @@ bool AsyncResourceHandler::OnResponseCompleted(
// If we crash here, figure out what URL the renderer was requesting.
// http://crbug.com/107692
char url_buf[128];
- base::strlcpy(url_buf, url_.spec().c_str(), arraysize(url_buf));
+ base::strlcpy(url_buf, request_->url().spec().c_str(), arraysize(url_buf));
base::debug::Alias(url_buf);
TimeTicks completion_time = TimeTicks::Now();
@@ -283,4 +317,23 @@ void AsyncResourceHandler::GlobalCleanup() {
}
}
+bool AsyncResourceHandler::WillSendData(bool* defer) {
+ if (++pending_data_count_ > kMaxPendingDataMessages) {
+ // We reached the max number of data messages that can be sent to
+ // the renderer for a given request. Pause the request and wait for
+ // the renderer to start processing them before resuming it.
+ *defer = did_defer_ = true;
+ return false;
+ }
+
+ return true;
+}
+
+void AsyncResourceHandler::ResumeIfDeferred() {
+ if (did_defer_) {
+ did_defer_ = false;
+ controller()->Resume();
+ }
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/async_resource_handler.h b/content/browser/renderer_host/async_resource_handler.h
index b865010..fe25e7e 100644
--- a/content/browser/renderer_host/async_resource_handler.h
+++ b/content/browser/renderer_host/async_resource_handler.h
@@ -11,6 +11,10 @@
#include "content/browser/renderer_host/resource_handler.h"
#include "googleurl/src/gurl.h"
+namespace net {
+class URLRequest;
+}
+
namespace content {
class ResourceDispatcherHostImpl;
class ResourceMessageFilter;
@@ -22,10 +26,15 @@ class AsyncResourceHandler : public ResourceHandler {
public:
AsyncResourceHandler(ResourceMessageFilter* filter,
int routing_id,
- const GURL& url,
+ net::URLRequest* request,
ResourceDispatcherHostImpl* rdh);
virtual ~AsyncResourceHandler();
+ // IPC message handlers:
+ void OnFollowRedirect(bool has_new_first_party_for_cookies,
+ const GURL& new_first_party_for_cookies);
+ void OnDataReceivedACK();
+
// ResourceHandler implementation:
virtual bool OnUploadProgress(int request_id,
uint64 position,
@@ -56,9 +65,17 @@ class AsyncResourceHandler : public ResourceHandler {
static void GlobalCleanup();
private:
+ // Returns true if it's ok to send the data. If there are already too many
+ // data messages pending, it defers the request and returns false. In this
+ // case the caller should not send the data.
+ bool WillSendData(bool* defer);
+
+ void ResumeIfDeferred();
+
scoped_refptr<SharedIOBuffer> read_buffer_;
scoped_refptr<ResourceMessageFilter> filter_;
int routing_id_;
+ net::URLRequest* request_;
ResourceDispatcherHostImpl* rdh_;
// |next_buffer_size_| is the size of the buffer to be allocated on the next
@@ -68,9 +85,11 @@ class AsyncResourceHandler : public ResourceHandler {
// was filled, up to a maximum size of 512k.
int next_buffer_size_;
- // TODO(battre): Remove url. This is only for debugging
- // http://crbug.com/107692.
- GURL url_;
+ // Number of messages we've sent to the renderer that we haven't gotten an
+ // ACK for. This allows us to avoid having too many messages in flight.
+ int pending_data_count_;
+
+ bool did_defer_;
DISALLOW_COPY_AND_ASSIGN(AsyncResourceHandler);
};
diff --git a/content/browser/renderer_host/buffered_resource_handler.cc b/content/browser/renderer_host/buffered_resource_handler.cc
index b57da4a..11db2df 100644
--- a/content/browser/renderer_host/buffered_resource_handler.cc
+++ b/content/browser/renderer_host/buffered_resource_handler.cc
@@ -383,13 +383,6 @@ bool BufferedResourceHandler::UseAlternateResourceHandler(
net::URLRequestStatus status(net::URLRequestStatus::HANDLED_EXTERNALLY, 0);
next_handler_->OnResponseCompleted(request_id, status, std::string());
- // Remove the non-owning pointer to the CrossSiteResourceHandler, if any,
- // from the extra request info because the CrossSiteResourceHandler (part of
- // the original ResourceHandler chain) will be deleted by the next statement.
- ResourceRequestInfoImpl* info =
- ResourceRequestInfoImpl::ForRequest(request_);
- info->set_cross_site_handler(NULL);
-
// This is handled entirely within the new ResourceHandler, so just reset the
// original ResourceHandler.
next_handler_ = handler.Pass();
diff --git a/content/browser/renderer_host/cross_site_resource_handler.cc b/content/browser/renderer_host/cross_site_resource_handler.cc
index 6495a63..7527401 100644
--- a/content/browser/renderer_host/cross_site_resource_handler.cc
+++ b/content/browser/renderer_host/cross_site_resource_handler.cc
@@ -10,12 +10,10 @@
#include "base/logging.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
#include "content/browser/renderer_host/resource_request_info_impl.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/global_request_id.h"
+#include "content/public/browser/resource_controller.h"
#include "content/public/common/resource_response.h"
-#include "net/base/io_buffer.h"
#include "net/http/http_response_headers.h"
namespace content {
@@ -39,21 +37,23 @@ CrossSiteResourceHandler::CrossSiteResourceHandler(
scoped_ptr<ResourceHandler> next_handler,
int render_process_host_id,
int render_view_id,
- ResourceDispatcherHostImpl* rdh)
+ net::URLRequest* request)
: LayeredResourceHandler(next_handler.Pass()),
render_process_host_id_(render_process_host_id),
render_view_id_(render_view_id),
+ request_(request),
has_started_response_(false),
in_cross_site_transition_(false),
request_id_(-1),
completed_during_transition_(false),
did_defer_(false),
completed_status_(),
- response_(NULL),
- rdh_(rdh) {
+ response_(NULL) {
}
CrossSiteResourceHandler::~CrossSiteResourceHandler() {
+ // Cleanup back-pointer stored on the request info.
+ ResourceRequestInfoImpl::ForRequest(request_)->set_cross_site_handler(NULL);
}
bool CrossSiteResourceHandler::OnRequestRedirected(
@@ -78,14 +78,7 @@ bool CrossSiteResourceHandler::OnResponseStarted(
DCHECK(!in_cross_site_transition_);
has_started_response_ = true;
- // Look up the request and associated info.
- GlobalRequestID global_id(render_process_host_id_, request_id);
- net::URLRequest* request = rdh_->GetURLRequest(global_id);
- if (!request) {
- DLOG(WARNING) << "Request wasn't found";
- return false;
- }
- ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
+ ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request_);
// If this is a download, just pass the response through without doing a
// cross-site check. The renderer will see it is a download and abort the
@@ -105,7 +98,7 @@ bool CrossSiteResourceHandler::OnResponseStarted(
// Tell the renderer to run the onunload event handler, and wait for the
// reply.
- StartCrossSiteTransition(request_id, response, global_id, defer);
+ StartCrossSiteTransition(request_id, response, defer);
return true;
}
@@ -135,9 +128,8 @@ bool CrossSiteResourceHandler::OnResponseCompleted(
// so that the error message (e.g., 404) can be displayed to the user.
// Also continue with the logic below to remember that we completed
// during the cross-site transition.
- GlobalRequestID global_id(render_process_host_id_, request_id);
bool defer = false;
- StartCrossSiteTransition(request_id, NULL, global_id, &defer);
+ StartCrossSiteTransition(request_id, NULL, &defer);
DCHECK(!defer); // Since !has_started_response_.
}
@@ -158,14 +150,6 @@ void CrossSiteResourceHandler::ResumeResponse() {
DCHECK(in_cross_site_transition_);
in_cross_site_transition_ = false;
- // Find the request for this response.
- GlobalRequestID global_id(render_process_host_id_, request_id_);
- net::URLRequest* request = rdh_->GetURLRequest(global_id);
- if (!request) {
- DLOG(WARNING) << "Resuming a request that wasn't found";
- return;
- }
-
if (has_started_response_) {
// Send OnResponseStarted to the new renderer.
DCHECK(response_);
@@ -181,7 +165,7 @@ void CrossSiteResourceHandler::ResumeResponse() {
// Remove ourselves from the ExtraRequestInfo.
ResourceRequestInfoImpl* info =
- ResourceRequestInfoImpl::ForRequest(request);
+ ResourceRequestInfoImpl::ForRequest(request_);
info->set_cross_site_handler(NULL);
// If the response completed during the transition, notify the next
@@ -199,7 +183,6 @@ void CrossSiteResourceHandler::ResumeResponse() {
void CrossSiteResourceHandler::StartCrossSiteTransition(
int request_id,
ResourceResponse* response,
- const GlobalRequestID& global_id,
bool* defer) {
in_cross_site_transition_ = true;
request_id_ = request_id;
@@ -207,13 +190,8 @@ void CrossSiteResourceHandler::StartCrossSiteTransition(
// Store this handler on the ExtraRequestInfo, so that RDH can call our
// ResumeResponse method when the close ACK is received.
- net::URLRequest* request = rdh_->GetURLRequest(global_id);
- if (!request) {
- DLOG(WARNING) << "Cross site response for a request that wasn't found";
- return;
- }
ResourceRequestInfoImpl* info =
- ResourceRequestInfoImpl::ForRequest(request);
+ ResourceRequestInfoImpl::ForRequest(request_);
info->set_cross_site_handler(this);
if (has_started_response_) {
diff --git a/content/browser/renderer_host/cross_site_resource_handler.h b/content/browser/renderer_host/cross_site_resource_handler.h
index 1c20e2a..1be17de 100644
--- a/content/browser/renderer_host/cross_site_resource_handler.h
+++ b/content/browser/renderer_host/cross_site_resource_handler.h
@@ -9,9 +9,11 @@
#include "content/browser/renderer_host/layered_resource_handler.h"
#include "net/url_request/url_request_status.h"
+namespace net {
+class URLRequest;
+}
+
namespace content {
-class ResourceDispatcherHostImpl;
-struct GlobalRequestID;
// Ensures that cross-site responses are delayed until the onunload handler of
// the previous page is allowed to run. This handler wraps an
@@ -23,7 +25,7 @@ class CrossSiteResourceHandler : public LayeredResourceHandler {
CrossSiteResourceHandler(scoped_ptr<ResourceHandler> next_handler,
int render_process_host_id,
int render_view_id,
- ResourceDispatcherHostImpl* rdh);
+ net::URLRequest* request);
virtual ~CrossSiteResourceHandler();
// ResourceHandler implementation:
@@ -51,13 +53,13 @@ class CrossSiteResourceHandler : public LayeredResourceHandler {
void StartCrossSiteTransition(
int request_id,
ResourceResponse* response,
- const GlobalRequestID& global_id,
bool* defer);
void ResumeIfDeferred();
int render_process_host_id_;
int render_view_id_;
+ net::URLRequest* request_;
bool has_started_response_;
bool in_cross_site_transition_;
int request_id_;
@@ -66,7 +68,6 @@ class CrossSiteResourceHandler : public LayeredResourceHandler {
net::URLRequestStatus completed_status_;
std::string completed_security_info_;
ResourceResponse* response_;
- ResourceDispatcherHostImpl* rdh_;
DISALLOW_COPY_AND_ASSIGN(CrossSiteResourceHandler);
};
diff --git a/content/browser/renderer_host/resource_dispatcher_host_impl.cc b/content/browser/renderer_host/resource_dispatcher_host_impl.cc
index 0ff9ef1..9514845 100644
--- a/content/browser/renderer_host/resource_dispatcher_host_impl.cc
+++ b/content/browser/renderer_host/resource_dispatcher_host_impl.cc
@@ -99,10 +99,6 @@ static ResourceDispatcherHostImpl* g_resource_dispatcher_host;
// The interval for calls to ResourceDispatcherHostImpl::UpdateLoadStates
const int kUpdateLoadStatesIntervalMsec = 100;
-// Maximum number of pending data messages sent to the renderer at any
-// given time for a given request.
-const int kMaxPendingDataMessages = 20;
-
// Maximum byte "cost" of all the outstanding requests for a renderer.
// See delcaration of |max_outstanding_requests_cost_per_process_| for details.
// This bound is 25MB, which allows for around 6000 outstanding requests.
@@ -930,22 +926,6 @@ void ResourceDispatcherHostImpl::BeginRequest(
return;
}
- // Construct the event handler.
- scoped_ptr<ResourceHandler> handler;
- if (sync_result) {
- handler.reset(new SyncResourceHandler(
- filter_, request_data.url, sync_result, this));
- } else {
- handler.reset(new AsyncResourceHandler(
- filter_, route_id, request_data.url, this));
- }
-
- // The RedirectToFileResourceHandler depends on being next in the chain.
- if (request_data.download_to_file) {
- handler.reset(
- new RedirectToFileResourceHandler(handler.Pass(), child_id, this));
- }
-
int load_flags =
BuildLoadFlagsForRequest(request_data, child_id, sync_result != NULL);
@@ -987,6 +967,61 @@ void ResourceDispatcherHostImpl::BeginRequest(
upload_size = request_data.upload_data->GetContentLengthSync();
}
+ bool allow_download = request_data.allow_download &&
+ ResourceType::IsFrame(request_data.resource_type);
+
+ // Make extra info and read footer (contains request ID).
+ ResourceRequestInfoImpl* extra_info =
+ new ResourceRequestInfoImpl(
+ process_type,
+ child_id,
+ route_id,
+ request_data.origin_pid,
+ request_id,
+ request_data.is_main_frame,
+ request_data.frame_id,
+ request_data.parent_is_main_frame,
+ request_data.parent_frame_id,
+ request_data.resource_type,
+ request_data.transition_type,
+ upload_size,
+ false, // is download
+ allow_download,
+ request_data.has_user_gesture,
+ request_data.referrer_policy,
+ resource_context);
+ extra_info->AssociateWithRequest(request); // Request takes ownership.
+
+ if (request->url().SchemeIs(chrome::kBlobScheme)) {
+ // Hang on to a reference to ensure the blob is not released prior
+ // to the job being started.
+ webkit_blob::BlobStorageController* controller =
+ GetBlobStorageControllerForResourceContext(resource_context);
+ extra_info->set_requested_blob_data(
+ controller->GetBlobDataFromUrl(request->url()));
+ }
+
+ // Have the appcache associate its extra info with the request.
+ appcache::AppCacheInterceptor::SetExtraRequestInfo(
+ request, ResourceContext::GetAppCacheService(resource_context), child_id,
+ request_data.appcache_host_id, request_data.resource_type);
+
+ // Construct the IPC resource handler.
+ scoped_ptr<ResourceHandler> handler;
+ if (sync_result) {
+ handler.reset(new SyncResourceHandler(
+ filter_, request, sync_result, this));
+ } else {
+ handler.reset(new AsyncResourceHandler(
+ filter_, route_id, request, this));
+ }
+
+ // The RedirectToFileResourceHandler depends on being next in the chain.
+ if (request_data.download_to_file) {
+ handler.reset(
+ new RedirectToFileResourceHandler(handler.Pass(), child_id, this));
+ }
+
// Install a CrossSiteResourceHandler if this request is coming from a
// RenderViewHost with a pending cross-site request. We only check this for
// MAIN_FRAME requests. Unblock requests only come from a blocked page, do
@@ -997,8 +1032,8 @@ void ResourceDispatcherHostImpl::BeginRequest(
HasPendingCrossSiteRequest(child_id, route_id)) {
// Wrap the event handler to be sure the current page's onunload handler
// has a chance to run before we render the new page.
- handler.reset(
- new CrossSiteResourceHandler(handler.Pass(), child_id, route_id, this));
+ handler.reset(new CrossSiteResourceHandler(handler.Pass(), child_id,
+ route_id, request));
}
// Insert a buffered event handler before the actual one.
@@ -1031,44 +1066,6 @@ void ResourceDispatcherHostImpl::BeginRequest(
throttles.Pass()));
}
- bool allow_download = request_data.allow_download &&
- ResourceType::IsFrame(request_data.resource_type);
- // Make extra info and read footer (contains request ID).
- ResourceRequestInfoImpl* extra_info =
- new ResourceRequestInfoImpl(
- process_type,
- child_id,
- route_id,
- request_data.origin_pid,
- request_id,
- request_data.is_main_frame,
- request_data.frame_id,
- request_data.parent_is_main_frame,
- request_data.parent_frame_id,
- request_data.resource_type,
- request_data.transition_type,
- upload_size,
- false, // is download
- allow_download,
- request_data.has_user_gesture,
- request_data.referrer_policy,
- resource_context);
- extra_info->AssociateWithRequest(request); // Request takes ownership.
-
- if (request->url().SchemeIs(chrome::kBlobScheme)) {
- // Hang on to a reference to ensure the blob is not released prior
- // to the job being started.
- webkit_blob::BlobStorageController* controller =
- GetBlobStorageControllerForResourceContext(resource_context);
- extra_info->set_requested_blob_data(
- controller->GetBlobDataFromUrl(request->url()));
- }
-
- // Have the appcache associate its extra info with the request.
- appcache::AppCacheInterceptor::SetExtraRequestInfo(
- request, ResourceContext::GetAppCacheService(resource_context), child_id,
- request_data.appcache_host_id, request_data.resource_type);
-
if (deferred_loader.get()) {
pending_loaders_[extra_info->GetGlobalRequestID()] = deferred_loader;
deferred_loader->CompleteTransfer(handler.Pass());
@@ -1082,33 +1079,13 @@ void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) {
}
void ResourceDispatcherHostImpl::OnDataReceivedACK(int request_id) {
- DataReceivedACK(filter_->child_id(), request_id);
-}
-
-void ResourceDispatcherHostImpl::DataReceivedACK(int child_id,
- int request_id) {
- ResourceLoader* loader = GetLoader(child_id, request_id);
+ ResourceLoader* loader = GetLoader(filter_->child_id(), request_id);
if (!loader)
return;
ResourceRequestInfoImpl* info = loader->GetRequestInfo();
-
- // Decrement the number of pending data messages.
- info->DecrementPendingDataCount();
-
- // If the pending data count was higher than the max, resume the request.
- if (info->pending_data_count() == kMaxPendingDataMessages) {
- // Decrement the pending data count one more time because we also
- // incremented it before pausing the request.
- info->DecrementPendingDataCount();
-
- // Resume the request.
- //
- // TODO(darin): Make the AsyncResourceHandler be responsible for resuming
- // via its controller(). This static_cast is here as a temporary measure.
- //
- static_cast<ResourceController*>(loader)->Resume();
- }
+ if (info->async_handler())
+ info->async_handler()->OnDataReceivedACK();
}
void ResourceDispatcherHostImpl::OnDataDownloadedACK(int request_id) {
@@ -1172,8 +1149,12 @@ void ResourceDispatcherHostImpl::OnFollowRedirect(
return;
}
- loader->OnFollowRedirect(has_new_first_party_for_cookies,
- new_first_party_for_cookies);
+ ResourceRequestInfoImpl* info = loader->GetRequestInfo();
+ if (info->async_handler()) {
+ info->async_handler()->OnFollowRedirect(
+ has_new_first_party_for_cookies,
+ new_first_party_for_cookies);
+ }
}
ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
@@ -1288,28 +1269,6 @@ void ResourceDispatcherHostImpl::BeginSaveFile(
BeginRequestInternal(request.Pass(), handler.Pass());
}
-bool ResourceDispatcherHostImpl::WillSendData(int child_id, int request_id,
- bool* defer) {
- ResourceLoader* loader = GetLoader(child_id, request_id);
- if (!loader) {
- NOTREACHED() << "WillSendData for invalid request";
- return false;
- }
-
- ResourceRequestInfoImpl* info = loader->GetRequestInfo();
-
- info->IncrementPendingDataCount();
- if (info->pending_data_count() > kMaxPendingDataMessages) {
- // We reached the max number of data messages that can be sent to
- // the renderer for a given request. Pause the request and wait for
- // the renderer to start processing them before resuming it.
- *defer = true;
- return false;
- }
-
- return true;
-}
-
void ResourceDispatcherHostImpl::MarkAsTransferredNavigation(
const GlobalRequestID& id) {
GetLoader(id)->MarkAsTransferring();
@@ -1518,6 +1477,9 @@ void ResourceDispatcherHostImpl::BeginRequestInternal(
IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(),
info->GetChildID());
+
+ // A ResourceHandler must not outlive its associated URLRequest.
+ handler.reset();
return;
}
diff --git a/content/browser/renderer_host/resource_dispatcher_host_impl.h b/content/browser/renderer_host/resource_dispatcher_host_impl.h
index 9d0a9ff..d8fece0 100644
--- a/content/browser/renderer_host/resource_dispatcher_host_impl.h
+++ b/content/browser/renderer_host/resource_dispatcher_host_impl.h
@@ -122,11 +122,6 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
int request_id,
bool from_renderer);
- // Returns true if it's ok to send the data. If there are already too many
- // data messages pending, it pauses the request and returns false. In this
- // case the caller should not send the data.
- bool WillSendData(int child_id, int request_id, bool* defer);
-
// Marks the request as "parked". This happens if a request is
// redirected cross-site and needs to be resumed by a new render view.
void MarkAsTransferredNavigation(const GlobalRequestID& id);
@@ -193,11 +188,6 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
// Cancels any blocked request for the specified route id.
void CancelBlockedRequestsForRoute(int child_id, int route_id);
- // Decrements the pending_data_count for the request and resumes
- // the request if it was paused due to too many pending data
- // messages sent.
- void DataReceivedACK(int child_id, int request_id);
-
// Maintains a collection of temp files created in support of
// the download_to_file capability. Used to grant access to the
// child process and to defer deletion of the file until it's
diff --git a/content/browser/renderer_host/resource_dispatcher_host_unittest.cc b/content/browser/renderer_host/resource_dispatcher_host_unittest.cc
index 1987837..1e28d60 100644
--- a/content/browser/renderer_host/resource_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/resource_dispatcher_host_unittest.cc
@@ -11,6 +11,8 @@
#include "base/memory/scoped_vector.h"
#include "base/message_loop.h"
#include "base/process_util.h"
+#include "base/string_number_conversions.h"
+#include "base/string_split.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
@@ -30,6 +32,7 @@
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_job.h"
+#include "net/url_request/url_request_simple_job.h"
#include "net/url_request/url_request_test_job.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/appcache/appcache_interfaces.h"
@@ -55,6 +58,14 @@ void GetResponseHead(const std::vector<IPC::Message>& messages,
ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, response_head));
}
+void GenerateIPCMessage(
+ scoped_refptr<ResourceMessageFilter> filter,
+ scoped_ptr<IPC::Message> message) {
+ bool msg_is_ok;
+ ResourceDispatcherHostImpl::Get()->OnMessageReceived(
+ *message, filter.get(), &msg_is_ok);
+}
+
} // namespace
static int RequestIDForMessage(const IPC::Message& msg) {
@@ -114,6 +125,7 @@ class ResourceIPCAccumulator {
typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages;
void GetClassifiedMessages(ClassifiedMessages* msgs);
+ private:
std::vector<IPC::Message> messages_;
};
@@ -289,7 +301,45 @@ class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
virtual bool NextReadAsync() OVERRIDE { return true; }
};
+class URLRequestBigJob : public net::URLRequestSimpleJob {
+ public:
+ URLRequestBigJob(net::URLRequest* request)
+ : net::URLRequestSimpleJob(request) {
+ }
+
+ virtual bool GetData(std::string* mime_type,
+ std::string* charset,
+ std::string* data) const {
+ *mime_type = "text/plain";
+ *charset = "UTF-8";
+
+ std::string text;
+ int count;
+ if (!ParseURL(request_->url(), &text, &count))
+ return false;
+
+ data->reserve(text.size() * count);
+ for (int i = 0; i < count; ++i)
+ data->append(text);
+
+ return true;
+ }
+
+ private:
+ virtual ~URLRequestBigJob() {}
+
+ // big-job:substring,N
+ static bool ParseURL(const GURL& url, std::string* text, int* count) {
+ std::vector<std::string> parts;
+ base::SplitString(url.path(), ',', &parts);
+ if (parts.size() != 2)
+ return false;
+
+ *text = parts[0];
+ return base::StringToInt(parts[1], count);
+ }
+};
// Associated with an URLRequest to determine if the URLRequest gets deleted.
class TestUserData : public base::SupportsUserData::Data {
@@ -379,7 +429,8 @@ class ResourceDispatcherHostTest : public testing::Test,
cache_thread_(BrowserThread::CACHE, &message_loop_),
io_thread_(BrowserThread::IO, &message_loop_),
old_factory_(NULL),
- resource_type_(ResourceType::SUB_RESOURCE) {
+ resource_type_(ResourceType::SUB_RESOURCE),
+ send_data_received_acks_(false) {
browser_context_.reset(new content::TestBrowserContext());
BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
message_loop_.RunAllPending();
@@ -389,6 +440,12 @@ class ResourceDispatcherHostTest : public testing::Test,
// IPC::Message::Sender implementation
virtual bool Send(IPC::Message* msg) {
accum_.AddMessage(*msg);
+
+ if (send_data_received_acks_ &&
+ msg->type() == ResourceMsg_DataReceived::ID) {
+ GenerateDataReceivedACK(*msg);
+ }
+
delete msg;
return true;
}
@@ -447,11 +504,15 @@ class ResourceDispatcherHostTest : public testing::Test,
void CompleteStartRequest(int request_id);
- void EnsureTestSchemeIsAllowed() {
+ void EnsureSchemeIsAllowed(const std::string& scheme) {
ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance();
- if (!policy->IsWebSafeScheme("test"))
- policy->RegisterWebSafeScheme("test");
+ if (!policy->IsWebSafeScheme(scheme))
+ policy->RegisterWebSafeScheme(scheme);
+ }
+
+ void EnsureTestSchemeIsAllowed() {
+ EnsureSchemeIsAllowed("test");
}
// Sets a particular response for any request from now on. To switch back to
@@ -467,6 +528,10 @@ class ResourceDispatcherHostTest : public testing::Test,
resource_type_ = type;
}
+ void SendDataReceivedACKs(bool send_acks) {
+ send_data_received_acks_ = send_acks;
+ }
+
// Intercepts requests for the given protocol.
void HandleScheme(const std::string& scheme) {
DCHECK(scheme_.empty());
@@ -474,6 +539,7 @@ class ResourceDispatcherHostTest : public testing::Test,
scheme_ = scheme;
old_factory_ = net::URLRequest::Deprecated::RegisterProtocolFactory(
scheme_, &ResourceDispatcherHostTest::Factory);
+ EnsureSchemeIsAllowed(scheme);
}
// Our own net::URLRequestJob factory.
@@ -484,6 +550,8 @@ class ResourceDispatcherHostTest : public testing::Test,
return new URLRequestTestDelayedStartJob(request);
} else if (delay_complete_) {
return new URLRequestTestDelayedCompletionJob(request);
+ } else if (scheme == "big-job") {
+ return new URLRequestBigJob(request);
} else {
return new net::URLRequestTestJob(request);
}
@@ -513,6 +581,18 @@ class ResourceDispatcherHostTest : public testing::Test,
delay_complete_ = delay_job_complete;
}
+ void GenerateDataReceivedACK(const IPC::Message& msg) {
+ EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type());
+
+ int request_id = IPC::MessageIterator(msg).NextInt();
+ scoped_ptr<IPC::Message> ack(
+ new ResourceHostMsg_DataReceived_ACK(msg.routing_id(), request_id));
+
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack)));
+ }
+
MessageLoopForIO message_loop_;
BrowserThreadImpl ui_thread_;
BrowserThreadImpl file_thread_;
@@ -527,6 +607,7 @@ class ResourceDispatcherHostTest : public testing::Test,
std::string scheme_;
net::URLRequest::ProtocolFactory* old_factory_;
ResourceType::Type resource_type_;
+ bool send_data_received_acks_;
static ResourceDispatcherHostTest* test_fixture_;
static bool delay_start_;
static bool delay_complete_;
@@ -1434,4 +1515,68 @@ TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
EXPECT_EQ(net::ERR_UNKNOWN_URL_SCHEME, status.error());
}
+TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) {
+ EXPECT_EQ(0, host_.pending_requests());
+
+ SendDataReceivedACKs(true);
+
+ HandleScheme("big-job");
+ MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
+
+ // Sort all the messages we saw by request.
+ ResourceIPCAccumulator::ClassifiedMessages msgs;
+ accum_.GetClassifiedMessages(&msgs);
+
+ size_t size = msgs[0].size();
+
+ EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
+ for (size_t i = 1; i < size - 1; ++i)
+ EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
+ EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type());
+}
+
+TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) {
+ EXPECT_EQ(0, host_.pending_requests());
+
+ HandleScheme("big-job");
+ MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
+
+ // Sort all the messages we saw by request.
+ ResourceIPCAccumulator::ClassifiedMessages msgs;
+ accum_.GetClassifiedMessages(&msgs);
+
+ // We expect 1x ReceivedResponse + Nx ReceivedData messages.
+ EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
+ for (size_t i = 1; i < msgs[0].size(); ++i)
+ EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
+
+ // NOTE: If we fail the above checks then it means that we probably didn't
+ // load a big enough response to trigger the delay mechanism we are trying to
+ // test!
+
+ msgs[0].erase(msgs[0].begin());
+
+ // ACK all DataReceived messages until we find a RequestComplete message.
+ bool complete = false;
+ while (!complete) {
+ for (size_t i = 0; i < msgs[0].size(); ++i) {
+ if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
+ complete = true;
+ break;
+ }
+
+ EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
+
+ ResourceHostMsg_DataReceived_ACK msg(0, 1);
+ bool msg_was_ok;
+ host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
+ }
+
+ MessageLoop::current()->RunAllPending();
+
+ msgs.clear();
+ accum_.GetClassifiedMessages(&msgs);
+ }
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/resource_loader.cc b/content/browser/renderer_host/resource_loader.cc
index b5cba21..a1baea5 100644
--- a/content/browser/renderer_host/resource_loader.cc
+++ b/content/browser/renderer_host/resource_loader.cc
@@ -177,18 +177,6 @@ void ResourceLoader::OnUploadProgressACK() {
waiting_for_upload_progress_ack_ = false;
}
-void ResourceLoader::OnFollowRedirect(bool has_new_first_party_for_cookies,
- const GURL& new_first_party_for_cookies) {
- if (!request_->status().is_success()) {
- DVLOG(1) << "OnDeferredRedirect for invalid request";
- return;
- }
-
- if (has_new_first_party_for_cookies)
- request_->set_first_party_for_cookies(new_first_party_for_cookies);
- request_->FollowDeferredRedirect();
-}
-
void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused,
const GURL& new_url,
bool* defer) {
diff --git a/content/browser/renderer_host/resource_loader.h b/content/browser/renderer_host/resource_loader.h
index bb37cdd4..0b01f18 100644
--- a/content/browser/renderer_host/resource_loader.h
+++ b/content/browser/renderer_host/resource_loader.h
@@ -49,8 +49,6 @@ class ResourceLoader : public net::URLRequest::Delegate,
// IPC message handlers:
void OnUploadProgressACK();
- void OnFollowRedirect(bool has_new_first_party_for_cookies,
- const GURL& new_first_party_for_cookies);
private:
// net::URLRequest::Delegate implementation:
diff --git a/content/browser/renderer_host/resource_request_info_impl.cc b/content/browser/renderer_host/resource_request_info_impl.cc
index 501d3f0..c063d1d 100644
--- a/content/browser/renderer_host/resource_request_info_impl.cc
+++ b/content/browser/renderer_host/resource_request_info_impl.cc
@@ -98,6 +98,7 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
WebKit::WebReferrerPolicy referrer_policy,
ResourceContext* context)
: cross_site_handler_(NULL),
+ async_handler_(NULL),
process_type_(process_type),
child_id_(child_id),
route_id_(route_id),
@@ -107,7 +108,6 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
frame_id_(frame_id),
parent_is_main_frame_(parent_is_main_frame),
parent_frame_id_(parent_frame_id),
- pending_data_count_(0),
is_download_(is_download),
allow_download_(allow_download),
has_user_gesture_(has_user_gesture),
diff --git a/content/browser/renderer_host/resource_request_info_impl.h b/content/browser/renderer_host/resource_request_info_impl.h
index 11bc178..38a926d 100644
--- a/content/browser/renderer_host/resource_request_info_impl.h
+++ b/content/browser/renderer_host/resource_request_info_impl.h
@@ -25,6 +25,7 @@ class BlobData;
}
namespace content {
+class AsyncResourceHandler;
class CrossSiteResourceHandler;
class ResourceContext;
struct GlobalRequestID;
@@ -83,9 +84,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
GlobalRequestID GetGlobalRequestID() const;
- // CrossSiteResourceHandler for this request, if it is a cross-site request.
- // (NULL otherwise.) This handler is part of the chain of ResourceHandlers
- // pointed to by resource_handler, and is not owned by this class.
+ // CrossSiteResourceHandler for this request. May be null.
CrossSiteResourceHandler* cross_site_handler() {
return cross_site_handler_;
}
@@ -93,17 +92,19 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
cross_site_handler_ = h;
}
+ // AsyncResourceHandler for this request. May be null.
+ AsyncResourceHandler* async_handler() {
+ return async_handler_;
+ }
+ void set_async_handler(AsyncResourceHandler* h) {
+ async_handler_ = h;
+ }
+
// Identifies the type of process (renderer, plugin, etc.) making the request.
ProcessType process_type() const {
return process_type_;
}
- // Number of messages we've sent to the renderer that we haven't gotten an
- // ACK for. This allows us to avoid having too many messages in flight.
- int pending_data_count() const { return pending_data_count_; }
- void IncrementPendingDataCount() { pending_data_count_++; }
- void DecrementPendingDataCount() { pending_data_count_--; }
-
// Downloads are allowed only as a top level request.
bool allow_download() const { return allow_download_; }
@@ -130,6 +131,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
private:
// Non-owning, may be NULL.
CrossSiteResourceHandler* cross_site_handler_;
+ AsyncResourceHandler* async_handler_;
ProcessType process_type_;
int child_id_;
@@ -140,7 +142,6 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
int64 frame_id_;
bool parent_is_main_frame_;
int64 parent_frame_id_;
- int pending_data_count_;
bool is_download_;
bool allow_download_;
bool has_user_gesture_;
diff --git a/content/browser/renderer_host/sync_resource_handler.cc b/content/browser/renderer_host/sync_resource_handler.cc
index 5c149b7..90a098e 100644
--- a/content/browser/renderer_host/sync_resource_handler.cc
+++ b/content/browser/renderer_host/sync_resource_handler.cc
@@ -18,14 +18,15 @@ namespace content {
SyncResourceHandler::SyncResourceHandler(
ResourceMessageFilter* filter,
- const GURL& url,
+ net::URLRequest* request,
IPC::Message* result_message,
ResourceDispatcherHostImpl* resource_dispatcher_host)
: read_buffer_(new net::IOBuffer(kReadBufSize)),
filter_(filter),
+ request_(request),
result_message_(result_message),
rdh_(resource_dispatcher_host) {
- result_.final_url = url;
+ result_.final_url = request_->url();
}
SyncResourceHandler::~SyncResourceHandler() {
@@ -46,12 +47,10 @@ bool SyncResourceHandler::OnRequestRedirected(
const GURL& new_url,
ResourceResponse* response,
bool* defer) {
- net::URLRequest* request = rdh_->GetURLRequest(
- GlobalRequestID(filter_->child_id(), request_id));
if (rdh_->delegate())
- rdh_->delegate()->OnRequestRedirected(request, response);
+ rdh_->delegate()->OnRequestRedirected(request_, response);
- DevToolsNetLogObserver::PopulateResponseInfo(request, response);
+ DevToolsNetLogObserver::PopulateResponseInfo(request_, response);
// TODO(darin): It would be much better if this could live in WebCore, but
// doing so requires API changes at all levels. Similar code exists in
// WebCore/platform/network/cf/ResourceHandleCFNet.cpp :-(
@@ -67,12 +66,10 @@ bool SyncResourceHandler::OnResponseStarted(
int request_id,
ResourceResponse* response,
bool* defer) {
- net::URLRequest* request = rdh_->GetURLRequest(
- GlobalRequestID(filter_->child_id(), request_id));
if (rdh_->delegate())
- rdh_->delegate()->OnResponseStarted(request, response, filter_);
+ rdh_->delegate()->OnResponseStarted(request_, response, filter_);
- DevToolsNetLogObserver::PopulateResponseInfo(request, response);
+ DevToolsNetLogObserver::PopulateResponseInfo(request_, response);
// We don't care about copying the status here.
result_.headers = response->headers;
@@ -116,10 +113,8 @@ bool SyncResourceHandler::OnResponseCompleted(
const std::string& security_info) {
result_.status = status;
- net::URLRequest* request = rdh_->GetURLRequest(
- GlobalRequestID(filter_->child_id(), request_id));
result_.encoded_data_length =
- DevToolsNetLogObserver::GetAndResetEncodedDataLength(request);
+ DevToolsNetLogObserver::GetAndResetEncodedDataLength(request_);
ResourceHostMsg_SyncLoad::WriteReplyParams(result_message_, result_);
filter_->Send(result_message_);
diff --git a/content/browser/renderer_host/sync_resource_handler.h b/content/browser/renderer_host/sync_resource_handler.h
index 8e4d4b1..f60f2e1 100644
--- a/content/browser/renderer_host/sync_resource_handler.h
+++ b/content/browser/renderer_host/sync_resource_handler.h
@@ -17,6 +17,7 @@ class Message;
namespace net {
class IOBuffer;
+class URLRequest;
}
namespace content {
@@ -28,7 +29,7 @@ class ResourceMessageFilter;
class SyncResourceHandler : public ResourceHandler {
public:
SyncResourceHandler(ResourceMessageFilter* filter,
- const GURL& url,
+ net::URLRequest* request,
IPC::Message* result_message,
ResourceDispatcherHostImpl* resource_dispatcher_host);
virtual ~SyncResourceHandler();
@@ -64,6 +65,7 @@ class SyncResourceHandler : public ResourceHandler {
SyncLoadResult result_;
scoped_refptr<ResourceMessageFilter> filter_;
+ net::URLRequest* request_;
IPC::Message* result_message_;
ResourceDispatcherHostImpl* rdh_;
};