New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 668289 link

Starred by 2 users

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Apr 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 2
Type: Bug



Sign in to add a comment

Links for external protocol handlers don't work inside OOPIFs

Project Member Reported by alex...@chromium.org, Nov 23 2016

Issue description

Repro steps:
1) Start Chrome with --site-per-process
2) Open http://csreis.github.io/
3) In same tab, navigate to http://alexmos17.github.io/tests/mailto.html
4) Click on the mailto link in the subframe.

Expected: external protocol handler for mailto: is launched.
Actual: nothing happens.

This was found by creis@ and nick@ in a code review while removing WebContents::GetRoutingID() in https://codereview.chromium.org/2515823002/.

The reason is that LaunchURL in chrome_resource_dispatcher_host_delegate.cc is called with the |render_process_id| from the OOPIF, which is mismatched with the routing ID of the current/active RenderViewHost for the WebContents.  I.e., render_process_id is different from web_contents->GetRenderViewHost()->GetProcess()->GetID().  Later, we get into ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck and then to tab_util::GetWebContentsByID, where we try to look up the RenderViewHost using the wrong process ID and fail.

Note that when I originally tried to repro this, things appeared to work.  This was sheer luck -- both main frame and subframe processes had a RenderViewHost with the same routing ID (1 in my case).  With the OOPIF process ID, GetWebContentsByID resolved 1 to the swapped-out RVH, which still resolved to the right WebContents.  To ensure the unlucky case in the repro, step 3) forces a cross-process navigation in the same tab, and on that path, the main frame's pending RFH grabs routing ID 1, the main frame RVH ends up with routing ID 2, and  the OOPIF's RVH gets routing ID 1.  Thus, looking up a RVH for routing ID 1 in main frame process fails.

It's unclear that we even need to pass render_process_id to LaunchURL, as we already have a web_contents_getter which appears to be based on RFH routing ID and process ID (or FTN ID with PlzNavigate). Seems like we could just use the web_contents that we get from that getter and gets its web_contents->GetRenderViewHost()->GetProcess()->GetID() instead.

As Charlie and Nick also pointed out, another problem with LaunchURL is a race where the WebContents switches to a different RVH after the LaunchURL task is posted from the IO thread.  This should still work with the above fix, as the current WebContents should be found by the web_contents_getter from a pending delete RFH, or, if the RFH already went away, the |web_contents| will be null and LaunchURL will return early.

It's not clear to me that we should try to stop the external protocol launch in the case above if the RFH where the link was clicked is pending deletion.  Seems that in practice, the external app could take a while to load and show up long after we've gone through LaunchURL, and possibly after other navigations take place.

Nick points out that it'd be good to rename |tab_contents_id| to |render_view_routing_id| in external_protocol_handler.cc.  If we wanted to go further, we'd also convert all the RenderViewHost usage there to RenderFrameHost, since AFAICT, all these IDs ever get used for is to get back the WebContents.

Charlie/Nick - does this plan sound reasonable?

Andrew, do you want to take a stab at fixing this?
 

Comment 1 by creis@chromium.org, Nov 23 2016

Nice analysis!  That plan sounds good to me.
Project Member

Comment 2 by bugdroid1@chromium.org, Dec 20 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/1fe2ac646c67872405598ad551dc4b2b430cfce4

commit 1fe2ac646c67872405598ad551dc4b2b430cfce4
Author: davidsac <davidsac@chromium.org>
Date: Tue Dec 20 01:27:41 2016

fix external protocol handling for OOPIFs

Replace using the wrong render_process_id for launching external protocol
requests in chrome_resource_dispatcher_host_delegate.cc.

Previously, handlers for external protocols like 'mailto:' weren't working for
OOPIFs because the render_process_id used to retrieve the content::WebContents
object was incorrect.

BUG= 668289 
TEST=See bug for repro steps

Review-Url: https://codereview.chromium.org/2538353002
Cr-Commit-Position: refs/heads/master@{#439654}

[modify] https://crrev.com/1fe2ac646c67872405598ad551dc4b2b430cfce4/chrome/browser/chrome_site_per_process_browsertest.cc
[modify] https://crrev.com/1fe2ac646c67872405598ad551dc4b2b430cfce4/chrome/browser/external_protocol/external_protocol_handler.cc
[modify] https://crrev.com/1fe2ac646c67872405598ad551dc4b2b430cfce4/chrome/browser/external_protocol/external_protocol_handler.h
[modify] https://crrev.com/1fe2ac646c67872405598ad551dc4b2b430cfce4/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
[modify] https://crrev.com/1fe2ac646c67872405598ad551dc4b2b430cfce4/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
[modify] https://crrev.com/1fe2ac646c67872405598ad551dc4b2b430cfce4/chrome/browser/prerender/prerender_test_utils.cc
[modify] https://crrev.com/1fe2ac646c67872405598ad551dc4b2b430cfce4/chrome/browser/ui/cocoa/external_protocol_dialog.mm
[modify] https://crrev.com/1fe2ac646c67872405598ad551dc4b2b430cfce4/chrome/browser/ui/external_protocol_dialog_delegate.cc
[add] https://crrev.com/1fe2ac646c67872405598ad551dc4b2b430cfce4/chrome/test/data/page_with_mailto.html

Project Member

Comment 3 by bugdroid1@chromium.org, Dec 21 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/058da9559dd68cd67cf8bbf291a2cfb8a7e55ec1

commit 058da9559dd68cd67cf8bbf291a2cfb8a7e55ec1
Author: davidsac <davidsac@chromium.org>
Date: Wed Dec 21 21:46:33 2016

Rename |tab_contents_id| to |render_view_routing_id| in external protocol handler code.

|tab_contents_id| is a misleading, confusing, and inappropriate name.

This should not change the functionality of the code, only readability.

BUG= 668289 

Review-Url: https://codereview.chromium.org/2591143002
Cr-Commit-Position: refs/heads/master@{#440228}

[modify] https://crrev.com/058da9559dd68cd67cf8bbf291a2cfb8a7e55ec1/chrome/browser/external_protocol/external_protocol_handler.cc
[modify] https://crrev.com/058da9559dd68cd67cf8bbf291a2cfb8a7e55ec1/chrome/browser/external_protocol/external_protocol_handler.h
[modify] https://crrev.com/058da9559dd68cd67cf8bbf291a2cfb8a7e55ec1/chrome/browser/ui/external_protocol_dialog_delegate.cc
[modify] https://crrev.com/058da9559dd68cd67cf8bbf291a2cfb8a7e55ec1/chrome/browser/ui/external_protocol_dialog_delegate.h

Status: Fixed (was: Assigned)
Should be fixed by r439654.
FYI, there is still a TODO referencing this bug in chrome/browser/external_protocol/external_protocol_handler.h

Sign in to add a comment