Commit 221ab60f authored by catch's avatar catch
Browse files

Issue #2678628 by Wim Leers: Consider removing the BigPipe no-JS cookie when...

Issue #2678628 by Wim Leers: Consider removing the BigPipe no-JS cookie when JS is enabled again in a browser
parent c1b5d37d
......@@ -48,19 +48,32 @@ function big_pipe_page_attachments(array &$page) {
// avoid endless redirect loops.
$has_big_pipe_nojs_cookie = $request->cookies->has(BigPipeStrategy::NOJS_COOKIE);
$page['#cache']['contexts'][] = 'cookies:' . BigPipeStrategy::NOJS_COOKIE;
if ($session_exists && !$has_big_pipe_nojs_cookie) {
$page['#attached']['html_head'][] = [
[
// Redirect through a 'Refresh' meta tag if JavaScript is disabled.
'#tag' => 'meta',
'#noscript' => TRUE,
'#attributes' => [
'http-equiv' => 'Refresh',
// @todo: Switch to Url::fromRoute() once https://www.drupal.org/node/2589967 is resolved.
'content' => '0; URL=' . Url::fromUri('internal:/big_pipe/no-js', ['query' => \Drupal::service('redirect.destination')->getAsArray()])->toString(),
if ($session_exists) {
if (!$has_big_pipe_nojs_cookie) {
// Let server set the BigPipe no-JS cookie.
$page['#attached']['html_head'][] = [
[
// Redirect through a 'Refresh' meta tag if JavaScript is disabled.
'#tag' => 'meta',
'#noscript' => TRUE,
'#attributes' => [
'http-equiv' => 'Refresh',
// @todo: Switch to Url::fromRoute() once https://www.drupal.org/node/2589967 is resolved.
'content' => '0; URL=' . Url::fromUri('internal:/big_pipe/no-js', ['query' => \Drupal::service('redirect.destination')->getAsArray()])->toString(),
],
],
],
'big_pipe_detect_nojs',
];
'big_pipe_detect_nojs',
];
}
else {
// Let client delete the BigPipe no-JS cookie.
$page['#attached']['html_head'][] = [
[
'#tag' => 'script',
'#value' => 'document.cookie = "' . BigPipeStrategy::NOJS_COOKIE . '=1; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"',
],
'big_pipe_detect_js',
];
}
}
}
......@@ -56,7 +56,8 @@ public function setNoJsCookie(Request $request) {
}
$response = new LocalRedirectResponse($request->query->get('destination'));
$response->headers->setCookie(new Cookie(BigPipeStrategy::NOJS_COOKIE, TRUE));
// Set cookie without httpOnly, so that JavaScript can delete it.
$response->headers->setCookie(new Cookie(BigPipeStrategy::NOJS_COOKIE, TRUE, 0, '/', NULL, FALSE, FALSE));
$response->addCacheableDependency((new CacheableMetadata())->addCacheContexts(['cookies:' . BigPipeStrategy::NOJS_COOKIE, 'session.exists']));
return $response;
}
......
......@@ -7,6 +7,7 @@
namespace Drupal\big_pipe\Tests;
use Drupal\big_pipe\Render\Placeholder\BigPipeStrategy;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Html;
use Drupal\Core\Url;
......@@ -78,20 +79,25 @@ protected function performMetaRefresh() {
* - \Drupal\big_pipe\Controller\BigPipeController
*/
public function testNoJsDetection() {
$no_js_to_js_markup = '<script>document.cookie = "' . BigPipeStrategy::NOJS_COOKIE . '=1; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"</script>';
// 1. No session (anonymous).
$this->drupalGet(Url::fromRoute('<front>'));
$this->assertSessionCookieExists(FALSE);
$this->assertBigPipeNoJsCookieExists(FALSE);
$this->assertNoRaw('<noscript><meta http-equiv="Refresh" content="0; URL=');
$this->assertNoRaw($no_js_to_js_markup);
// 2. Session (authenticated).
$this->drupalLogin($this->rootUser);
$this->assertSessionCookieExists(TRUE);
$this->assertBigPipeNoJsCookieExists(FALSE);
$this->assertRaw('<noscript><meta http-equiv="Refresh" content="0; URL=' . base_path() . 'big_pipe/no-js?destination=' . base_path() . 'user/1" />' . "\n" . '</noscript>');
$this->assertNoRaw($no_js_to_js_markup);
$this->assertBigPipeNoJsMetaRefreshRedirect();
$this->assertBigPipeNoJsCookieExists(TRUE);
$this->assertNoRaw('<noscript><meta http-equiv="Refresh" content="0; URL=');
$this->assertRaw($no_js_to_js_markup);
$this->drupalLogout();
// Close the prior connection and remove the collected state.
......@@ -105,9 +111,11 @@ public function testNoJsDetection() {
$this->assertSessionCookieExists(TRUE);
$this->assertBigPipeNoJsCookieExists(FALSE);
$this->assertRaw('<noscript><meta http-equiv="Refresh" content="0; URL=' . base_path() . 'big_pipe/no-js?destination=' . base_path() . 'user/login" />' . "\n" . '</noscript>');
$this->assertNoRaw($no_js_to_js_markup);
$this->assertBigPipeNoJsMetaRefreshRedirect();
$this->assertBigPipeNoJsCookieExists(TRUE);
$this->assertNoRaw('<noscript><meta http-equiv="Refresh" content="0; URL=');
$this->assertRaw($no_js_to_js_markup);
// Close the prior connection and remove the collected state.
$this->curlClose();
......@@ -119,11 +127,13 @@ public function testNoJsDetection() {
$this->assertSessionCookieExists(FALSE);
$this->assertBigPipeNoJsCookieExists(FALSE);
$this->assertNoRaw('<noscript><meta http-equiv="Refresh" content="0; URL=');
$this->assertNoRaw($no_js_to_js_markup);
$this->drupalLogin($this->rootUser);
$this->drupalGet(Url::fromRoute('big_pipe_test.no_big_pipe'));
$this->assertSessionCookieExists(TRUE);
$this->assertBigPipeNoJsCookieExists(FALSE);
$this->assertNoRaw('<noscript><meta http-equiv="Refresh" content="0; URL=');
$this->assertNoRaw($no_js_to_js_markup);
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment