summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclamy <clamy@chromium.org>2015-11-20 06:55:49 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-20 14:56:37 +0000
commit94ca34e7e6c05e75f2c10a87b76a1839d96a1ebd (patch)
tree66f293a4e55da875afa0bc05e004c44bee3bf20b
parente0807cfe3196f5313211d8938c155f43ea2b416d (diff)
downloadchromium_src-94ca34e7e6c05e75f2c10a87b76a1839d96a1ebd.zip
chromium_src-94ca34e7e6c05e75f2c10a87b76a1839d96a1ebd.tar.gz
chromium_src-94ca34e7e6c05e75f2c10a87b76a1839d96a1ebd.tar.bz2
Add a method in NavigationHandle to get the HttpResponseHeaders
This CL adds a method in NavigationHandle to get the HttpResponseHeaders, received after a navigation has encountered a redirect or is ready to commit. BUG=537634 Review URL: https://codereview.chromium.org/1409993018 Cr-Commit-Position: refs/heads/master@{#360818}
-rw-r--r--content/browser/frame_host/navigation_handle_impl.cc24
-rw-r--r--content/browser/frame_host/navigation_handle_impl.h29
-rw-r--r--content/browser/frame_host/navigation_handle_impl_unittest.cc2
-rw-r--r--content/browser/frame_host/navigation_request.cc5
-rw-r--r--content/browser/frame_host/navigator_impl.cc6
-rw-r--r--content/browser/loader/navigation_resource_throttle.cc75
-rw-r--r--content/browser/loader/navigation_resource_throttle.h1
7 files changed, 120 insertions, 22 deletions
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc
index 6ac5243..4fcb2c6c 100644
--- a/content/browser/frame_host/navigation_handle_impl.cc
+++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -159,6 +159,13 @@ bool NavigationHandleImpl::IsSamePage() {
return is_same_page_;
}
+const net::HttpResponseHeaders* NavigationHandleImpl::GetResponseHeaders() {
+ DCHECK(state_ >= WILL_REDIRECT_REQUEST)
+ << "This accessor should only be called when the request encountered a "
+ "redirect or received a response";
+ return response_headers_.get();
+}
+
bool NavigationHandleImpl::HasCommitted() {
return state_ == DID_COMMIT || state_ == DID_COMMIT_ERROR_PAGE;
}
@@ -220,6 +227,7 @@ NavigationHandleImpl::CallWillRedirectRequestForTesting(
NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::DEFER;
WillRedirectRequest(new_url, new_method_is_post, new_referrer_url,
new_is_external_protocol,
+ scoped_refptr<net::HttpResponseHeaders>(),
base::Bind(&UpdateThrottleCheckResult, &result));
// Reset the callback to ensure it will not be called later.
@@ -269,6 +277,7 @@ void NavigationHandleImpl::WillRedirectRequest(
bool new_method_is_post,
const GURL& new_referrer_url,
bool new_is_external_protocol,
+ scoped_refptr<net::HttpResponseHeaders> response_headers,
const ThrottleChecksFinishedCallback& callback) {
// Update the navigation parameters.
url_ = new_url;
@@ -276,6 +285,7 @@ void NavigationHandleImpl::WillRedirectRequest(
sanitized_referrer_.url = new_referrer_url;
sanitized_referrer_ = Referrer::SanitizeForRequest(url_, sanitized_referrer_);
is_external_protocol_ = new_is_external_protocol;
+ response_headers_ = response_headers;
state_ = WILL_REDIRECT_REQUEST;
complete_callback_ = callback;
@@ -294,11 +304,19 @@ void NavigationHandleImpl::DidRedirectNavigation(const GURL& new_url) {
}
void NavigationHandleImpl::ReadyToCommitNavigation(
- RenderFrameHostImpl* render_frame_host) {
- CHECK(!render_frame_host_);
+ RenderFrameHostImpl* render_frame_host,
+ scoped_refptr<net::HttpResponseHeaders> response_headers) {
+ DCHECK(!render_frame_host_);
render_frame_host_ = render_frame_host;
+ response_headers_ = response_headers;
state_ = READY_TO_COMMIT;
- GetDelegate()->ReadyToCommitNavigation(this);
+
+ // Only notify the WebContentsObservers when PlzNavigate is enabled, as
+ // |render_frame_host_| may be wrong in the case of transfer navigations.
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation)) {
+ GetDelegate()->ReadyToCommitNavigation(this);
+ }
}
void NavigationHandleImpl::DidCommitNavigation(
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h
index 622512f..70fb99e 100644
--- a/content/browser/frame_host/navigation_handle_impl.h
+++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -100,6 +100,12 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
NavigatorDelegate* GetDelegate() const;
+ // Returns the response headers for the request. This can only be accessed
+ // after a redirect was encountered or after the the navigation is ready to
+ // commit. It should not be modified, as modifications will not be reflected
+ // in the network stack.
+ const net::HttpResponseHeaders* GetResponseHeaders();
+
void set_net_error_code(net::Error net_error_code) {
net_error_code_ = net_error_code;
}
@@ -113,6 +119,12 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
is_transferring_ = is_transferring;
}
+ // Updates the RenderFrameHost that is about to commit the navigation. This
+ // is used during transfer navigations.
+ void set_render_frame_host(RenderFrameHostImpl* render_frame_host) {
+ render_frame_host_ = render_frame_host;
+ }
+
// PlzNavigate
ServiceWorkerNavigationHandle* service_worker_handle() const {
return service_worker_handle_.get();
@@ -134,11 +146,13 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
// Called when the URLRequest will be redirected in the network stack.
// |callback| will be called when all throttles check have completed. This
// will allow the caller to cancel the navigation or let it proceed.
- void WillRedirectRequest(const GURL& new_url,
- bool new_method_is_post,
- const GURL& new_referrer_url,
- bool new_is_external_protocol,
- const ThrottleChecksFinishedCallback& callback);
+ void WillRedirectRequest(
+ const GURL& new_url,
+ bool new_method_is_post,
+ const GURL& new_referrer_url,
+ bool new_is_external_protocol,
+ scoped_refptr<net::HttpResponseHeaders> response_headers,
+ const ThrottleChecksFinishedCallback& callback);
// Called when the navigation was redirected. This will update the |url_| and
// inform the delegate.
@@ -147,7 +161,9 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
// Called when the navigation is ready to be committed in
// |render_frame_host|. This will update the |state_| and inform the
// delegate.
- void ReadyToCommitNavigation(RenderFrameHostImpl* render_frame_host);
+ void ReadyToCommitNavigation(
+ RenderFrameHostImpl* render_frame_host,
+ scoped_refptr<net::HttpResponseHeaders> response_headers);
// Called when the navigation was committed in |render_frame_host|. This will
// update the |state_|.
@@ -194,6 +210,7 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
net::Error net_error_code_;
RenderFrameHostImpl* render_frame_host_;
bool is_same_page_;
+ scoped_refptr<net::HttpResponseHeaders> response_headers_;
// The state the navigation is in.
State state_;
diff --git a/content/browser/frame_host/navigation_handle_impl_unittest.cc b/content/browser/frame_host/navigation_handle_impl_unittest.cc
index cd2d0ec..ee999cb 100644
--- a/content/browser/frame_host/navigation_handle_impl_unittest.cc
+++ b/content/browser/frame_host/navigation_handle_impl_unittest.cc
@@ -103,7 +103,7 @@ class NavigationHandleImplTest : public RenderViewHostImplTestHarness {
// It's safe to use base::Unretained since the NavigationHandle is owned by
// the NavigationHandleImplTest.
test_handle_->WillRedirectRequest(
- GURL(), false, GURL(), false,
+ GURL(), false, GURL(), false, scoped_refptr<net::HttpResponseHeaders>(),
base::Bind(&NavigationHandleImplTest::UpdateThrottleCheckResult,
base::Unretained(this)));
}
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index fbabed6..7c7dcd6 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -17,6 +17,7 @@
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/stream_handle.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/resource_response.h"
#include "net/base/load_flags.h"
#include "net/http/http_request_headers.h"
#include "net/url_request/redirect_info.h"
@@ -224,8 +225,6 @@ void NavigationRequest::CreateNavigationHandle() {
void NavigationRequest::TransferNavigationHandleOwnership(
RenderFrameHostImpl* render_frame_host) {
render_frame_host->SetNavigationHandle(navigation_handle_.Pass());
- render_frame_host->navigation_handle()->ReadyToCommitNavigation(
- render_frame_host);
}
void NavigationRequest::OnRequestRedirected(
@@ -243,7 +242,7 @@ void NavigationRequest::OnRequestRedirected(
// TODO(clamy): pass the real value for |is_external_protocol| if needed.
navigation_handle_->WillRedirectRequest(
common_params_.url, begin_params_.method == "POST",
- common_params_.referrer.url, false,
+ common_params_.referrer.url, false, response->head.headers,
base::Bind(&NavigationRequest::OnRedirectChecksComplete,
base::Unretained(this)));
}
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 0b83a77..742445a 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -151,6 +151,8 @@ void NavigatorImpl::DidStartProvisionalLoad(
// DidStartProvisionalLoad should not correspond to a new navigation.
DCHECK_EQ(url, render_frame_host->navigation_handle()->GetURL());
render_frame_host->navigation_handle()->set_is_transferring(false);
+ render_frame_host->navigation_handle()->set_render_frame_host(
+ render_frame_host);
return;
}
@@ -749,6 +751,8 @@ void NavigatorImpl::CommitNavigation(FrameTreeNode* frame_tree_node,
render_frame_host, navigation_request->common_params().url);
navigation_request->TransferNavigationHandleOwnership(render_frame_host);
+ render_frame_host->navigation_handle()->ReadyToCommitNavigation(
+ render_frame_host, response ? response->head.headers : nullptr);
render_frame_host->CommitNavigation(response, body.Pass(),
navigation_request->common_params(),
navigation_request->request_params());
@@ -779,6 +783,8 @@ void NavigatorImpl::FailedNavigation(FrameTreeNode* frame_tree_node,
render_frame_host, navigation_request->common_params().url);
navigation_request->TransferNavigationHandleOwnership(render_frame_host);
+ render_frame_host->navigation_handle()->ReadyToCommitNavigation(
+ render_frame_host, scoped_refptr<net::HttpResponseHeaders>());
render_frame_host->FailedNavigation(navigation_request->common_params(),
navigation_request->request_params(),
has_stale_copy_in_cache, error_code);
diff --git a/content/browser/loader/navigation_resource_throttle.cc b/content/browser/loader/navigation_resource_throttle.cc
index efb3ac9..44fd0c1 100644
--- a/content/browser/loader/navigation_resource_throttle.cc
+++ b/content/browser/loader/navigation_resource_throttle.cc
@@ -59,13 +59,15 @@ void CheckWillStartRequestOnUIThread(UIChecksPerformedCallback callback,
is_external_protocol, base::Bind(&SendCheckResultToIOThread, callback));
}
-void CheckWillRedirectRequestOnUIThread(UIChecksPerformedCallback callback,
- int render_process_id,
- int render_frame_host_id,
- const GURL& new_url,
- bool new_method_is_post,
- const GURL& new_referrer_url,
- bool new_is_external_protocol) {
+void CheckWillRedirectRequestOnUIThread(
+ UIChecksPerformedCallback callback,
+ int render_process_id,
+ int render_frame_host_id,
+ const GURL& new_url,
+ bool new_method_is_post,
+ const GURL& new_referrer_url,
+ bool new_is_external_protocol,
+ scoped_refptr<net::HttpResponseHeaders> headers) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderFrameHostImpl* render_frame_host =
RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id);
@@ -86,10 +88,28 @@ void CheckWillRedirectRequestOnUIThread(UIChecksPerformedCallback callback,
->FilterURL(false, &new_validated_url);
navigation_handle->WillRedirectRequest(
new_validated_url, new_method_is_post, new_referrer_url,
- new_is_external_protocol,
+ new_is_external_protocol, headers,
base::Bind(&SendCheckResultToIOThread, callback));
}
+void WillProcessResponseOnUIThread(
+ int render_process_id,
+ int render_frame_host_id,
+ scoped_refptr<net::HttpResponseHeaders> headers) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RenderFrameHostImpl* render_frame_host =
+ RenderFrameHostImpl::FromID(render_process_id, render_frame_host_id);
+ if (!render_frame_host)
+ return;
+
+ NavigationHandleImpl* navigation_handle =
+ render_frame_host->navigation_handle();
+ if (!navigation_handle)
+ return;
+
+ navigation_handle->ReadyToCommitNavigation(render_frame_host, headers);
+}
+
} // namespace
NavigationResourceThrottle::NavigationResourceThrottle(net::URLRequest* request)
@@ -98,6 +118,7 @@ NavigationResourceThrottle::NavigationResourceThrottle(net::URLRequest* request)
NavigationResourceThrottle::~NavigationResourceThrottle() {}
void NavigationResourceThrottle::WillStartRequest(bool* defer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
if (!info)
return;
@@ -128,6 +149,7 @@ void NavigationResourceThrottle::WillStartRequest(bool* defer) {
void NavigationResourceThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info,
bool* defer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
if (!info)
return;
@@ -144,15 +166,50 @@ void NavigationResourceThrottle::WillRedirectRequest(
UIChecksPerformedCallback callback =
base::Bind(&NavigationResourceThrottle::OnUIChecksPerformed,
weak_ptr_factory_.GetWeakPtr());
+
+ // Send the redirect info to the NavigationHandle on the UI thread.
+ // Note: to avoid threading issues, a copy of the HttpResponseHeaders is sent
+ // in lieu of the original.
+ scoped_refptr<net::HttpResponseHeaders> response_headers;
+ if (request_->response_headers()) {
+ response_headers = new net::HttpResponseHeaders(
+ request_->response_headers()->raw_headers());
+ }
+
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&CheckWillRedirectRequestOnUIThread, callback,
render_process_id, render_frame_id, redirect_info.new_url,
redirect_info.new_method == "POST",
- GURL(redirect_info.new_referrer), new_is_external_protocol));
+ GURL(redirect_info.new_referrer), new_is_external_protocol,
+ response_headers));
*defer = true;
}
+void NavigationResourceThrottle::WillProcessResponse(bool* defer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
+ if (!info)
+ return;
+
+ int render_process_id, render_frame_id;
+ if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id))
+ return;
+
+ // Send a copy of the response headers to the NavigationHandle on the UI
+ // thread.
+ scoped_refptr<net::HttpResponseHeaders> response_headers;
+ if (request_->response_headers()) {
+ response_headers = new net::HttpResponseHeaders(
+ request_->response_headers()->raw_headers());
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&WillProcessResponseOnUIThread, render_process_id,
+ render_frame_id, response_headers));
+}
+
const char* NavigationResourceThrottle::GetNameForLogging() const {
return "NavigationResourceThrottle";
}
diff --git a/content/browser/loader/navigation_resource_throttle.h b/content/browser/loader/navigation_resource_throttle.h
index e46b59d..753d99b 100644
--- a/content/browser/loader/navigation_resource_throttle.h
+++ b/content/browser/loader/navigation_resource_throttle.h
@@ -28,6 +28,7 @@ class NavigationResourceThrottle : public ResourceThrottle {
void WillStartRequest(bool* defer) override;
void WillRedirectRequest(const net::RedirectInfo& redirect_info,
bool* defer) override;
+ void WillProcessResponse(bool* defer) override;
const char* GetNameForLogging() const override;
private: