Closed Bug 1608224 Opened 4 years ago Closed 4 years ago

Source for Twitter page not shown as expected

Categories

(Core :: DOM: Networking, defect, P2)

defect

Tracking

()

VERIFIED FIXED
mozilla74
Tracking Status
firefox-esr68 --- unaffected
firefox72 --- unaffected
firefox73 --- unaffected
firefox74 + verified

People

(Reporter: ytausky, Assigned: mayhemer)

References

Details

(Keywords: regression, Whiteboard: [necko-triaged])

Attachments

(1 file)

When I go to someone's Twitter page (example) and choose "View Page Source" from the context menu, I get a non-styled rendering of the page itself instead of the normal source viewer.

I'm on Nightly Build ID 20200107095722 and it works for me. So you can treat that as lower range regression window point.

Can you reproduce on an empty profile? I can't, and I wonder if this is a dupe of bug 1605657.

Flags: needinfo?(ytausky)

(In reply to :Gijs (he/him) from comment #2)

Can you reproduce on an empty profile? I can't, and I wonder if this is a dupe of bug 1605657.

Oh, sorry, I can reproduce, but reloading the view source page (which I did after uninstalling the add-on that trips bug 1605657) fixes it.

Flags: needinfo?(ytausky)

Mozregression points out to this range.

  • last good build_date: 2020-01-07;
  • first bad build_date: 2020-01-08.
  • 73.0b3 not affected by this.

Probably bug 1598523? Matt, could you take a look?

Flags: needinfo?(matt.woodrow)

Hmm, looks like view-source is broken for anything that redirects, due to a serviceworker intercept or a real HTTP redirect (we need more tests for this!).

The issue is that AsyncOnChannelRedirect gets called on the DocumentLoadListener for the old and new inner channels (the real http channels, not the nsViewSourceChannel). We then grab the OriginalURI from the new channel, and store it in mChannelCreationURI, and that doesn't include 'view-source'.

When we try to create the real channel in the content process, the URI we have no longer has 'view-source', so we don't get an nsViewSourceChannel wrapper in the content process.

We take a copy of the OriginalURI during AsyncOnChannelRedirect, since it gets overwritten to be the OriginalURI of the initial (pre-redirect) load after this point. We need the value we're grabbing in order to create the real channel in the content process. We really need a variant of this that includes the 'view-source' prefix, which doesn't appear to exist anywhere right now.

nsViewSourceChannel appears to largely ignore redirects, except that it updates it's URI/mChannel when it gets OnStartRequest. This includes manually adding a 'view-source' prefix, but this is on the final URI, not the original of the current channel.

It also appears that functions like Suspend/Resume on nsViewSourceChannel are broken if we have a redirect and try to call them before OnStartRequest, since they'd try to Suspend the original channel, not the current redirect.

DocumentLoadListener caches mChannel on redirects, as well as the original URI, both of which seem like they'll be wrong when we get a redirect for the inner channel.

Honza, do you have any ideas on the best way to solve this?

I'm beginning to think we should just hide 'view-source' from the parent entirely, and just append it when we get back to the child process. I think we wanted to make process switching decision based on view-source though, which we'd no longer know about.

Flags: needinfo?(matt.woodrow) → needinfo?(honzab.moz)

Thanks for the description, Matt. Something tells me this is a fallout from bug 1598523 (please adjust if it it really something else). To be honest, I really lack a good tech documentation for the docchannel code right now to look into it and recall the code flow. The code became rather very complicated and I don't have cycles to go through it and study it again to understand what to do with this bug now. I'll schedule a f2f meeting to talk about this, it will be more effective.

Blocks: 1598523
Flags: needinfo?(honzab.moz)

:ytausky, since this bug is a regression, could you fill (if possible) the regressed_by field?
For more information, please visit auto_nag documentation.

Flags: needinfo?(ytausky)

The idea to fix this is via another "view-source" specific hack:

  • let nsViewSourceChannel implement nsIInterfaceRequestor and nsIChannelEventSink
  • let it inject itself as notification callbacks of the inner channel in Init or AsyncOpen
  • from GetInterface return:
    • nsIViewSourceChannel: itself
    • nsIChannelEventSink: itself
    • anything else forward to the outer (original) notification callbacks
  • in AsyncOnChannelRedirect inject like this to the new channel as well and then just forward call to AsyncOnChannelRedirect to the outer notification callbacks with the same arguments
  • DocumentLoadListener then can query the new redirect-to channel's notification callbacks for nsIViewSourceChannel to and update the creation-URI to view-source:, probably here
    • possibly make nsViewSourceChannel::BuildViewSourceURI a public static method to do this more easily

I decided to use a hack rather than updating new channel's original URI (or LI's rpURI) to be prefixed with "view-source:" in AsyncOnChannelRedirect to not effect security checks we are performing during redirection. It may be worth filing a followup bug, but I think it's a too sensitive change to do to just fix this particular bug. I didn't write down why I have chosen the URI update as late as in OnStartRequest in bug 1403998.

Assignee: nobody → honzab.moz
Status: NEW → ASSIGNED
Component: View Source → DOM: Networking
Flags: needinfo?(ytausky)
Priority: -- → P2
Product: Toolkit → Core
Whiteboard: [necko-triaged]

in AsyncOnChannelRedirect inject like this to the new channel as well

Or create a new view-source channel wrapping the new post-redirect channel? If it did that, it could pass itself and the new thing to the outer notification callbacks, right? And then DocumentLoadListener might not need any special magic?

(In reply to Boris Zbarsky [:bzbarsky, bz on IRC] from comment #10)

in AsyncOnChannelRedirect inject like this to the new channel as well

Or create a new view-source channel wrapping the new post-redirect channel? If it did that, it could pass itself and the new thing to the outer notification callbacks, right? And then DocumentLoadListener might not need any special magic?

Thanks, yes. That is another option that also crossed my mind, but that may effect security checks as well and is also a lot more work. We then may need an IPC protocol for the view-source channel (have parent and child parts), but it's more a guess at the moment - maybe we don't.

I'll try that first, but something tells me it will be more complicated and we have just few days to get this done for this, affected release... I'm not sure I will have time to work on this in Berlin.

(In reply to Boris Zbarsky [:bzbarsky, bz on IRC] from comment #10)

in AsyncOnChannelRedirect inject like this to the new channel as well

Or create a new view-source channel wrapping the new post-redirect channel? If it did that, it could pass itself and the new thing to the outer notification callbacks, right? And then DocumentLoadListener might not need any special magic?

Reading this again... I'm not sure how this would help or at least I can see a simpler solution after (re-)studding our redirect notify ordering.

According the redirect notify helper logic we first notify the IO service which calls, in this order: CONTENTSECURITYMANAGER, all registered global category entries. Then it pops back to the helper to notify the callbacks of the old channel, if implementing nsIEventSink.

So, the actual update of the URL happens as the last and thus will not effect security check (unless I'm missing something). We are then probably fine to simply update the OriginalURI of the new channel in nsViewSourceChannel implementing (and forwarding) nsIEventSink. That is the proper and sufficient fix. Hopefully nothing else will break.

I think we still might have bugs, because we're going to call DocumentLoadListener::AsyncOnChannelRedirect, which will change mChannel from the old nsViewSourceChannel to the new nsHttpChannel.

Looks like we'd set mChannel back to the nsViewSourceChannel during OnStartRequest, and most places we use it are after that.

I think only Cancel() could use the wrong mChannel (but it's confusing to verify), and that should be fine to Cancel the new inner http channel directly, so maybe everything will work.

That said, it's a bit confusing. I like the idea of creating a new nsViewSourcewChannel wrapper (after security checks are done), just so that DocumentLoadListener doesn't get confused.

(In reply to Matt Woodrow (:mattwoodrow) from comment #15)

I think we still might have bugs, because we're going to call DocumentLoadListener::AsyncOnChannelRedirect, which will change mChannel from the old nsViewSourceChannel to the new nsHttpChannel.

Looks like we'd set mChannel back to the nsViewSourceChannel during OnStartRequest, and most places we use it are after that.

I think only Cancel() could use the wrong mChannel (but it's confusing to verify), and that should be fine to Cancel the new inner http channel directly, so maybe everything will work.

That said, it's a bit confusing. I like the idea of creating a new nsViewSourcewChannel wrapper (after security checks are done), just so that DocumentLoadListener doesn't get confused.

Can you please be more specific what exactly this would help with? Or what confusion you exactly see?

Ah... I see now. Hmm... that was there before as well and you are working more with the inner channel anyway, so I thought this would be fine to do. I can have a different patch that will create a new nsViewSourceChannel. Note that the "old" channel will then also be (for consistency) the old (current mChannel) nsV.S.C, what actually might be a better as well.

Tomorrow.

I started to write a patch according the bz's and matt's proposal and it's getting overly complicated. I will open a new bug for that work. Because I won't have time to work on it for this release, let's consider the patch here as an intermediate fix.

bz, matt, what do you think?

Flags: needinfo?(matt.woodrow)
Flags: needinfo?(bzbarsky)

That sounds reasonable to me.

Flags: needinfo?(bzbarsky)
Pushed by honzab.moz@firemni.cz:
https://hg.mozilla.org/integration/autoland/rev/bdad1c3a97a0
Update originalURI of the "new" redirect channel used by a view-source channel to let consumers see it has been actually used for view-source, r=bzbarsky
Flags: needinfo?(matt.woodrow)
Status: ASSIGNED → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla74
See Also: → 1613196
Flags: qe-verify+

Reproduced the issue using Firefox 74.0a1 (20200109213942) on Windows 10x64.
The issue is verified fixed with Firefox 74.0b5 (20200218224219) on Windows 10x64, macOS 10.15 and Ubuntu 16.04.

Status: RESOLVED → VERIFIED
Flags: qe-verify+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: