Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
LanguageNegotiationBrowser
correctly disables page cache in case an Accept-Language
header is provided and it is asked for the language.
However, if there is no such header, then it doesn't, resulting in caching the response and the next request that does have such a header will receive the wrong response.
This can be reproduced with the following language detection order:
- URL
- Browser
- Default / selected language
Proposed resolution
Always trigger the page_cache_kill_switch
. Extend test coverage to do multiple requests in a row, including some without a header.
Comment | File | Size | Author |
---|---|---|---|
#25 | interdiff-2986325-22-25.txt | 1.42 KB | arpad.rozsa |
#25 | drupal-browser-detection-2986325-25.patch | 6.48 KB | arpad.rozsa |
#25 | drupal-browser-detection-2986325-25-test-only.patch | 5.13 KB | arpad.rozsa |
#22 | interdiff-2986325-19-22.txt | 5.9 KB | arpad.rozsa |
#22 | drupal-browser-detection-2986325-22.patch | 5.95 KB | arpad.rozsa |
Comments
Comment #2
sleitner CreditAttribution: sleitner commentedComment #3
sleitner CreditAttribution: sleitner commentedComment #4
sleitner CreditAttribution: sleitner commentedComment #6
sleitner CreditAttribution: sleitner commentedComment #7
sleitner CreditAttribution: sleitner commentedComment #8
sleitner CreditAttribution: sleitner commentedComment #10
swentel CreditAttribution: swentel as a volunteer commentedthis is a duplicate of #2430335: Browser language detection is not cache aware no ?
Comment #11
sleitner CreditAttribution: sleitner commented@swentel: no, https://www.drupal.org/project/drupal/issues/2430335 aims at caching more pages, but in this issue shows that at this point drupal caches too much when no language is sent by the browser/robot.
I think, that browser language detection can not be cached, because it is not an 1:1 relation. The browser normally sends a list of languages, therefore drupal would have to cache all possible combinations containing the installed languages.
Comment #12
kubrick CreditAttribution: kubrick commentedThanks so much for the patch! I've been trying to fix this for hours now. Seems to work perfectly.
Comment #13
Babaone CreditAttribution: Babaone as a volunteer and commented@kibrick which fix did you use to solve this problem ? Can anyone help me ?
Comment #14
sleitner CreditAttribution: sleitner commented@Babaone this patch should fix the problem:
https://www.drupal.org/files/issues/2018-07-17/drupal-browser-detection-...
Comment #15
BerdirMissed this.
Great that you already wrote a test, not that the patch with the fix needs to include both the fix *and* the test.
Also, the issue title isn't very helpful, which is one reason why I didn't find this issue, and possibly others neither. I'll close #3024535: LanguageNegotiationBrowser needs to trigger the page cache kill switch even when there is no Accept-Language header as a duplicate, I'd suggest to use my title or something similar.
Comment #16
sleitner CreditAttribution: sleitner commented@Berdir : Thanks, I added a patch with both the test and the code fix.
Comment #18
sleitner CreditAttribution: sleitner commentedRemoved unnecessary test assert
Comment #19
arpad.rozsa CreditAttribution: arpad.rozsa at MD Systems GmbH commentedThe fix is working as expected. Extended the test with assertion of the page caching, which was also a main point of this patch, to not cache the page, when the Accept-Language header is not present.
Comment #21
Berdirmissing documentation property.
no need to create protected properties for variables that are only used in the context of one method, use $admin instead.
Tests usually enable languages with ConfigurabeLanguage::createFromLangcode(), should be quite a bit faster.
lets try to avoid a dependency on node, we just need some kind of url that we can post against as an anonymous user.
Maybe we can use the system_test.echo route instead or some other page that's accessible to anonymous users.
setUp() shouldn't have asserts, move those to the method. Also, "normal behavior" is not a very good desccription, maybe test correct cache header or so?
Comment #22
arpad.rozsa CreditAttribution: arpad.rozsa at MD Systems GmbH commentedMade all the changes according to your review.
Comment #24
BerdirThanks, looks good now I think. We only test for MISS now and not HIT, I *think* that's enough, as a MISS also means that the page is cacheable and was cached. But we could also make that explicit and do another request that would return a HIT.
Actually, lets do that and at the end of a the current test. Then we now that the existing URL with language prefix is still cached and returned from cache after requests without a language prefix.
extra empty line here, can be fixed on commit guess.
Comment #25
arpad.rozsa CreditAttribution: arpad.rozsa at MD Systems GmbH commentedAdded the test for HIT at the end, and also removed the extra empty line.
Comment #26
BerdirThanks, looks good now I think.
We'll see what happens in #2430335: Browser language detection is not cache aware exactly, but whatever we do there, we do have explicit test coverage now for how page cache is expected to behave with different combinations of headers/URL's, and we can adjust it there accordingly.
Comment #28
plachPatch looks good to me as well. Please let's merge the IS with the one @Berdir posted at #3024535: LanguageNegotiationBrowser needs to trigger the page cache kill switch even when there is no Accept-Language header and fix the nit below:
Comment does not wrap at column 80.
Comment #29
plachComment #30
timcosgrove CreditAttribution: timcosgrove at Pinterest commentedMade a pass at merging the IS from https://www.drupal.org/project/drupal/issues/3024535 (we have an interest in this issue moving forward).
Comment #31
timcosgrove CreditAttribution: timcosgrove at Pinterest commented@plach, the longest comment there (ends with "browser negotiation") ends at column 74 when applied, unless I'm missing something.
Comment #32
timcosgrove CreditAttribution: timcosgrove at Pinterest commentedAdded issue summary from https://www.drupal.org/project/drupal/issues/3024535 to this issue; cannot repro the code style issue mentioned in https://www.drupal.org/project/drupal/issues/2986325#comment-12958068 (with the patch applied to 8.7.x, all comments added are under 80 columns).
Comment #33
plachMy bad, I wasn't clear: the comment can be rewrapped to fit 80 chars better. Specifically, "page" fits after "internal".
Comment #34
plachI will fix that on commit, thanks for the IS update.
Comment #35
plachCommitted 1cc42e0 and pushed to 8.7.x. Thanks!
Comment #37
plachStreamlined the IS.
Comment #38
plachUncrediting myself.
Comment #39
plachBriefly discussed this with @catch: this might involve some (hopefully beneficial) behavior changes, so let's keep it 8.7.x only. It's safe to apply the committed patch to 8.6.x for people needing the fix right now.