diff options
author | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-30 18:01:39 +0000 |
---|---|---|
committer | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-30 18:01:39 +0000 |
commit | 6568a9e384e0f92422c68d4f31fb401df4acbaed (patch) | |
tree | 477e1e2de4dd34d79e47a8a1e3b922ff3cecd83a /chrome/browser/renderer_host | |
parent | ae5ca890de8d9f1a91f5198741c76f375146693b (diff) | |
download | chromium_src-6568a9e384e0f92422c68d4f31fb401df4acbaed.zip chromium_src-6568a9e384e0f92422c68d4f31fb401df4acbaed.tar.gz chromium_src-6568a9e384e0f92422c68d4f31fb401df4acbaed.tar.bz2 |
Add plumbing for allowing the renderer to intercept and cancel redirects before
they are sent.
A good portion of this CL is to support the new UI test.
The IPC to notify the renderer of a redirect now includes a ResponseInfo struct
allowing WebURLLoaderImpl to provide detailed response info (including response
headers) to WebKit. This isn't strictly necessary, but I thought I'd include
this to make the code more future proof.
A cross origin restriction is added to SyncResourceHandler::OnRequestRedirected
that mimics the code in WebCore/platform/network/cf/ResourceHandleCFNet.cpp.
This is most unfortunate, and I filed a bug at bugs.webkit.org about the
similar duplication of logic in WebCore.
There seemed to be enough code paths leading to request cancellation at the
ResourceDispatcher level that I couldn't easily ensure that a request only gets
cancelled once. So, I added an is_cancelled flag to record if it is not
necessary to send a ViewHostMsg_CancelRequest IPC. This avoids some warnings
in the ResourceDispatcherHost.
To support my UI test, I needed to change URLRequestMockHttpJob to know how to
serve redirects. I moved URLRequestHttpJob::IsRedirectResponse to its base
class, URLRequestJob so that the implementation could be shared. This revealed
a minor bug in URLRequest. We were never resetting response_info_ upon
following a redirect. I added this code consolidated similar code from
URLRequest::Redirect and URLRequest::RestartWithJob into a new PrepareToRestart
method.
To support my UI test, I added a "hit count" field to URLRequestFilter, and I
added an associated automation IPC to query the value. The test was a bit
challenging to write because there is no way to tell the difference from JS.
Before and after, it appears to JS as though the cross-origin redirect failed.
However, the server can see the extra redirect request. So, I simply record
the number of hits against URLs of the form http://mock.http/foo, and use that
to observe if any extra requests were made. I implemented the new IPC message
by extending the AutomationResourceMessageFilter. This allowed me to trap the
IPC message on the IO thread where it is safe to probe the URLRequestFilter. I
then changed the implementation of AutomationMsg_SetFilteredInet to work
similarly.
I revised URLRequestMockHTTPJob::GetOnDiskPath to support ports. This actually
allowed me to reuse URLRequestMockHTTPJob to service URLs in different security
origins. My test redirects from http://mock.http/ to http://mock.http:4000/.
Please see the comments in cross-origin-redirect-blocked.html for details about
how the test functions.
R=brettw,wtc
BUG=16413
TEST=covered by resource_dispatcher_host_uitest.cc
Review URL: http://codereview.chromium.org/159370
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22067 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
20 files changed, 166 insertions, 76 deletions
diff --git a/chrome/browser/renderer_host/async_resource_handler.cc b/chrome/browser/renderer_host/async_resource_handler.cc index 6b69db3..dfd1f56 100644 --- a/chrome/browser/renderer_host/async_resource_handler.cc +++ b/chrome/browser/renderer_host/async_resource_handler.cc @@ -62,10 +62,12 @@ bool AsyncResourceHandler::OnUploadProgress(int request_id, } bool AsyncResourceHandler::OnRequestRedirected(int request_id, - const GURL& new_url) { - return receiver_->Send(new ViewMsg_Resource_ReceivedRedirect(routing_id_, - request_id, - new_url)); + const GURL& new_url, + ResourceResponse* response, + bool* defer) { + *defer = true; + return receiver_->Send(new ViewMsg_Resource_ReceivedRedirect( + routing_id_, request_id, new_url, response->response_head)); } bool AsyncResourceHandler::OnResponseStarted(int request_id, diff --git a/chrome/browser/renderer_host/async_resource_handler.h b/chrome/browser/renderer_host/async_resource_handler.h index 89ecfad..17e9260 100644 --- a/chrome/browser/renderer_host/async_resource_handler.h +++ b/chrome/browser/renderer_host/async_resource_handler.h @@ -26,7 +26,8 @@ class AsyncResourceHandler : public ResourceHandler { // ResourceHandler implementation: bool OnUploadProgress(int request_id, uint64 position, uint64 size); - bool OnRequestRedirected(int request_id, const GURL& new_url); + bool OnRequestRedirected(int request_id, const GURL& new_url, + ResourceResponse* response, bool* defer); bool OnResponseStarted(int request_id, ResourceResponse* response); bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, int min_size); diff --git a/chrome/browser/renderer_host/buffered_resource_handler.cc b/chrome/browser/renderer_host/buffered_resource_handler.cc index 8d0f17f..b1007fe 100644 --- a/chrome/browser/renderer_host/buffered_resource_handler.cc +++ b/chrome/browser/renderer_host/buffered_resource_handler.cc @@ -60,8 +60,11 @@ bool BufferedResourceHandler::OnUploadProgress(int request_id, } bool BufferedResourceHandler::OnRequestRedirected(int request_id, - const GURL& new_url) { - return real_handler_->OnRequestRedirected(request_id, new_url); + const GURL& new_url, + ResourceResponse* response, + bool* defer) { + return real_handler_->OnRequestRedirected( + request_id, new_url, response, defer); } bool BufferedResourceHandler::OnResponseStarted(int request_id, diff --git a/chrome/browser/renderer_host/buffered_resource_handler.h b/chrome/browser/renderer_host/buffered_resource_handler.h index e553aca..3799b99 100644 --- a/chrome/browser/renderer_host/buffered_resource_handler.h +++ b/chrome/browser/renderer_host/buffered_resource_handler.h @@ -21,7 +21,8 @@ class BufferedResourceHandler : public ResourceHandler { // ResourceHandler implementation: bool OnUploadProgress(int request_id, uint64 position, uint64 size); - bool OnRequestRedirected(int request_id, const GURL& new_url); + bool OnRequestRedirected(int request_id, const GURL& new_url, + ResourceResponse* response, bool* defer); bool OnResponseStarted(int request_id, ResourceResponse* response); bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, int min_size); diff --git a/chrome/browser/renderer_host/cross_site_resource_handler.cc b/chrome/browser/renderer_host/cross_site_resource_handler.cc index 7b05a72..eb688e7 100644 --- a/chrome/browser/renderer_host/cross_site_resource_handler.cc +++ b/chrome/browser/renderer_host/cross_site_resource_handler.cc @@ -84,10 +84,13 @@ CrossSiteResourceHandler::CrossSiteResourceHandler( rdh_(resource_dispatcher_host) {} bool CrossSiteResourceHandler::OnRequestRedirected(int request_id, - const GURL& new_url) { + const GURL& new_url, + ResourceResponse* response, + bool* defer) { // We should not have started the transition before being redirected. DCHECK(!in_cross_site_transition_); - return next_handler_->OnRequestRedirected(request_id, new_url); + return next_handler_->OnRequestRedirected( + request_id, new_url, response, defer); } bool CrossSiteResourceHandler::OnResponseStarted(int request_id, diff --git a/chrome/browser/renderer_host/cross_site_resource_handler.h b/chrome/browser/renderer_host/cross_site_resource_handler.h index b741aa0..b50e641 100644 --- a/chrome/browser/renderer_host/cross_site_resource_handler.h +++ b/chrome/browser/renderer_host/cross_site_resource_handler.h @@ -21,7 +21,8 @@ class CrossSiteResourceHandler : public ResourceHandler { ResourceDispatcherHost* resource_dispatcher_host); // ResourceHandler implementation: - bool OnRequestRedirected(int request_id, const GURL& new_url); + bool OnRequestRedirected(int request_id, const GURL& new_url, + ResourceResponse* response, bool* defer); bool OnResponseStarted(int request_id, ResourceResponse* response); bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, diff --git a/chrome/browser/renderer_host/download_resource_handler.cc b/chrome/browser/renderer_host/download_resource_handler.cc index 6661666..8b189bf 100644 --- a/chrome/browser/renderer_host/download_resource_handler.cc +++ b/chrome/browser/renderer_host/download_resource_handler.cc @@ -35,7 +35,9 @@ DownloadResourceHandler::DownloadResourceHandler(ResourceDispatcherHost* rdh, // Not needed, as this event handler ought to be the final resource. bool DownloadResourceHandler::OnRequestRedirected(int request_id, - const GURL& url) { + const GURL& url, + ResourceResponse* response, + bool* defer) { url_ = url; return true; } diff --git a/chrome/browser/renderer_host/download_resource_handler.h b/chrome/browser/renderer_host/download_resource_handler.h index d9afa42..e4613a8 100644 --- a/chrome/browser/renderer_host/download_resource_handler.h +++ b/chrome/browser/renderer_host/download_resource_handler.h @@ -25,7 +25,8 @@ class DownloadResourceHandler : public ResourceHandler { bool save_as); // Not needed, as this event handler ought to be the final resource. - bool OnRequestRedirected(int request_id, const GURL& url); + bool OnRequestRedirected(int request_id, const GURL& url, + ResourceResponse* response, bool* defer); // Send the download creation information to the download thread. bool OnResponseStarted(int request_id, ResourceResponse* response); diff --git a/chrome/browser/renderer_host/download_throttling_resource_handler.cc b/chrome/browser/renderer_host/download_throttling_resource_handler.cc index f3ad5bb..ee286db 100644 --- a/chrome/browser/renderer_host/download_throttling_resource_handler.cc +++ b/chrome/browser/renderer_host/download_throttling_resource_handler.cc @@ -41,10 +41,15 @@ bool DownloadThrottlingResourceHandler::OnUploadProgress(int request_id, return true; } -bool DownloadThrottlingResourceHandler::OnRequestRedirected(int request_id, - const GURL& url) { - if (download_handler_.get()) - return download_handler_->OnRequestRedirected(request_id, url); +bool DownloadThrottlingResourceHandler::OnRequestRedirected( + int request_id, + const GURL& url, + ResourceResponse* response, + bool* defer) { + if (download_handler_.get()) { + return download_handler_->OnRequestRedirected( + request_id, url, response, defer); + } url_ = url; return true; } diff --git a/chrome/browser/renderer_host/download_throttling_resource_handler.h b/chrome/browser/renderer_host/download_throttling_resource_handler.h index 5a2eea9..117b3d2 100644 --- a/chrome/browser/renderer_host/download_throttling_resource_handler.h +++ b/chrome/browser/renderer_host/download_throttling_resource_handler.h @@ -40,7 +40,8 @@ class DownloadThrottlingResourceHandler virtual bool OnUploadProgress(int request_id, uint64 position, uint64 size); - virtual bool OnRequestRedirected(int request_id, const GURL& url); + virtual bool OnRequestRedirected(int request_id, const GURL& url, + ResourceResponse* response, bool* defer); virtual bool OnResponseStarted(int request_id, ResourceResponse* response); virtual bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, int min_size); diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc index a626f06..94bf0b6 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc @@ -227,6 +227,20 @@ bool ShouldServiceRequest(ChildProcessInfo::ProcessType process_type, return true; } +void PopulateResourceResponse(URLRequest* request, + FilterPolicy::Type filter_policy, + ResourceResponse* response) { + response->response_head.status = request->status(); + response->response_head.request_time = request->request_time(); + response->response_head.response_time = request->response_time(); + response->response_head.headers = request->response_headers(); + request->GetCharset(&response->response_head.charset); + response->response_head.filter_policy = filter_policy; + response->response_head.content_length = request->GetExpectedContentSize(); + response->response_head.app_cache_id = WebAppCacheContext::kNoAppCacheId; + request->GetMimeType(&response->response_head.mime_type); +} + } // namespace ResourceDispatcherHost::ResourceDispatcherHost(MessageLoop* io_loop) @@ -328,6 +342,7 @@ bool ResourceDispatcherHost::OnMessageReceived(const IPC::Message& message, IPC_MESSAGE_HANDLER(ViewHostMsg_DataReceived_ACK, OnDataReceivedACK) IPC_MESSAGE_HANDLER(ViewHostMsg_UploadProgress_ACK, OnUploadProgressACK) IPC_MESSAGE_HANDLER(ViewHostMsg_CancelRequest, OnCancelRequest) + IPC_MESSAGE_HANDLER(ViewHostMsg_FollowRedirect, OnFollowRedirect) IPC_MESSAGE_HANDLER(ViewHostMsg_ClosePage_ACK, OnClosePageACK) IPC_END_MESSAGE_MAP_EX() @@ -571,6 +586,10 @@ void ResourceDispatcherHost::OnCancelRequest(int request_id) { CancelRequest(receiver_->GetProcessId(), request_id, true, true); } +void ResourceDispatcherHost::OnFollowRedirect(int request_id) { + FollowDeferredRedirect(receiver_->GetProcessId(), request_id); +} + void ResourceDispatcherHost::OnClosePageACK( const ViewMsg_ClosePage_Params& params) { if (params.for_cross_site_transition) { @@ -731,47 +750,16 @@ void ResourceDispatcherHost::CancelRequest(int process_id, CancelRequest(process_id, request_id, from_renderer, true); } -void ResourceDispatcherHost::CancelRequest(int process_id, - int request_id, - bool from_renderer, - bool allow_delete) { +void ResourceDispatcherHost::FollowDeferredRedirect(int process_id, + int request_id) { PendingRequestList::iterator i = pending_requests_.find( GlobalRequestID(process_id, request_id)); if (i == pending_requests_.end()) { - // We probably want to remove this warning eventually, but I wanted to be - // able to notice when this happens during initial development since it - // should be rare and may indicate a bug. - DLOG(WARNING) << "Canceling a request that wasn't found"; + DLOG(WARNING) << "FollowDeferredRedirect for invalid request"; return; } - // WebKit will send us a cancel for downloads since it no longer handles them. - // In this case, ignore the cancel since we handle downloads in the browser. - ExtraRequestInfo* info = ExtraInfoForRequest(i->second); - if (!from_renderer || !info->is_download) { - if (info->login_handler) { - info->login_handler->OnRequestCancelled(); - info->login_handler = NULL; - } - if (info->ssl_client_auth_handler) { - info->ssl_client_auth_handler->OnRequestCancelled(); - info->ssl_client_auth_handler = NULL; - } - if (!i->second->is_pending() && allow_delete) { - // No io is pending, canceling the request won't notify us of anything, - // so we explicitly remove it. - // TODO(sky): removing the request in this manner means we're not - // notifying anyone. We need make sure the event handlers and others are - // notified so that everything is cleaned up properly. - RemovePendingRequest(info->process_id, info->request_id); - } else { - i->second->Cancel(); - } - } - - // Do not remove from the pending requests, as the request will still - // call AllDataReceived, and may even have more data before it does - // that. + i->second->FollowDeferredRedirect(); } bool ResourceDispatcherHost::WillSendData(int process_id, @@ -779,7 +767,7 @@ bool ResourceDispatcherHost::WillSendData(int process_id, PendingRequestList::iterator i = pending_requests_.find( GlobalRequestID(process_id, request_id)); if (i == pending_requests_.end()) { - NOTREACHED() << L"WillSendData for invalid request"; + NOTREACHED() << "WillSendData for invalid request"; return false; } @@ -968,7 +956,10 @@ void ResourceDispatcherHost::OnReceivedRedirect(URLRequest* request, return; } - if (!info->resource_handler->OnRequestRedirected(info->request_id, new_url)) + scoped_refptr<ResourceResponse> response = new ResourceResponse; + PopulateResourceResponse(request, info->filter_policy, response); + if (!info->resource_handler->OnRequestRedirected(info->request_id, new_url, + response, defer_redirect)) CancelRequest(info->process_id, info->request_id, false); } @@ -1050,17 +1041,8 @@ void ResourceDispatcherHost::OnResponseStarted(URLRequest* request) { bool ResourceDispatcherHost::CompleteResponseStarted(URLRequest* request) { ExtraRequestInfo* info = ExtraInfoForRequest(request); - scoped_refptr<ResourceResponse> response(new ResourceResponse); - - response->response_head.status = request->status(); - response->response_head.request_time = request->request_time(); - response->response_head.response_time = request->response_time(); - response->response_head.headers = request->response_headers(); - request->GetCharset(&response->response_head.charset); - response->response_head.filter_policy = info->filter_policy; - response->response_head.content_length = request->GetExpectedContentSize(); - response->response_head.app_cache_id = WebAppCacheContext::kNoAppCacheId; - request->GetMimeType(&response->response_head.mime_type); + scoped_refptr<ResourceResponse> response = new ResourceResponse; + PopulateResourceResponse(request, info->filter_policy, response); const URLRequest::UserData* d = request->GetUserData(&Blacklist::kRequestDataKey); @@ -1093,6 +1075,49 @@ bool ResourceDispatcherHost::CompleteResponseStarted(URLRequest* request) { response.get()); } +void ResourceDispatcherHost::CancelRequest(int process_id, + int request_id, + bool from_renderer, + bool allow_delete) { + PendingRequestList::iterator i = pending_requests_.find( + GlobalRequestID(process_id, request_id)); + if (i == pending_requests_.end()) { + // We probably want to remove this warning eventually, but I wanted to be + // able to notice when this happens during initial development since it + // should be rare and may indicate a bug. + DLOG(WARNING) << "Canceling a request that wasn't found"; + return; + } + + // WebKit will send us a cancel for downloads since it no longer handles them. + // In this case, ignore the cancel since we handle downloads in the browser. + ExtraRequestInfo* info = ExtraInfoForRequest(i->second); + if (!from_renderer || !info->is_download) { + if (info->login_handler) { + info->login_handler->OnRequestCancelled(); + info->login_handler = NULL; + } + if (info->ssl_client_auth_handler) { + info->ssl_client_auth_handler->OnRequestCancelled(); + info->ssl_client_auth_handler = NULL; + } + if (!i->second->is_pending() && allow_delete) { + // No io is pending, canceling the request won't notify us of anything, + // so we explicitly remove it. + // TODO(sky): removing the request in this manner means we're not + // notifying anyone. We need make sure the event handlers and others are + // notified so that everything is cleaned up properly. + RemovePendingRequest(info->process_id, info->request_id); + } else { + i->second->Cancel(); + } + } + + // Do not remove from the pending requests, as the request will still + // call AllDataReceived, and may even have more data before it does + // that. +} + int ResourceDispatcherHost::IncrementOutstandingRequestsMemoryCost( int cost, int process_id) { // Retrieve the previous value (defaulting to 0 if not found). @@ -1675,6 +1700,7 @@ bool ResourceDispatcherHost::IsResourceDispatcherHostMessage( switch (message.type()) { case ViewHostMsg_RequestResource::ID: case ViewHostMsg_CancelRequest::ID: + case ViewHostMsg_FollowRedirect::ID: case ViewHostMsg_ClosePage_ACK::ID: case ViewHostMsg_DataReceived_ACK::ID: case ViewHostMsg_DownloadProgress_ACK::ID: diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.h b/chrome/browser/renderer_host/resource_dispatcher_host.h index b75d408..5353562 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.h +++ b/chrome/browser/renderer_host/resource_dispatcher_host.h @@ -250,6 +250,10 @@ class ResourceDispatcherHost : public URLRequest::Delegate { int request_id, bool from_renderer); + // Follows a deferred redirect for the given request. + void FollowDeferredRedirect(int process_id, + int request_id); + // 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. @@ -503,6 +507,7 @@ class ResourceDispatcherHost : public URLRequest::Delegate { void OnDataReceivedACK(int request_id); void OnUploadProgressACK(int request_id); void OnCancelRequest(int request_id); + void OnFollowRedirect(int request_id); // Returns true if the message passed in is a resource related message. static bool IsResourceDispatcherHostMessage(const IPC::Message&); diff --git a/chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc b/chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc index c13d3c2..d8654fd 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc @@ -314,4 +314,21 @@ TEST_F(ResourceDispatcherTest, CrossSiteNavigationErrorPage) { EXPECT_EQ(L"Title Of Awesomeness", tab_title); } +TEST_F(ResourceDispatcherTest, CrossOriginRedirectBlocked) { + int before = automation()->GetFilteredInetHitCount(); + CheckTitleTest(L"cross-origin-redirect-blocked.html", + L"done"); + int after = automation()->GetFilteredInetHitCount(); + // + // We expect the following URL requests from this test: + // 1- http://mock.http/cross-origin-redirect-blocked.html + // 2- http://mock.http/redirect-to-title2.html + // 3- http://mock.http/title2.html + // + // If the redirect in #2 were not blocked, we'd also see a request + // for http://mock.http:4000/title2.html. + // + EXPECT_EQ(3, after - before); +} + } // namespace diff --git a/chrome/browser/renderer_host/resource_handler.h b/chrome/browser/renderer_host/resource_handler.h index df1b8a6..76851b6 100644 --- a/chrome/browser/renderer_host/resource_handler.h +++ b/chrome/browser/renderer_host/resource_handler.h @@ -63,8 +63,12 @@ class ResourceHandler : public base::RefCounted<ResourceHandler> { return true; } - // The request was redirected to a new URL. - virtual bool OnRequestRedirected(int request_id, const GURL& url) = 0; + // The request was redirected to a new URL. |*defer| has an initial value of + // false. Set |*defer| to true to defer the redirect. The redirect may be + // followed later on via ResourceDispatcherHost::FollowDeferredRedirect. + virtual bool OnRequestRedirected(int request_id, const GURL& url, + ResourceResponse* response, + bool* defer) = 0; // Response headers and meta data are available. virtual bool OnResponseStarted(int request_id, diff --git a/chrome/browser/renderer_host/safe_browsing_resource_handler.cc b/chrome/browser/renderer_host/safe_browsing_resource_handler.cc index 0d2af57..c215262 100644 --- a/chrome/browser/renderer_host/safe_browsing_resource_handler.cc +++ b/chrome/browser/renderer_host/safe_browsing_resource_handler.cc @@ -56,8 +56,11 @@ bool SafeBrowsingResourceHandler::OnUploadProgress(int request_id, return next_handler_->OnUploadProgress(request_id, position, size); } -bool SafeBrowsingResourceHandler::OnRequestRedirected(int request_id, - const GURL& new_url) { +bool SafeBrowsingResourceHandler::OnRequestRedirected( + int request_id, + const GURL& new_url, + ResourceResponse* response, + bool* defer) { if (in_safe_browsing_check_) { Release(); in_safe_browsing_check_ = false; @@ -73,7 +76,8 @@ bool SafeBrowsingResourceHandler::OnRequestRedirected(int request_id, // Can't pause now because it's too early, so we'll do it in OnWillRead. } - return next_handler_->OnRequestRedirected(request_id, new_url); + return next_handler_->OnRequestRedirected( + request_id, new_url, response, defer); } bool SafeBrowsingResourceHandler::OnResponseStarted( diff --git a/chrome/browser/renderer_host/safe_browsing_resource_handler.h b/chrome/browser/renderer_host/safe_browsing_resource_handler.h index 44018b1..e2901e8 100644 --- a/chrome/browser/renderer_host/safe_browsing_resource_handler.h +++ b/chrome/browser/renderer_host/safe_browsing_resource_handler.h @@ -30,7 +30,8 @@ class SafeBrowsingResourceHandler : public ResourceHandler, // ResourceHandler implementation: bool OnUploadProgress(int request_id, uint64 position, uint64 size); - bool OnRequestRedirected(int request_id, const GURL& new_url); + bool OnRequestRedirected(int request_id, const GURL& new_url, + ResourceResponse* response, bool* defer); bool OnResponseStarted(int request_id, ResourceResponse* response); void OnGetHashTimeout(); bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, diff --git a/chrome/browser/renderer_host/save_file_resource_handler.cc b/chrome/browser/renderer_host/save_file_resource_handler.cc index 3289df1..22f3441 100644 --- a/chrome/browser/renderer_host/save_file_resource_handler.cc +++ b/chrome/browser/renderer_host/save_file_resource_handler.cc @@ -23,7 +23,9 @@ SaveFileResourceHandler::SaveFileResourceHandler(int render_process_host_id, } bool SaveFileResourceHandler::OnRequestRedirected(int request_id, - const GURL& url) { + const GURL& url, + ResourceResponse* response, + bool* defer) { final_url_ = url; return true; } diff --git a/chrome/browser/renderer_host/save_file_resource_handler.h b/chrome/browser/renderer_host/save_file_resource_handler.h index bc3548c..9a976b2 100644 --- a/chrome/browser/renderer_host/save_file_resource_handler.h +++ b/chrome/browser/renderer_host/save_file_resource_handler.h @@ -21,7 +21,8 @@ class SaveFileResourceHandler : public ResourceHandler { // Saves the redirected URL to final_url_, we need to use the original // URL to match original request. - bool OnRequestRedirected(int request_id, const GURL& url); + bool OnRequestRedirected(int request_id, const GURL& url, + ResourceResponse* response, bool* defer); // Sends the download creation information to the download thread. bool OnResponseStarted(int request_id, ResourceResponse* response); diff --git a/chrome/browser/renderer_host/sync_resource_handler.cc b/chrome/browser/renderer_host/sync_resource_handler.cc index 01d0d8f..dd279a0 100644 --- a/chrome/browser/renderer_host/sync_resource_handler.cc +++ b/chrome/browser/renderer_host/sync_resource_handler.cc @@ -26,7 +26,16 @@ SyncResourceHandler::~SyncResourceHandler() { } bool SyncResourceHandler::OnRequestRedirected(int request_id, - const GURL& new_url) { + const GURL& new_url, + ResourceResponse* response, + bool* defer) { + // 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 :-( + if (new_url.GetOrigin() != result_.final_url.GetOrigin()) { + LOG(ERROR) << "Cross origin redirect denied"; + return false; + } result_.final_url = new_url; return true; } diff --git a/chrome/browser/renderer_host/sync_resource_handler.h b/chrome/browser/renderer_host/sync_resource_handler.h index 8aa4681..615d7473 100644 --- a/chrome/browser/renderer_host/sync_resource_handler.h +++ b/chrome/browser/renderer_host/sync_resource_handler.h @@ -20,7 +20,8 @@ class SyncResourceHandler : public ResourceHandler { IPC::Message* result_message); ~SyncResourceHandler(); - bool OnRequestRedirected(int request_id, const GURL& new_url); + bool OnRequestRedirected(int request_id, const GURL& new_url, + ResourceResponse* response, bool* defer); bool OnResponseStarted(int request_id, ResourceResponse* response); bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, int min_size); |