Add a WebContents getter callback in ResourceRequestInfo
This CL adds a method to ResourceRequestInfo that returns a callback that can
be used on the UI thread to get the WebContents associated with the request.It
is used in the SSLErrorHandler code, instead of using a RenderProcessHost ID
and a RenderFrameHost ID directly .This allows SSL error interstitials to work
with PlzNavigate enabled.
BUG = 504347
Review URL: https://codereview.chromium.org/1459473003
Cr-Commit-Position: refs/heads/master@{#361314}
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc
index 5a9bbff..be19ccd 100644
--- a/content/browser/loader/resource_loader.cc
+++ b/content/browser/loader/resource_loader.cc
@@ -312,19 +312,9 @@
bool fatal) {
ResourceRequestInfoImpl* info = GetRequestInfo();
- int render_process_id;
- int render_frame_id;
- if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id))
- NOTREACHED();
-
SSLManager::OnSSLCertificateError(
- weak_ptr_factory_.GetWeakPtr(),
- info->GetResourceType(),
- request_->url(),
- render_process_id,
- render_frame_id,
- ssl_info,
- fatal);
+ weak_ptr_factory_.GetWeakPtr(), info->GetResourceType(), request_->url(),
+ info->GetWebContentsForRequest(), ssl_info, fatal);
}
void ResourceLoader::OnBeforeNetworkStart(net::URLRequest* unused,
diff --git a/content/browser/loader/resource_request_info_impl.cc b/content/browser/loader/resource_request_info_impl.cc
index 6ed5993..990ac79 100644
--- a/content/browser/loader/resource_request_info_impl.cc
+++ b/content/browser/loader/resource_request_info_impl.cc
@@ -4,15 +4,34 @@
#include "content/browser/loader/resource_request_info_impl.h"
+#include "base/command_line.h"
+#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/loader/global_routing_id.h"
#include "content/browser/loader/resource_message_filter.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/net/url_request_user_data.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_request_id.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
#include "net/url_request/url_request.h"
namespace content {
+namespace {
+
+WebContents* GetWebContentsFromFTNID(int frame_tree_node_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ FrameTreeNode* frame_tree_node =
+ FrameTreeNode::GloballyFindByID(frame_tree_node_id);
+ if (!frame_tree_node)
+ return nullptr;
+
+ return WebContentsImpl::FromFrameTreeNode(frame_tree_node);
+}
+
+} // namespace
+
// ----------------------------------------------------------------------------
// ResourceRequestInfo
@@ -168,6 +187,30 @@
ResourceRequestInfoImpl::~ResourceRequestInfoImpl() {
}
+base::Callback<WebContents*(void)>
+ResourceRequestInfoImpl::GetWebContentsForRequest() const {
+ // PlzNavigate: navigation requests are created with a valid FrameTreeNode ID
+ // and invalid RenderProcessHost and RenderFrameHost IDs. The FrameTreeNode
+ // ID should be used to access the WebContents.
+ if (frame_tree_node_id_ != -1) {
+ DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation));
+ return base::Bind(&GetWebContentsFromFTNID, frame_tree_node_id_);
+ }
+
+ // In other cases, use the RenderProcessHost ID + RenderFrameHost ID to get
+ // the WebContents.
+ int render_process_host_id = -1;
+ int render_frame_host_id = -1;
+ if (!GetAssociatedRenderFrame(&render_process_host_id,
+ &render_frame_host_id)) {
+ NOTREACHED();
+ }
+
+ return base::Bind(&WebContentsImpl::FromRenderFrameHostID,
+ render_process_host_id, render_frame_host_id);
+}
+
ResourceContext* ResourceRequestInfoImpl::GetContext() const {
return context_;
}
diff --git a/content/browser/loader/resource_request_info_impl.h b/content/browser/loader/resource_request_info_impl.h
index 774668a..db1f0a6 100644
--- a/content/browser/loader/resource_request_info_impl.h
+++ b/content/browser/loader/resource_request_info_impl.h
@@ -23,6 +23,7 @@
class DetachableResourceHandler;
class ResourceContext;
class ResourceMessageFilter;
+class WebContents;
struct GlobalRequestID;
struct GlobalRoutingID;
@@ -92,6 +93,14 @@
bool IsUsingLoFi() const override;
bool ShouldReportRawHeaders() const;
+ // Returns a callback that returns a pointer to the WebContents this request
+ // is associated with, or nullptr if it no longer exists or the request is
+ // not associated with a WebContents. The callback should only run on the UI
+ // thread.
+ // Note: Not all resource requests will be owned by a WebContents. For
+ // example, requests made by a ServiceWorker.
+ base::Callback<WebContents*(void)> GetWebContentsForRequest() const;
+
CONTENT_EXPORT void AssociateWithRequest(net::URLRequest* request);
CONTENT_EXPORT int GetRequestID() const;
diff --git a/content/browser/renderer_host/websocket_host.cc b/content/browser/renderer_host/websocket_host.cc
index 70c846e3..8c04e04 100644
--- a/content/browser/renderer_host/websocket_host.cc
+++ b/content/browser/renderer_host/websocket_host.cc
@@ -14,6 +14,7 @@
#include "content/browser/ssl/ssl_error_handler.h"
#include "content/browser/ssl/ssl_manager.h"
#include "content/common/websocket_messages.h"
+#include "content/public/browser/render_frame_host.h"
#include "ipc/ipc_message_macros.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
@@ -274,13 +275,9 @@
<< " cert_status=" << ssl_info.cert_status << " fatal=" << fatal;
ssl_error_handler_delegate_.reset(
new SSLErrorHandlerDelegate(callbacks.Pass()));
- SSLManager::OnSSLCertificateError(ssl_error_handler_delegate_->GetWeakPtr(),
- RESOURCE_TYPE_SUB_RESOURCE,
- url,
- dispatcher_->render_process_id(),
- render_frame_id_,
- ssl_info,
- fatal);
+ SSLManager::OnSSLCertificateSubresourceError(
+ ssl_error_handler_delegate_->GetWeakPtr(), url,
+ dispatcher_->render_process_id(), render_frame_id_, ssl_info, fatal);
// The above method is always asynchronous.
return WebSocketEventInterface::CHANNEL_ALIVE;
}
diff --git a/content/browser/ssl/ssl_cert_error_handler.cc b/content/browser/ssl/ssl_cert_error_handler.cc
index 9ec7885..54b165d9 100644
--- a/content/browser/ssl/ssl_cert_error_handler.cc
+++ b/content/browser/ssl/ssl_cert_error_handler.cc
@@ -15,19 +15,12 @@
const base::WeakPtr<Delegate>& delegate,
ResourceType resource_type,
const GURL& url,
- int render_process_id,
- int render_frame_id,
const net::SSLInfo& ssl_info,
bool fatal)
- : SSLErrorHandler(delegate,
- resource_type,
- url,
- render_process_id,
- render_frame_id),
+ : SSLErrorHandler(delegate, resource_type, url),
ssl_info_(ssl_info),
cert_error_(net::MapCertStatusToNetError(ssl_info.cert_status)),
- fatal_(fatal) {
-}
+ fatal_(fatal) {}
SSLCertErrorHandler* SSLCertErrorHandler::AsSSLCertErrorHandler() {
return this;
diff --git a/content/browser/ssl/ssl_cert_error_handler.h b/content/browser/ssl/ssl_cert_error_handler.h
index e3c4378..11174ed0 100644
--- a/content/browser/ssl/ssl_cert_error_handler.h
+++ b/content/browser/ssl/ssl_cert_error_handler.h
@@ -22,8 +22,6 @@
SSLCertErrorHandler(const base::WeakPtr<Delegate>& delegate,
ResourceType resource_type,
const GURL& url,
- int render_process_id,
- int render_frame_id,
const net::SSLInfo& ssl_info,
bool fatal);
diff --git a/content/browser/ssl/ssl_error_handler.cc b/content/browser/ssl/ssl_error_handler.cc
index 45b6dfd..40b2b564 100644
--- a/content/browser/ssl/ssl_error_handler.cc
+++ b/content/browser/ssl/ssl_error_handler.cc
@@ -20,13 +20,9 @@
SSLErrorHandler::SSLErrorHandler(const base::WeakPtr<Delegate>& delegate,
ResourceType resource_type,
- const GURL& url,
- int render_process_id,
- int render_frame_id)
+ const GURL& url)
: manager_(NULL),
delegate_(delegate),
- render_process_id_(render_process_id),
- render_frame_id_(render_frame_id),
request_url_(url),
resource_type_(resource_type),
request_has_been_notified_(false) {
@@ -55,13 +51,11 @@
return NULL;
}
-void SSLErrorHandler::Dispatch() {
+void SSLErrorHandler::Dispatch(
+ const base::Callback<WebContents*(void)>& web_contents_getter) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- WebContents* web_contents = NULL;
- RenderFrameHost* render_frame_host =
- RenderFrameHost::FromID(render_process_id_, render_frame_id_);
- web_contents = WebContents::FromRenderFrameHost(render_frame_host);
+ WebContents* web_contents = web_contents_getter.Run();
if (!web_contents) {
// We arrived on the UI thread, but the tab we're looking for is no longer
@@ -116,6 +110,11 @@
base::Bind(&SSLErrorHandler::CompleteTakeNoAction, this));
}
+SSLManager* SSLErrorHandler::GetManager() const {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return manager_;
+}
+
void SSLErrorHandler::CompleteCancelRequest(int error) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/content/browser/ssl/ssl_error_handler.h b/content/browser/ssl/ssl_error_handler.h
index 26fc147..3596d47 100644
--- a/content/browser/ssl/ssl_error_handler.h
+++ b/content/browser/ssl/ssl_error_handler.h
@@ -25,6 +25,7 @@
class ResourceDispatcherHostImpl;
class SSLCertErrorHandler;
class SSLManager;
+class WebContents;
// An SSLErrorHandler carries information from the IO thread to the UI thread
// and is dispatched to the appropriate SSLManager when it arrives on the
@@ -65,7 +66,7 @@
// this error.
//
// Call on UI thread.
- void Dispatch();
+ void Dispatch(const base::Callback<WebContents*(void)>& web_contents_getter);
// Available on either thread.
const GURL& request_url() const { return request_url_; }
@@ -96,8 +97,9 @@
// call this.
void TakeNoAction();
- int render_process_id() const { return render_process_id_; }
- int render_frame_id() const { return render_frame_id_; }
+ // Returns the manager associated with this SSLErrorHandler.
+ // Should only be accessed on the UI thread.
+ SSLManager* GetManager() const;
protected:
friend class base::RefCountedThreadSafe<SSLErrorHandler>;
@@ -105,9 +107,7 @@
// Construct on the IO thread.
SSLErrorHandler(const base::WeakPtr<Delegate>& delegate,
ResourceType resource_type,
- const GURL& url,
- int render_process_id,
- int render_frame_id);
+ const GURL& url);
virtual ~SSLErrorHandler();
@@ -137,11 +137,6 @@
// Call on the IO thread.
void CompleteTakeNoAction();
- // We use these members to find the correct SSLManager when we arrive on
- // the UI thread.
- int render_process_id_;
- int render_frame_id_;
-
// The URL that we requested.
// This read-only member can be accessed on any thread.
const GURL request_url_;
diff --git a/content/browser/ssl/ssl_manager.cc b/content/browser/ssl/ssl_manager.cc
index e4c71e3..cd6c2bea 100644
--- a/content/browser/ssl/ssl_manager.cc
+++ b/content/browser/ssl/ssl_manager.cc
@@ -51,8 +51,7 @@
const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
const ResourceType resource_type,
const GURL& url,
- int render_process_id,
- int render_frame_id,
+ const base::Callback<WebContents*(void)>& web_contents_getter,
const net::SSLInfo& ssl_info,
bool fatal) {
DCHECK(delegate.get());
@@ -60,8 +59,6 @@
<< net::MapCertStatusToNetError(ssl_info.cert_status)
<< " resource_type: " << resource_type
<< " url: " << url.spec()
- << " render_process_id: " << render_process_id
- << " render_frame_id: " << render_frame_id
<< " cert_status: " << std::hex << ssl_info.cert_status;
// A certificate error occurred. Construct a SSLCertErrorHandler object and
@@ -69,13 +66,23 @@
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&SSLCertErrorHandler::Dispatch,
- new SSLCertErrorHandler(delegate,
- resource_type,
- url,
- render_process_id,
- render_frame_id,
- ssl_info,
- fatal)));
+ new SSLCertErrorHandler(delegate, resource_type, url, ssl_info,
+ fatal),
+ web_contents_getter));
+}
+
+// static
+void SSLManager::OnSSLCertificateSubresourceError(
+ const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
+ const GURL& url,
+ int render_process_id,
+ int render_frame_id,
+ const net::SSLInfo& ssl_info,
+ bool fatal) {
+ OnSSLCertificateError(delegate, RESOURCE_TYPE_SUB_RESOURCE, url,
+ base::Bind(&WebContentsImpl::FromRenderFrameHostID,
+ render_process_id, render_frame_id),
+ ssl_info, fatal);
}
// static
diff --git a/content/browser/ssl/ssl_manager.h b/content/browser/ssl/ssl_manager.h
index 8128ee8..6e46705 100644
--- a/content/browser/ssl/ssl_manager.h
+++ b/content/browser/ssl/ssl_manager.h
@@ -52,6 +52,16 @@
const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
ResourceType resource_type,
const GURL& url,
+ const base::Callback<WebContents*(void)>& web_contents_getter,
+ const net::SSLInfo& ssl_info,
+ bool fatal);
+
+ // Same as the above, and only works for subresources. Prefer using
+ // OnSSLCertificateError whenever possible (ie when you have access to the
+ // WebContents).
+ static void OnSSLCertificateSubresourceError(
+ const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
+ const GURL& url,
int render_process_id,
int render_frame_id,
const net::SSLInfo& ssl_info,
diff --git a/content/browser/ssl/ssl_policy.cc b/content/browser/ssl/ssl_policy.cc
index dab2a5a..ed8d80b3 100644
--- a/content/browser/ssl/ssl_policy.cc
+++ b/content/browser/ssl/ssl_policy.cc
@@ -232,17 +232,11 @@
CertificateRequestResultType result =
CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE;
GetContentClient()->browser()->AllowCertificateError(
- handler->render_process_id(),
- handler->render_frame_id(),
- handler->cert_error(),
- handler->ssl_info(),
- handler->request_url(),
- handler->resource_type(),
- overridable,
- strict_enforcement,
+ handler->GetManager()->controller()->GetWebContents(),
+ handler->cert_error(), handler->ssl_info(), handler->request_url(),
+ handler->resource_type(), overridable, strict_enforcement,
expired_previous_decision,
- base::Bind(&SSLPolicy::OnAllowCertificate,
- base::Unretained(this),
+ base::Bind(&SSLPolicy::OnAllowCertificate, base::Unretained(this),
make_scoped_refptr(handler)),
&result);
switch (result) {
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index f768020..c36e3a7 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -566,6 +566,18 @@
WebContents::FromRenderFrameHost(frame_tree_node->current_frame_host()));
}
+// static
+WebContents* WebContentsImpl::FromRenderFrameHostID(int render_process_host_id,
+ int render_frame_host_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RenderFrameHost* render_frame_host =
+ RenderFrameHost::FromID(render_process_host_id, render_frame_host_id);
+ if (!render_frame_host)
+ return nullptr;
+
+ return WebContents::FromRenderFrameHost(render_frame_host);
+}
+
RenderFrameHostManager* WebContentsImpl::GetRenderManagerForTesting() {
return GetRenderManager();
}
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index b397bd7b..8d55780 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -113,6 +113,8 @@
static std::vector<WebContentsImpl*> GetAllWebContents();
static WebContentsImpl* FromFrameTreeNode(FrameTreeNode* frame_tree_node);
+ static WebContents* FromRenderFrameHostID(int render_process_host_id,
+ int render_frame_host_id);
// Creates a swapped out RenderView. This is used by the browser plugin to
// create a swapped out RenderView in the embedder render process for the