TLDR

  • Quicklink has a default setting that turns off the library when it detects a session. It detects sessions using $session->isStarted()
  • Starting at Drupal 8.14, this detects a session for anonymous users when there should be none. This is on a basic standard Drupal install.
  • This causes the library not to load and breaks functionality.

To reproduce:

1. New install of Drupal 8.6.14 - standard profile under PHP 7.2.14
2. Install Devel, generate 50 content nodes.
3. Install Quicklink. Enable debug mode.
4. Clear cache
5. In incognito mode, quicklink is not being loaded. Looking at module debug log indicates this is because we think there is a session.

Comments

mherchel created an issue. See original summary.

mherchel’s picture

StatusFileSize
new593 bytes

When I'm anonymous in Xdebug and I'm evaluating expressions, $session->isStarted() returns true, while $session->start() returns false.

I'm not sure what the difference is, and why they would be returning a different value.

I can verify that when I am logged in, $session->start() returns true.

@andyg5000 Can you review this?

mherchel’s picture

This is weird. The change record (https://www.drupal.org/node/2228871) indicates the original code should be working.

mherchel’s picture

Title: Quicklink thinks session is started when it is not » Quicklink can think session is started when it is not
andyg5000’s picture

Yea, the patch doesn't make sense to me and seems like it should be working as-is. Is this a vanilla Drupal site you're testing or something that might be using private storage or other session invoking code?

mherchel’s picture

Troubleshooting log:

1) $session->isStarted() is set to true.
2) When I step into isStarted(), I see that $this->startedLazy is set to true

3) I then set breakpoints everywhere in core where startedLazy is being set to TRUE (there are only two).

4) It breaks at SessionManager.php at line 140. This is where startedLazy is being set to TRUE.

mherchel’s picture

I uninstalled BigPipe. But the issue persists.

mherchel’s picture

mherchel’s picture

Yeah, so I'm pretty sure this is related to Drupal core issue #3045349: Lazy started sessions with session data are not saved with symfony/http-foundation 3.4.24, where the isStarted() function is overwritten and now checks for lazy sessions.

mherchel’s picture

Yep. Verified this works properly in Drupal 8.6.13 but is broken in Drupal 8.6.14.

This issue definitely seems to be caused by #3045349: Lazy started sessions with session data are not saved with symfony/http-foundation 3.4.24

mherchel’s picture

Title: Quicklink can think session is started when it is not » Quicklink detects session when there is none in Drupal 8.6.14 and above
mherchel’s picture

Issue summary: View changes
mglaman’s picture

+++ b/quicklink.module
@@ -153,7 +153,7 @@ function quicklink_preprocess_html(&$variables, $hook) {
     $session = \Drupal::getContainer()->get('session_manager');
-    if (!empty($session) && $session->isStarted()) {
+    if (!empty($session) && $session->start()) {

The session manager should never be empty.

mglaman’s picture

👀looks like you could use some help writing some tests to catch this.

mglaman’s picture

Here are three patches. The last one using session_configuration should work, and is why page_cache did not break in Drupal core -- this is how it detects a session.

mglaman’s picture

Status: Active » Needs review
StatusFileSize
new3.57 KB

Here's a patch which has a test that shows HEAD has a failure.

mglaman’s picture

Assigned: Unassigned » mglaman
StatusFileSize
new4.19 KB

This uses a setup script. And fixes another missing config item in the schema.

mglaman’s picture

StatusFileSize
new4.92 KB

Here's a patch with the fix. However, please don't commit this just yet. Tomorrow I'd like to provide a proper patch for the schema.yml. Or at least fix the labels in this one.

mherchel’s picture

Thanks for all your work on this. Note that I just added the config schema to 8.x-1.x-dev within #3042448: Add config schema for quicklink.settings.

mglaman’s picture

Assigned: mglaman » Unassigned
StatusFileSize
new7.73 KB
new3.6 KB

Here is a reroll. I made one against 8.x-1.x and the 8.x-1.x-dev (which shouldn't exist?)

mglaman’s picture

FWIW you probably need to merge 8.x-1.x-dev into 8.x-1.x and then delete the 8.x-1.x-dev branch, then patch two from #20 will apply.

  • mherchel committed 7ec743c on 8.x-1.x authored by mglaman
    Issue #3047931 by mglaman, mherchel, q0rban: Quicklink detects session...
mherchel’s picture

Status: Needs review » Fixed

Fixed and pushed to 8.x-1.1! Thanks @mglaman!

wim leers’s picture

Yep, you want to use SessionConfigurationInterface::hasSession(), this is also what BigPipe uses to only activate itself for requests with sessions (see https://git.drupalcode.org/project/drupal/blob/c779a82a28c2e9f140f6a11db...).

So the committed solution should work fine! 👍

While looking at the code, I did spot two problems, both relating to cacheability:

  1. $variables['#cache']['contexts'][] = 'session.exists'; should be inside the "if no_load_when_session" branch, to vary correctly — BigPipe does this too (see https://git.drupalcode.org/project/drupal/blob/c779a82a28c2e9f140f6a11db...) — this is still directly related to the originally reported problem
  2. $variables['#cache']['tags'] = $config->getCacheTags(); should be added immediately after loading $config to ensure that configuration changes are reflected immediately, without manual clearing of caches :) — this one I just noticed by looking at everything above.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.