Closed Bug 1368080 Opened 7 years ago Closed 7 years ago

Bad handling of multiple HTTP/2 pushes of the same resource

Categories

(Core :: Networking: HTTP, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla56
Tracking Status
firefox56 --- fixed

People

(Reporter: jaffathecake, Assigned: u408661)

Details

(Whiteboard: [necko-active])

Attachments

(2 files)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36

Steps to reproduce:

Scrappy test case: https://github.com/jakearchibald/http2-push-test
Video of issue: https://www.youtube.com/watch?v=N___ogRnhIA


Actual results:

From the video:

0:06 - Resource '/data' pushed along with navigation.
0:11 - '/data' fetched and correctly comes from push cache.
0:14 - Page reloaded, pushing '/data' again.
0:20 - Page reloaded, pushing '/data' again, while it's already in the push cache. This causes Firefox to reject the stream with an INTERNAL_ERROR.
0:28 - '/data' fetched, and it comes from the server, not the push cache.


Expected results:

Push streams may be rejected if the browser already has the resource, but it should use the CANCEL or REFUSED_STREAM code.

The big problem is that Firefox then drops the item it already had in the push cache.

Firefox should either keep the item it already had (what Chrome does), or allow the new item to overwrite the old one.
This was spotted in nightly btw.
Component: Untriaged → Networking: HTTP
Product: Firefox → Core
Assignee: nobody → hurley
Whiteboard: [necko-active]
Writeup including this bug by reporter: https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/
OK, finally got around to looking at this. Both issues mentioned here (wrong error code & removed push) exist, quite obviously. The issue with the missing push on duplicate lies in this: when we go to do cleanup on stuff we've allocated for the duplicate push, we follow the regular cleanup stream logic. This is 99.9% correct - the only thing we do in that code path that's wrong (in this case) is to remove the entry in the push cache without regard to its stream id (we only remove based on hash key, and since both pushes are for the same URL, the hash keys are the same). The easy solution here is to make that removal contingent on the stream ID of the stored push and the stream ID of the push we're cleaning up being the same. It's a pretty straightforward patch. As with many of these things, writing the test for our setup will be the tricky bit. Either way, patch should exist this week.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Comment on attachment 8882214 [details]
Bug 1368080 - Use REFUSED_STREAM instead of INTERNAL_ERROR on duplicate push key.

https://reviewboard.mozilla.org/r/153322/#review158832
Attachment #8882214 - Flags: review?(mcmanus) → review+
Comment on attachment 8882215 [details]
Bug 1368080 - Only remove pushed streams from cache when canceling the stream if the ids match.

https://reviewboard.mozilla.org/r/153324/#review158834

thanks
Attachment #8882215 - Flags: review?(mcmanus) → review+
Pushed by hurley@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/992ddd920585
Use REFUSED_STREAM instead of INTERNAL_ERROR on duplicate push key. r=mcmanus
https://hg.mozilla.org/integration/autoland/rev/671e8c23db24
Only remove pushed streams from cache when canceling the stream if the ids match. r=mcmanus
https://hg.mozilla.org/mozilla-central/rev/992ddd920585
https://hg.mozilla.org/mozilla-central/rev/671e8c23db24
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla56
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: