Problem/Motivation
The EU Only option is incompatible with page cache. If page cache is enabled, even without a additional caching layer such a Varnish, a user (not) in a EU, could be served a page with(out) the pop-up. The display of the pop-up is set for the HTTP request that put the page in the cache, not the request for which the page is served because it is done in eu_cookie_compliance_page_build()
.
Proposed resolution
Instead of checking for the visitor country in eu_cookie_compliance_page_build()
, provide a non-cacheable menu callback that return the visitor country, and check whether or not to display the pop-up from JavaScript only. The callback should support both the GeoIP and Smart IP modules.
The should be the default behavior of the module has soon as page caching is enabled (ie. the cache
variable is true). If page cache is not enabled, the existing behavior could still be used (but switching to the JS based check shouldn't hurt).
Original report by @jrbeeman
As currently designed, this module requires that Drupal bootstrap for every page request, making technologies like Varnish difficult to use in conjunction with the cookie detection.
Solution: Provide a menu callback that returns country information that can then be used by the module JS to determine if the cookie warning should be displayed.
Comments
Comment #1
jrbeemanPatch attached.
This patch adds a menu callback that returns JSON-formatted data about the country from which the user is visiting and a corresponding option in the module settings for which detection method to use. This feature requires the GeoIP module to be installed.
Comment #2
jrbeemanComment #3
svenryen CreditAttribution: svenryen commentedThere's a suggested fix for Varnish here: https://drupal.org/node/2190719
Comment #4
pbuyle CreditAttribution: pbuyle commentedThe Varnish solution linked in in #3 is to allow Varnish to cache pages when the module is used. Because of the cookie-agreed set in JavaScript, and only consumed in JavaScript, a standard Varnish configuration will not cache the page. But the value of the cookie does not change the content of the page, so it could safely be ignored by Varnish (or other HTTP cache).
This issue is about serving the same cached page to all visitors, regardless of their country. Since Geo-localisation of the visitor is done on the server side, it result is cached. If the UE only setting s enabled (available when the GeoIP or the Smart IP module is enabled), the page could be generated for a user in the EU with the JavaScript code for the pop-up. Then the page will be cached, and when a not from the EU will get the page, the page with the pop-up will be served. Or a page without the pop-up could be cached, then served to a visitor from the EU.
Note that, because alteration of the page to add the pop-up is done in a
eu_cookie_compliance_page_build()
, I believe the issue to be present even when only the Drupal page cache is used.Comment #5
pbuyle CreditAttribution: pbuyle commentedComment #6
pbuyle CreditAttribution: pbuyle commentedComment #7
Finn Lewis CreditAttribution: Finn Lewis commented@svenryen: I'm not sure the suggested fix for Varnish at: https://drupal.org/node/2190719 will actually have the desired effect. I could be wrong, but it suggests passing the cookie-agreed cookie through, which (depending on the rest of your Varnish configuration) will usually result in Varnish not caching the page. In my tests that has certainly been the case, so I was interested in the patch above.
@jrbeeman: I liked the look of your patch, but couldn't get it to apply cleanly, so re-rolled against the latest 7.x-1.x-dev. I have tested this somewhat on a server and it seems to be working well, but I have yet to test with a greater variety of IPs from different countries. I also added a variable_get() to enable us to easier alter the array of country codes that we consider EU, (or actually care about), as this may change over time depending on the use case.
Patch attached, will report back when tested further.
@mongolito404
I think you are confirming that this is indeed an issue. Just to clarify my understanding, the patch in the original post and the re-roll attached aims to address this by using a separate callback to Drupal at /eu-cookie-compliance-check (which is not cached by Drupal and can be ignored by Varnish) such that the cached page can decide how to behave depending on the result of this.
Comment #8
svenryen CreditAttribution: svenryen commentedThank you for the re-roll. I will see if I can get this functionality into the 2.x branch. If you can help @finn.lewis , do you have a Varnish environment where I can test my code? I don't have any Varnish set up for now.
Comment #9
Jody LynnThis is the patch in 7 with an additional isset to prevent notices we were seeing on cache clear.
Comment #10
Jody LynnThat last patch was bad. New patch and I also removed the whitespace fixes as they were making the patch not apply to 7.x-1.14.
Comment #11
Leeteq CreditAttribution: Leeteq commentedComment #12
pbuyle CreditAttribution: pbuyle commenteddrupal_add_http_header('Cache-Control', 'private');
should prevent aching of the JSON by a reverse-proxy cache such a Varnish or CloudFront. Solving the issue mentionned in #4. However, it should be called beforedrupal_json_output()
. The later may trigger a buffer flush and start the HTTP response, which will prevent any additional header to work.Comment #13
l0keMoved
drupal_add_http_header('Cache-Control', 'private');
beforedrupal_json_output()
as noted here #2153799-12: The EU Only option is incompatible with page cache.I've noticed that value of
Drupal.settings.eu_cookie_compliance.domain
ineu_cookie_compliance.js
is getting cached because it's passed from cachableeu_cookie_compliance_page_build()
, so it doesn't work correct.Proposed solution is to use AJAX callback to get the domain value.
Comment #14
oppure CreditAttribution: oppure commentedHi thanks for the patch, can you clarify if the fix works only when selecting the javascript based EU only option? If so is it possible to make it work also with smart_ip module? geoip unfortunately can't use cloudflare as location source. Thanks.
Comment #15
clairedesbois@gmail.comTo do tests, I added code to recover the geoip_debug parameter in the URL to use a IP of my choice (I'm in Canada, the patch doesn't work with my true IP thus the cookie is directly setted).
Comment #16
svenryen CreditAttribution: svenryen commentedComment #17
SocialNicheGuru CreditAttribution: SocialNicheGuru commenteddid not apply cleanly to newest dev version.
Comment #18
svenryen CreditAttribution: svenryen commentedThank you for the patch, I've added it to -dev. I improved it a little bit so that it would also show the "Thank you"-banner, and also support smart_ip.
Comment #20
svenryen CreditAttribution: svenryen commented