Fix race when reloading original URL.
Fixes an issue where the browser's last committed entry and the renderer can become out of sync when reloading the original requested URL, which causes the browser to kill the renderer process.
BUG=491861TBR=jam@chromium.org for chromium.fyi.json
Committed: https://crrev.com/573e8be6d639b7066a270ae99d02e829e10b90dd
Cr-Commit-Position: refs/heads/master@{#338864}
I'm not sure about the cause of the crash in the browsertest yet, but here's ...
5 years, 5 months ago
(2015-07-06 20:56:39 UTC)
#4
I'm not sure about the cause of the crash in the browsertest yet, but here's a
few other comments about the change and test.
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
File content/browser/frame_host/navigation_controller_impl_browsertest.cc
(right):
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
content/browser/frame_host/navigation_controller_impl_browsertest.cc:2155: for
(int i = 0; i < 1000; i++) {
This doesn't seem like a great strategy for a test. The loop isn't guaranteed
to test different schedules, so even if the bug exists we'll only fail if we're
lucky.
Can we structure the test so that it deterministically hits the failure without
your fix, without looping?
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
content/browser/frame_host/navigation_controller_impl_browsertest.cc:2179:
EXPECT_TRUE(shell()->web_contents()->IsLoading());
It seems like we should be able to verify that the last committed entry has the
modified URL and not the original URL at this point.
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
content/browser/frame_host/navigation_controller_impl_browsertest.cc:2180: //
Wait until there's no more navigations.
nit: Blank line above.
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
File content/browser/frame_host/navigation_entry_impl.cc (right):
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
content/browser/frame_host/navigation_entry_impl.cc:457: url =
GetOriginalRequestURL();
Switching the URL here is clever, but it causes problems for WebContentsObserver
methods like DidStartNavigationToPendingEntry, which report that a navigation to
the entry's URL (not the original URL) was started.
That's the reason the ReloadOriginalRequestURL unit test is failing.
I definitely agree that we shouldn't change the NavigationEntry's URL (since it
also refers to the last committed page), but maybe there's a way to get the
observer notifications correct.
lfg
Please take another look. https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_host/navigation_controller_impl_browsertest.cc File content/browser/frame_host/navigation_controller_impl_browsertest.cc (right): https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_host/navigation_controller_impl_browsertest.cc#newcode2155 content/browser/frame_host/navigation_controller_impl_browsertest.cc:2155: for (int i = 0; ...
5 years, 5 months ago
(2015-07-08 22:09:29 UTC)
#5
Please take another look.
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
File content/browser/frame_host/navigation_controller_impl_browsertest.cc
(right):
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
content/browser/frame_host/navigation_controller_impl_browsertest.cc:2155: for
(int i = 0; i < 1000; i++) {
On 2015/07/06 20:56:39, Charlie Reis wrote:
> This doesn't seem like a great strategy for a test. The loop isn't guaranteed
> to test different schedules, so even if the bug exists we'll only fail if
we're
> lucky.
>
> Can we structure the test so that it deterministically hits the failure
without
> your fix, without looping?
Sorry, this was just a test because I wasn't sure why the test was flaky. Turned
out there was a pending message in the message loop that wasn't being handled.
I've changed the strategy a bit, now I'm sending the ExecuteScript, but not
waiting for it, so I don't need to rely on setTimeout anymore. This should make
the test deterministic.
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
content/browser/frame_host/navigation_controller_impl_browsertest.cc:2179:
EXPECT_TRUE(shell()->web_contents()->IsLoading());
On 2015/07/06 20:56:39, Charlie Reis wrote:
> It seems like we should be able to verify that the last committed entry has
the
> modified URL and not the original URL at this point.
We can't, because we're not running the message loop, we don't know if the
renderer has executed the javascript or not. I've added a check at the end to
make sure we end up in the original URL.
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
content/browser/frame_host/navigation_controller_impl_browsertest.cc:2180: //
Wait until there's no more navigations.
On 2015/07/06 20:56:39, Charlie Reis wrote:
> nit: Blank line above.
Done.
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
File content/browser/frame_host/navigation_entry_impl.cc (right):
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
content/browser/frame_host/navigation_entry_impl.cc:457: url =
GetOriginalRequestURL();
On 2015/07/06 20:56:39, Charlie Reis wrote:
> Switching the URL here is clever, but it causes problems for
WebContentsObserver
> methods like DidStartNavigationToPendingEntry, which report that a navigation
to
> the entry's URL (not the original URL) was started.
>
> That's the reason the ReloadOriginalRequestURL unit test is failing.
>
> I definitely agree that we shouldn't change the NavigationEntry's URL (since
it
> also refers to the last committed page), but maybe there's a way to get the
> observer notifications correct.
That seems to be the only issue, so I fixed just that specific case. Cloning is
also not an option, since we don't want a new entry in the session history.
Correct me if I'm wrong, but I think there are no more observable effects
outside of the navigator.
Charlie Reis
Thanks. I'm still wary about using two different URLs throughout NavigateToEntry, though. Some thoughts below ...
5 years, 5 months ago
(2015-07-08 23:23:38 UTC)
#6
Thanks. I'm still wary about using two different URLs throughout
NavigateToEntry, though. Some thoughts below about how we can fix that.
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
File content/browser/frame_host/navigation_controller_impl_browsertest.cc
(right):
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
content/browser/frame_host/navigation_controller_impl_browsertest.cc:2179:
EXPECT_TRUE(shell()->web_contents()->IsLoading());
On 2015/07/08 22:09:28, lfg wrote:
> On 2015/07/06 20:56:39, Charlie Reis wrote:
> > It seems like we should be able to verify that the last committed entry has
> the
> > modified URL and not the original URL at this point.
>
> We can't, because we're not running the message loop, we don't know if the
> renderer has executed the javascript or not. I've added a check at the end to
> make sure we end up in the original URL.
Hmm, ok. It's unfortunate, since that's the part we'd really like to prevent
regression on, but I don't see a great way to test it.
(Maybe a StallDelegate on the original URL that lets us check state before
allowing the navigation to commit?)
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
File content/browser/frame_host/navigation_controller_impl_browsertest.cc
(right):
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigation_controller_impl_browsertest.cc:2179:
->ExecuteJavaScriptWithUserGestureForTests(base::UTF8ToUTF16(script));
Please add a comment saying why this has to be done this way (i.e., what
sequence of events do you need for the test to be meaningful?).
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigation_controller_impl_browsertest.cc:2185: while
(shell()->web_contents()->GetLastCommittedURL() != url)
Does replaceState generate a load stop? I'm wondering if this would be cleaner
with WaitForLoadStop and then an expectation that we're on |url|. (I suppose we
can do this loop if needed, but we should have more of an explanation why it's
necessary if so.)
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
File content/browser/frame_host/navigator_impl.cc (right):
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigator_impl.cc:236: if
(frame_entry.url().spec().size() > GetMaxURLChars()) {
There's a lot of frame_entry.url() uses in here that are all wrong in this case.
Can we move the reloadOriginalURL check from ConstructCommonNavigationParams to
the top of this method and create a dest_url and dest_referrer to use below?
We'll have to pass them to RequestNavigation and
ConstructCommonNavigationParams, and they'll trump whatever is in frame_entry.
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigator_impl.cc:254: navigation_start,
frame_entry.url(), entry.restore_type()));
dest_url
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigator_impl.cc:261:
frame_tree_node->navigation_request()->common_params().url,
dest_url
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigator_impl.cc:279: frame_entry.url());
dest_url
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigator_impl.cc:324:
frame_entry.url().SchemeIs(url::kJavaScriptScheme)) {
dest_url
(Not sure if javascript: URLs can actually be in redirect chains, but we should
be consistent here.)
lfg
Another round of changes, please take a look. https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_host/navigation_controller_impl_browsertest.cc File content/browser/frame_host/navigation_controller_impl_browsertest.cc (right): https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_host/navigation_controller_impl_browsertest.cc#newcode2179 content/browser/frame_host/navigation_controller_impl_browsertest.cc:2179: EXPECT_TRUE(shell()->web_contents()->IsLoading()); ...
5 years, 5 months ago
(2015-07-14 18:58:31 UTC)
#7
Another round of changes, please take a look.
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
File content/browser/frame_host/navigation_controller_impl_browsertest.cc
(right):
https://codereview.chromium.org/1189413005/diff/80001/content/browser/frame_h...
content/browser/frame_host/navigation_controller_impl_browsertest.cc:2179:
EXPECT_TRUE(shell()->web_contents()->IsLoading());
On 2015/07/08 23:23:37, Charlie Reis wrote:
> Hmm, ok. It's unfortunate, since that's the part we'd really like to prevent
> regression on, but I don't see a great way to test it.
>
> (Maybe a StallDelegate on the original URL that lets us check state before
> allowing the navigation to commit?)
I've changed the test to look at the commits instead. We are only indirectly
testing the last committed url, but it may be enough, what do you think?
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
File content/browser/frame_host/navigation_controller_impl_browsertest.cc
(right):
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigation_controller_impl_browsertest.cc:2179:
->ExecuteJavaScriptWithUserGestureForTests(base::UTF8ToUTF16(script));
On 2015/07/08 23:23:37, Charlie Reis wrote:
> Please add a comment saying why this has to be done this way (i.e., what
> sequence of events do you need for the test to be meaningful?).
Done.
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigation_controller_impl_browsertest.cc:2185: while
(shell()->web_contents()->GetLastCommittedURL() != url)
On 2015/07/08 23:23:37, Charlie Reis wrote:
> Does replaceState generate a load stop? I'm wondering if this would be
cleaner
> with WaitForLoadStop and then an expectation that we're on |url|. (I suppose
we
> can do this loop if needed, but we should have more of an explanation why it's
> necessary if so.)
It only generates a load stop when IsLoading() is true, so in this case we only
get 1 loadstop, but 2 commits.
I've cleaned it up by waiting on the commits instead.
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
File content/browser/frame_host/navigator_impl.cc (right):
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigator_impl.cc:236: if
(frame_entry.url().spec().size() > GetMaxURLChars()) {
On 2015/07/08 23:23:37, Charlie Reis wrote:
> There's a lot of frame_entry.url() uses in here that are all wrong in this
case.
>
> Can we move the reloadOriginalURL check from ConstructCommonNavigationParams
to
> the top of this method and create a dest_url and dest_referrer to use below?
> We'll have to pass them to RequestNavigation and
> ConstructCommonNavigationParams, and they'll trump whatever is in frame_entry.
Done.
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigator_impl.cc:254: navigation_start,
frame_entry.url(), entry.restore_type()));
On 2015/07/08 23:23:37, Charlie Reis wrote:
> dest_url
Done.
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigator_impl.cc:261:
frame_tree_node->navigation_request()->common_params().url,
On 2015/07/08 23:23:37, Charlie Reis wrote:
> dest_url
Done.
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigator_impl.cc:279: frame_entry.url());
On 2015/07/08 23:23:37, Charlie Reis wrote:
> dest_url
Done.
https://codereview.chromium.org/1189413005/diff/140001/content/browser/frame_...
content/browser/frame_host/navigator_impl.cc:324:
frame_entry.url().SchemeIs(url::kJavaScriptScheme)) {
On 2015/07/08 23:23:37, Charlie Reis wrote:
> dest_url
>
> (Not sure if javascript: URLs can actually be in redirect chains, but we
should
> be consistent here.)
Done.
Charlie Reis
THanks for the updates! LGTM with nits. You can disable the test on the Site ...
5 years, 5 months ago
(2015-07-14 22:23:10 UTC)
#8
https://codereview.chromium.org/1189413005/diff/180001/content/browser/frame_host/navigation_controller_impl_browsertest.cc File content/browser/frame_host/navigation_controller_impl_browsertest.cc (right): https://codereview.chromium.org/1189413005/diff/180001/content/browser/frame_host/navigation_controller_impl_browsertest.cc#newcode2148 content/browser/frame_host/navigation_controller_impl_browsertest.cc:2148: // This tests for a race in ReloadOriginalRequest. Not ...
5 years, 5 months ago
(2015-07-14 22:47:28 UTC)
#9
LGTM with nit. One possible concern: I'm worried about other parts of the NavigationEntry that ...
5 years, 5 months ago
(2015-07-14 23:02:24 UTC)
#10
LGTM with nit.
One possible concern: I'm worried about other parts of the NavigationEntry that
come from the redirect_url but are used with the original_url, especially the
SiteInstance. Most client redirects aren't cross-process (yet), but I would
guess that we would load the original_url in the redirect_url's SiteInstance the
way things stand. That's bad. That's probably true before this CL lands as
well.
We may want to land this to get the bug fixed in Chrome (where cross-process
redirects are rare) and then revisit that issue separately.
https://codereview.chromium.org/1189413005/diff/200001/testing/buildbot/chrom...
File testing/buildbot/chromium.fyi.json (right):
https://codereview.chromium.org/1189413005/diff/200001/testing/buildbot/chrom...
testing/buildbot/chromium.fyi.json:4030:
"--gtest_filter=-*.PreventSpoofFromSubframeAndReplace:SessionHistoryTest.CrossFrameFormBackForward:SessionHistoryTest.FrameBackForward:*.SupportCrossProcessPostMessageWithMessagePort:DevToolsProtocolTest.NavigationPreservesMessages"
You need to add it here as well.
lfg
I've created bug 510251 so we don't forget to revisit this issue. https://codereview.chromium.org/1189413005/diff/200001/testing/buildbot/chromium.fyi.json File testing/buildbot/chromium.fyi.json ...
5 years, 5 months ago
(2015-07-14 23:11:30 UTC)
#11
Issue 1189413005: Fix race when reloading original URL
(Closed)
Created 5 years, 6 months ago by lfg
Modified 5 years, 5 months ago
Reviewers: Avi (use Gerrit), Charlie Reis
Base URL: https://chromium.googlesource.com/chromium/src.git@master
Comments: 48