Problem with CompressionDictionaries when a load is replacing a dictionary and using itself as the dictionary
Categories
(Core :: Networking: Cache, defect, P2)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox149 | --- | fixed |
People
(Reporter: jesup, Assigned: jesup)
References
(Blocks 1 open bug, )
Details
(Whiteboard: [necko-triaged])
Attachments
(6 files)
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review |
HttpChannel was calling InitCacheEntry right before ParseDictionary(), which is when it would realize it was replacing an old dictionary and might Suspend() the new request until the old dictionary had loaded the cache contents (for use in decoding active requests, including the one for the replacement). InitCacheEntry will see we're overwriting a cache entry and will truncate it, and also will notice there's a dictionary associated and tell it to remove itself. This happens before we can suspend and wait.
Moving InitCacheEntry below ParseDictionary, and putting a split inbetween where we check for Suspend lets the old dictionary load the cache contents before removing itself and Resume()ing the replacement load (which will be using the old dictionary to decompress the new one).
This is a weird edgecase in general, where we're loading the same URI even though it's cached, and using itself for compression - which will result in 99.999% compression (i.e. it will just dump out a copy of itself unless the contents of that URI on the server have changed, which is possible not isn't happening in this case. This is happening a LOT in ChatGPT (something like 30-some replacements during a load IIRC), and at least once in Shopify (some css file).
| Assignee | ||
Comment 1•5 months ago
|
||
Move InitCacheEntry to after parsing dictionaries and possibly suspending
the request.
| Assignee | ||
Comment 2•5 months ago
|
||
Issues found with this case:
- InitCacheEntry called before ParseDictionary can suspend the replacement
- Content-Length needs to get removed/blanked/fixed if we decompress before storing in the cache (avoids thinking it's partial, though this seems to not hurt much -- so far)
- RemoveFromVary() needs to use case-insensitive comparisons (we need to remove available-dictionary and accept-encoding for dictionaries and dictionary-compressed responses)
- (not specific to this issue: GetMetaDataElement() should be case-insensitive for keys, or perhaps we should flatten header name case (not values) for request/response headers in the metadata, and flatten the lookup values for headers)
- In case we do end up revalidating anyways, we need to not let the dictionary load stall like normal ones do. Add a Cache load flag to set this
Updated•5 months ago
|
| Assignee | ||
Comment 3•5 months ago
|
||
The Content-Length in the saved cache headers needs to not conflict with
size of data in the cache
| Assignee | ||
Comment 4•5 months ago
|
||
In particular, if we Suspend for 5+ seconds and timeout
| Assignee | ||
Comment 5•5 months ago
|
||
| Assignee | ||
Comment 6•5 months ago
|
||
| Assignee | ||
Comment 7•5 months ago
|
||
Comment 9•5 months ago
|
||
| bugherder | ||
https://hg.mozilla.org/mozilla-central/rev/71879ab12afc
https://hg.mozilla.org/mozilla-central/rev/d7d876d135ab
https://hg.mozilla.org/mozilla-central/rev/a79807f3659f
https://hg.mozilla.org/mozilla-central/rev/a017057df408
https://hg.mozilla.org/mozilla-central/rev/b5defdd1e162
https://hg.mozilla.org/mozilla-central/rev/c7dcd1cbf56c
Updated•4 months ago
|
Description
•