Chris@0: options = $options; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function hasSession(Request $request) { Chris@0: return $request->cookies->has($this->getName($request)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getOptions(Request $request) { Chris@0: $options = $this->options; Chris@0: Chris@0: // Generate / validate the cookie domain. Chris@0: $options['cookie_domain'] = $this->getCookieDomain($request) ?: ''; Chris@0: Chris@0: // If the site is accessed via SSL, ensure that the session cookie is Chris@0: // issued with the secure flag. Chris@0: $options['cookie_secure'] = $request->isSecure(); Chris@0: Chris@0: // Set the session cookie name. Chris@0: $options['name'] = $this->getName($request); Chris@0: Chris@0: return $options; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns the session cookie name. Chris@0: * Chris@0: * @param \Symfony\Component\HttpFoundation\Request $request Chris@0: * The request. Chris@0: * Chris@0: * @return string Chris@0: * The name of the session cookie. Chris@0: */ Chris@0: protected function getName(Request $request) { Chris@0: // To prevent session cookies from being hijacked, a user can configure the Chris@0: // SSL version of their website to only transfer session cookies via SSL by Chris@0: // using PHP's session.cookie_secure setting. The browser will then use two Chris@0: // separate session cookies for the HTTPS and HTTP versions of the site. So Chris@0: // we must use different session identifiers for HTTPS and HTTP to prevent a Chris@0: // cookie collision. Chris@0: $prefix = $request->isSecure() ? 'SSESS' : 'SESS'; Chris@0: return $prefix . $this->getUnprefixedName($request); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns the session cookie name without the secure/insecure prefix. Chris@0: * Chris@0: * @param \Symfony\Component\HttpFoundation\Request $request Chris@0: * The request. Chris@0: * Chris@0: * @returns string Chris@0: * The session name without the prefix (SESS/SSESS). Chris@0: */ Chris@0: protected function getUnprefixedName(Request $request) { Chris@0: if ($test_prefix = $this->drupalValidTestUa()) { Chris@0: $session_name = $test_prefix; Chris@0: } Chris@0: elseif (isset($this->options['cookie_domain'])) { Chris@0: // If the user specifies the cookie domain, also use it for session name. Chris@0: $session_name = $this->options['cookie_domain']; Chris@0: } Chris@0: else { Chris@0: // Otherwise use $base_url as session name, without the protocol Chris@0: // to use the same session identifiers across HTTP and HTTPS. Chris@0: $session_name = $request->getHost() . $request->getBasePath(); Chris@0: // Replace "core" out of session_name so core scripts redirect properly, Chris@0: // specifically install.php. Chris@0: $session_name = preg_replace('#/core$#', '', $session_name); Chris@0: } Chris@0: Chris@0: return substr(hash('sha256', $session_name), 0, 32); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Return the session cookie domain. Chris@0: * Chris@0: * The Set-Cookie response header and its domain attribute are defined in RFC Chris@17: * 2109, RFC 2965 and RFC 6265 each one superseding the previous version. Chris@0: * Chris@0: * @see http://tools.ietf.org/html/rfc2109 Chris@0: * @see http://tools.ietf.org/html/rfc2965 Chris@0: * @see http://tools.ietf.org/html/rfc6265 Chris@0: * Chris@0: * @param \Symfony\Component\HttpFoundation\Request $request Chris@0: * The request. Chris@0: * Chris@0: * @returns string Chris@0: * The session cookie domain. Chris@0: */ Chris@0: protected function getCookieDomain(Request $request) { Chris@0: if (isset($this->options['cookie_domain'])) { Chris@0: $cookie_domain = $this->options['cookie_domain']; Chris@0: } Chris@0: else { Chris@0: $host = $request->getHost(); Chris@0: // To maximize compatibility and normalize the behavior across user Chris@0: // agents, the cookie domain should start with a dot. Chris@0: $cookie_domain = '.' . $host; Chris@0: } Chris@0: Chris@0: // Cookies for domains without an embedded dot will be rejected by user Chris@0: // agents in order to defeat malicious websites attempting to set cookies Chris@0: // for top-level domains. Also IP addresses may not be used in the domain Chris@0: // attribute of a Set-Cookie header. Chris@0: if (count(explode('.', $cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $cookie_domain))) { Chris@0: return $cookie_domain; Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Wraps drupal_valid_test_ua(). Chris@0: * Chris@0: * @return string|false Chris@0: * Either the simpletest prefix (the string "simpletest" followed by any Chris@0: * number of digits) or FALSE if the user agent does not contain a valid Chris@0: * HMAC and timestamp. Chris@0: */ Chris@0: protected function drupalValidTestUa() { Chris@0: return drupal_valid_test_ua(); Chris@0: } Chris@0: Chris@0: }