/**
  * Sets extra headers on successful responses.
  *
  * @param Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
  *   The event to process.
  */
 public function onRespond(FilterResponseEvent $event)
 {
     if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) {
         return;
     }
     $request = $event->getRequest();
     $response = $event->getResponse();
     // Set the X-UA-Compatible HTTP header to force IE to use the most recent
     // rendering engine or use Chrome's frame rendering engine if available.
     $response->headers->set('X-UA-Compatible', 'IE=edge,chrome=1', FALSE);
     // Set the Content-language header.
     $response->headers->set('Content-language', $this->languageManager->getCurrentLanguage()->id);
     // Attach globally-declared headers to the response object so that Symfony
     // can send them for us correctly.
     // @todo remove this once we have removed all drupal_add_http_header()
     //   calls.
     $headers = drupal_get_http_header();
     foreach ($headers as $name => $value) {
         $response->headers->set($name, $value, FALSE);
     }
     $is_cacheable = drupal_page_is_cacheable();
     // Add headers necessary to specify whether the response should be cached by
     // proxies and/or the browser.
     if ($is_cacheable && $this->config->get('cache.page.max_age') > 0) {
         if (!$this->isCacheControlCustomized($response)) {
             $this->setResponseCacheable($response, $request);
         }
     } else {
         $this->setResponseNotCacheable($response, $request);
     }
     // Currently it is not possible to cache some types of responses. Therefore
     // exclude binary file responses (generated files, e.g. images with image
     // styles) and streamed responses (files directly read from the disk).
     // see: https://github.com/symfony/symfony/issues/9128#issuecomment-25088678
     if ($is_cacheable && $this->config->get('cache.page.use_internal') && !$response instanceof BinaryFileResponse && !$response instanceof StreamedResponse) {
         // Store the response in the internal page cache.
         drupal_page_set_cache($response, $request);
         $response->headers->set('X-Drupal-Cache', 'MISS');
         drupal_serve_page_from_cache($response, $request);
     }
 }
Esempio n. 2
0
/**
 * Allow other modules to modify $children & $elements before they are rendered.
 *
 * @param $children
 *   An array of children elements.
 * @param $elements
 *   A render array containing:
 *   - #items: The JavaScript items as returned by drupal_add_js() and
 *     altered by drupal_get_js().
 *   - #group_callback: A function to call to group #items. Following
 *     this function, #aggregate_callback is called to aggregate items within
 *     the same group into a single file.
 *   - #aggregate_callback: A function to call to aggregate the items within
 *     the groups arranged by the #group_callback function.
 *
 * @see advagg_modify_js_pre_render()
 * @see advagg_js_compress_advagg_modify_js_pre_render_alter()
 */
function hook_advagg_modify_js_pre_render_alter(&$children, &$elements)
{
    // Get variables.
    $aggregate_settings['variables']['advagg_js_compressor'] = variable_get('advagg_js_inline_compressor', ADVAGG_JS_INLINE_COMPRESSOR);
    $aggregate_settings['variables']['advagg_js_max_compress_ratio'] = variable_get('advagg_js_max_compress_ratio', ADVAGG_JS_MAX_COMPRESS_RATIO);
    // Do nothing if the compressor is disabled.
    if (empty($aggregate_settings['variables']['advagg_js_compressor'])) {
        return;
    }
    // Do nothing if the page is not cacheable and inline compress if not
    // cacheable is not checked.
    if (!variable_get('advagg_js_inline_compress_if_not_cacheable', ADVAGG_JS_INLINE_COMPRESS_IF_NOT_CACHEABLE) && !drupal_page_is_cacheable()) {
        return;
    }
    // Compress any inline JS.
    module_load_include('inc', 'advagg_js_compress', 'advagg_js_compress.advagg');
    foreach ($children as $key => &$values) {
        if (!empty($values['#value'])) {
            $contents = $values['#value'];
            $filename = drupal_hash_base64($contents);
            advagg_js_compress_prep($contents, $filename, $aggregate_settings, FALSE);
            $values['#value'] = $contents;
        }
    }
}
  /**
   * Get the user account for the request.
   *
   * @param array $request
   *   The request.
   * @param string $method
   *   The HTTP method.
   * @param boolean $cache
   *   Boolean indicating if the resolved user should be cached for next calls.
   *
   * @throws RestfulUnauthorizedException
   * @return \stdClass
   *   The user object.
   */
  public function getAccount(array $request = array(), $method = \RestfulInterface::GET, $cache = TRUE) {
    global $user;

    // Return the previously resolved user, if any.
    if (!empty($this->account)) {
      return $this->account;
    }

    // Resolve the user based on the providers in the manager.
    $account = NULL;
    foreach ($this as $provider) {
      if ($provider->applies($request, $method) && $account = $provider->authenticate($request, $method)) {
        // The account has been loaded, we can stop looking.
        break;
      }
    }

    if (!$account) {

      if ($this->count() && !$this->getIsOptional()) {
        // Allow caching pages for anonymous users.
        drupal_page_is_cacheable(variable_get('restful_page_cache', FALSE));

        // User didn't authenticate against any provider, so we throw an error.
        throw new \RestfulUnauthorizedException('Bad credentials');
      }

      // If the account could not be authenticated default to the global user.
      // Most of the cases the cookie provider will do this for us.
      $account = drupal_anonymous_user();

      if (empty($request['__application']['rest_call'])) {
        // If we are using the API from within Drupal and we have not tried to
        // authenticate using the 'cookie' provider, then we expect to be logged
        // in using the cookie authentication as a last resort.
        $account = $user->uid ? user_load($user->uid) : $account;
      }
    }
    if ($cache) {
      $this->setAccount($account);
    }

    // Disable page caching for security reasons so that an authenticated user
    // response never gets into the page cache for anonymous users.
    // This is necessary because the page cache system only looks at session
    // cookies, but not at HTTP Basic Auth headers.
    drupal_page_is_cacheable(!$account->uid && variable_get('restful_page_cache', FALSE));

    // Record the access time of this request.
    $this->setAccessTime($account);

    return $account;
  }
 /**
  * Get kernel
  *
  * @return KernelInterface
  */
 private function getKernel()
 {
     if (!$this->kernel) {
         if (!self::$bootstrapped) {
             // Avoid Drupal attempt to return a cached page while we are
             // actually unit testing it
             drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
             $GLOBALS['conf']['cache'] = 0;
             drupal_page_is_cacheable(false);
             drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
             self::$bootstrapped = true;
         }
         $this->kernel = $this->createKernelInstance(uniqid('test_'));
         $this->kernel->boot();
         $this->kernel->getContainer()->get('request_stack')->push(\MakinaCorpus\Drupal\Sf\Http\Request::createFromGlobals());
         \Drupal::_setKernel($this->kernel);
     }
     return $this->kernel;
 }
Esempio n. 5
0
 /**
  * Default constructor.
  */
 public function __construct()
 {
     global $user, $is_https;
     $this->httpsEnabled = $this->handleHttps() && $is_https;
     $this->sessionName = session_name();
     if ($this->httpsEnabled) {
         $this->sessionNameUnsecure = substr(session_name(), 1);
     }
     if (!empty($_COOKIE[$this->sessionName]) || $this->httpsEnabled && !empty($_COOKIE[$this->sessionNameUnsecure])) {
         // If a session cookie exists, initialize the session. Otherwise the
         // session is only started on demand in drupal_session_commit(), making
         // anonymous users not use a session cookie unless something is stored in
         // $_SESSION. This allows HTTP proxies to cache anonymous page views.
         $this->start();
         $this->sessionIdentifier = session_id();
         $this->refreshAfterSessionChange();
         if ($user->uid || !$this->sessionIsEmpty()) {
             drupal_page_is_cacheable(FALSE);
         }
     } else {
         // Set a session identifier for this request. This is necessary because
         // we lazily start sessions at the end of this request, and some
         // processes (like drupal_get_token()) needs to know the future
         // session ID in advance.
         $user = drupal_anonymous_user();
         $this->generateSessionIdentifier();
         $this->refreshAfterSessionChange();
     }
 }
 /**
  * Generates a derivative, given a style and image path.
  *
  * After generating an image, transfer it to the requesting agent.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request object.
  * @param string $scheme
  *   The file scheme, defaults to 'private'.
  * @param \Drupal\image\ImageStyleInterface $image_style
  *   The image style to deliver.
  *
  * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
  *   Thrown when the user does not have access to the file.
  * @throws \Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException
  *   Thrown when the file is still being generated.
  *
  * @return \Symfony\Component\HttpFoundation\BinaryFileResponse|\Symfony\Component\HttpFoundation\Response
  *   The transferred file as response or some error response.
  */
 public function deliver(Request $request, $scheme, ImageStyleInterface $image_style)
 {
     $target = $request->query->get('file');
     $image_uri = $scheme . '://' . $target;
     // Check that the style is defined, the scheme is valid, and the image
     // derivative token is valid. Sites which require image derivatives to be
     // generated without a token can set the
     // 'image.settings:allow_insecure_derivatives' configuration to TRUE to
     // bypass the latter check, but this will increase the site's vulnerability
     // to denial-of-service attacks.
     $valid = !empty($image_style) && file_stream_wrapper_valid_scheme($scheme);
     if (!$this->config('image.settings')->get('allow_insecure_derivatives')) {
         $valid &= $request->query->get(IMAGE_DERIVATIVE_TOKEN) === $image_style->getPathToken($image_uri);
     }
     if (!$valid) {
         throw new AccessDeniedHttpException();
     }
     $derivative_uri = $image_style->buildUri($image_uri);
     $headers = array();
     // If using the private scheme, let other modules provide headers and
     // control access to the file.
     if ($scheme == 'private') {
         if (file_exists($derivative_uri)) {
             return parent::download($request, $scheme);
         } else {
             $headers = $this->moduleHandler()->invokeAll('file_download', array($image_uri));
             if (in_array(-1, $headers) || empty($headers)) {
                 throw new AccessDeniedHttpException();
             }
         }
     }
     // Don't try to generate file if source is missing.
     if (!file_exists($image_uri)) {
         watchdog('image', 'Source image at %source_image_path not found while trying to generate derivative image at %derivative_path.', array('%source_image_path' => $image_uri, '%derivative_path' => $derivative_uri));
         return new Response($this->t('Error generating image, missing source file.'), 404);
     }
     // Don't start generating the image if the derivative already exists or if
     // generation is in progress in another thread.
     $lock_name = 'image_style_deliver:' . $image_style->id() . ':' . Crypt::hashBase64($image_uri);
     if (!file_exists($derivative_uri)) {
         $lock_acquired = $this->lock->acquire($lock_name);
         if (!$lock_acquired) {
             // Tell client to retry again in 3 seconds. Currently no browsers are
             // known to support Retry-After.
             throw new ServiceUnavailableHttpException(3, $this->t('Image generation in progress. Try again shortly.'));
         }
     }
     // Try to generate the image, unless another thread just did it while we
     // were acquiring the lock.
     $success = file_exists($derivative_uri) || $image_style->createDerivative($image_uri, $derivative_uri);
     if (!empty($lock_acquired)) {
         $this->lock->release($lock_name);
     }
     if ($success) {
         drupal_page_is_cacheable(FALSE);
         $image = $this->imageFactory->get($derivative_uri);
         $uri = $image->getSource();
         $headers += array('Content-Type' => $image->getMimeType(), 'Content-Length' => $image->getFileSize());
         return new BinaryFileResponse($uri, 200, $headers);
     } else {
         watchdog('image', 'Unable to generate the derived image located at %path.', array('%path' => $derivative_uri));
         return new Response($this->t('Error generating image.'), 500);
     }
 }
Esempio n. 7
0
 /**
  * {@inheritdoc}
  */
 public function startLazy()
 {
     global $user;
     if (($this->started || $this->startedLazy) && !$this->closed) {
         return $this->started;
     }
     $is_https = $this->requestStack->getCurrentRequest()->isSecure();
     $cookies = $this->requestStack->getCurrentRequest()->cookies;
     $insecure_session_name = $this->getInsecureName();
     if ($cookies->has($this->getName()) && ($session_name = $cookies->get($this->getName())) || $is_https && $this->isMixedMode() && ($cookies->has($insecure_session_name) && ($session_name = $cookies->get($insecure_session_name)))) {
         // If a session cookie exists, initialize the session. Otherwise the
         // session is only started on demand in save(), making
         // anonymous users not use a session cookie unless something is stored in
         // $_SESSION. This allows HTTP proxies to cache anonymous pageviews.
         $result = $this->start();
         if ($user->isAuthenticated() || !$this->isSessionObsolete()) {
             drupal_page_is_cacheable(FALSE);
         }
     } else {
         // Set a session identifier for this request. This is necessary because
         // we lazily start sessions at the end of this request, and some
         // processes (like \Drupal::csrfToken()) needs to know the future
         // session ID in advance.
         $user = new AnonymousUserSession();
         $this->setId(Crypt::randomBytesBase64());
         if ($is_https && $this->isMixedMode()) {
             $session_id = Crypt::randomBytesBase64();
             $cookies->set($insecure_session_name, $session_id);
         }
         $result = FALSE;
     }
     date_default_timezone_set(drupal_get_user_timezone());
     $this->startedLazy = TRUE;
     return $result;
 }
Esempio n. 8
0
 /**
  * {@inheritdoc}
  *
  * @todo Invoke proper request/response/terminate events.
  */
 public function handlePageCache(Request $request)
 {
     $this->boot();
     $this->initializeCookieGlobals($request);
     // Check for a cache mode force from settings.php.
     if (Settings::get('page_cache_without_database')) {
         $cache_enabled = TRUE;
     } else {
         $config = $this->getContainer()->get('config.factory')->get('system.performance');
         $cache_enabled = $config->get('cache.page.use_internal');
     }
     // If there is no session cookie and cache is enabled (or forced), try to
     // serve a cached page.
     if (!$request->cookies->has(session_name()) && $cache_enabled && drupal_page_is_cacheable()) {
         // Get the page from the cache.
         $response = drupal_page_get_cache($request);
         // If there is a cached page, display it.
         if ($response) {
             $response->headers->set('X-Drupal-Cache', 'HIT');
             drupal_serve_page_from_cache($response, $request);
             // We are done.
             $response->prepare($request);
             $response->send();
             exit;
         }
     }
     return $this;
 }