Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\big_pipe\Controller;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\big_pipe\Render\Placeholder\BigPipeStrategy;
|
Chris@0
|
6 use Drupal\Core\Cache\CacheableMetadata;
|
Chris@0
|
7 use Drupal\Core\Routing\LocalRedirectResponse;
|
Chris@0
|
8 use Symfony\Component\HttpFoundation\Cookie;
|
Chris@0
|
9 use Symfony\Component\HttpFoundation\Request;
|
Chris@0
|
10 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
Chris@0
|
11 use Symfony\Component\HttpKernel\Exception\HttpException;
|
Chris@0
|
12
|
Chris@0
|
13 /**
|
Chris@0
|
14 * Returns responses for BigPipe module routes.
|
Chris@0
|
15 */
|
Chris@0
|
16 class BigPipeController {
|
Chris@0
|
17
|
Chris@0
|
18 /**
|
Chris@0
|
19 * Sets a BigPipe no-JS cookie, redirects back to the original location.
|
Chris@0
|
20 *
|
Chris@0
|
21 * @param \Symfony\Component\HttpFoundation\Request $request
|
Chris@0
|
22 * The current request.
|
Chris@0
|
23 *
|
Chris@0
|
24 * @return \Drupal\Core\Routing\LocalRedirectResponse
|
Chris@0
|
25 * A response that sets the no-JS cookie and redirects back to the original
|
Chris@0
|
26 * location.
|
Chris@0
|
27 *
|
Chris@0
|
28 * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
|
Chris@0
|
29 * Thrown when the no-JS cookie is already set or when there is no session.
|
Chris@0
|
30 * @throws \Symfony\Component\HttpKernel\Exception\HttpException
|
Chris@0
|
31 * Thrown when the original location is missing, i.e. when no 'destination'
|
Chris@0
|
32 * query argument is set.
|
Chris@0
|
33 *
|
Chris@0
|
34 * @see \Drupal\big_pipe\Render\Placeholder\BigPipeStrategy
|
Chris@0
|
35 */
|
Chris@0
|
36 public function setNoJsCookie(Request $request) {
|
Chris@0
|
37 // This controller may only be accessed when the browser does not support
|
Chris@0
|
38 // JavaScript. It is accessed automatically when that's the case thanks to
|
Chris@0
|
39 // big_pipe_page_attachments(). When this controller is executed, deny
|
Chris@0
|
40 // access when either:
|
Chris@0
|
41 // - the no-JS cookie is already set: this indicates a redirect loop, since
|
Chris@0
|
42 // the cookie was already set, yet the user is executing this controller;
|
Chris@0
|
43 // - there is no session, in which case BigPipe is not enabled anyway, so it
|
Chris@0
|
44 // is pointless to set this cookie.
|
Chris@18
|
45 if ($request->cookies->has(BigPipeStrategy::NOJS_COOKIE) || !$request->hasSession()) {
|
Chris@0
|
46 throw new AccessDeniedHttpException();
|
Chris@0
|
47 }
|
Chris@0
|
48
|
Chris@0
|
49 if (!$request->query->has('destination')) {
|
Chris@0
|
50 throw new HttpException(400, 'The original location is missing.');
|
Chris@0
|
51 }
|
Chris@0
|
52
|
Chris@0
|
53 $response = new LocalRedirectResponse($request->query->get('destination'));
|
Chris@0
|
54 // Set cookie without httpOnly, so that JavaScript can delete it.
|
Chris@18
|
55 $response->headers->setCookie(new Cookie(BigPipeStrategy::NOJS_COOKIE, TRUE, 0, '/', NULL, FALSE, FALSE, FALSE, NULL));
|
Chris@0
|
56 $response->addCacheableDependency((new CacheableMetadata())->addCacheContexts(['cookies:' . BigPipeStrategy::NOJS_COOKIE, 'session.exists']));
|
Chris@0
|
57 return $response;
|
Chris@0
|
58 }
|
Chris@0
|
59
|
Chris@0
|
60 }
|