/** * Asserts page cache miss, then hit for the given URL; checks cache headers. * * @param \Drupal\Core\Url $url * The URL to test. * @param string[] $expected_contexts * The expected cache contexts for the given URL. * @param string[] $expected_tags * The expected cache tags for the given URL. */ protected function assertPageCacheContextsAndTags(Url $url, array $expected_contexts, array $expected_tags) { $absolute_url = $url->setAbsolute()->toString(); sort($expected_contexts); sort($expected_tags); // Assert cache miss + expected cache contexts + tags. $this->drupalGet($absolute_url); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); $this->assertCacheTags($expected_tags); $this->assertCacheContexts($expected_contexts); // Assert cache hit + expected cache contexts + tags. $this->drupalGet($absolute_url); $this->assertCacheTags($expected_tags); $this->assertCacheContexts($expected_contexts); // Assert page cache item + expected cache tags. $cid_parts = array($url->setAbsolute()->toString(), 'html'); $cid = implode(':', $cid_parts); $cache_entry = \Drupal::cache('render')->get($cid); sort($cache_entry->tags); $this->assertEqual($cache_entry->tags, $expected_tags); if ($cache_entry->tags !== $expected_tags) { debug('Missing cache tags: ' . implode(',', array_diff($cache_entry->tags, $expected_tags))); debug('Unwanted cache tags: ' . implode(',', array_diff($expected_tags, $cache_entry->tags))); } }
/** * Asserts page cache miss, then hit for the given URL; checks cache headers. * * @param \Drupal\Core\Url $url * The URL to test. * @param string[] $expected_contexts * The expected cache contexts for the given URL. * @param string[] $expected_tags * The expected cache tags for the given URL. */ protected function assertPageCacheContextsAndTags(Url $url, array $expected_contexts, array $expected_tags) { $absolute_url = $url->setAbsolute()->toString(); sort($expected_contexts); sort($expected_tags); $get_cache_header_values = function ($header_name) { $header_value = $this->drupalGetHeader($header_name); if (empty($header_value)) { return []; } else { return explode(' ', $header_value); } }; // Assert cache miss + expected cache contexts + tags. $this->drupalGet($absolute_url); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); $actual_contexts = $get_cache_header_values('X-Drupal-Cache-Contexts'); $actual_tags = $get_cache_header_values('X-Drupal-Cache-Tags'); $this->assertIdentical($actual_contexts, $expected_contexts); if ($actual_contexts !== $expected_contexts) { debug('Missing cache contexts: ' . implode(',', array_diff($actual_contexts, $expected_contexts))); debug('Unwanted cache contexts: ' . implode(',', array_diff($expected_contexts, $actual_contexts))); } $this->assertIdentical($actual_tags, $expected_tags); if ($actual_tags !== $expected_tags) { debug('Missing cache tags: ' . implode(',', array_diff($actual_tags, $expected_tags))); debug('Unwanted cache tags: ' . implode(',', array_diff($expected_tags, $actual_tags))); } // Assert cache hit + expected cache contexts + tags. $this->drupalGet($absolute_url); $actual_contexts = $get_cache_header_values('X-Drupal-Cache-Contexts'); $actual_tags = $get_cache_header_values('X-Drupal-Cache-Tags'); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); $this->assertIdentical($actual_contexts, $expected_contexts); if ($actual_contexts !== $expected_contexts) { debug('Missing cache contexts: ' . implode(',', array_diff($actual_contexts, $expected_contexts))); debug('Unwanted cache contexts: ' . implode(',', array_diff($expected_contexts, $actual_contexts))); } $this->assertIdentical($actual_tags, $expected_tags); if ($actual_tags !== $expected_tags) { debug('Missing cache tags: ' . implode(',', array_diff($actual_tags, $expected_tags))); debug('Unwanted cache tags: ' . implode(',', array_diff($expected_tags, $actual_tags))); } // Assert page cache item + expected cache tags. $cid_parts = array($url->setAbsolute()->toString(), 'html'); $cid = implode(':', $cid_parts); $cache_entry = \Drupal::cache('render')->get($cid); sort($cache_entry->tags); $this->assertEqual($cache_entry->tags, $expected_tags); if ($cache_entry->tags !== $expected_tags) { debug('Missing cache tags: ' . implode(',', array_diff($cache_entry->tags, $expected_tags))); debug('Unwanted cache tags: ' . implode(',', array_diff($expected_tags, $cache_entry->tags))); } }
/** * Performs a HTTP request with Basic authentication. * * We do not use \Drupal\simpletest\WebTestBase::drupalGet because we need to * set curl settings for basic authentication. * * @param \Drupal\Core\Url $url * A Url object. * @param string $username * The user name to authenticate with. * @param string $password * The password. * @param string $mime_type * The MIME type for the Accept header. * * @return string * Curl output. */ protected function basicAuthGet(Url $url, $username, $password, $mime_type = NULL) { if (!isset($mime_type)) { $mime_type = $this->defaultMimeType; } $out = $this->curlExec(array(CURLOPT_HTTPGET => TRUE, CURLOPT_URL => $url->setAbsolute()->toString(), CURLOPT_NOBODY => FALSE, CURLOPT_HTTPAUTH => CURLAUTH_BASIC, CURLOPT_USERPWD => $username . ':' . $password, CURLOPT_HTTPHEADER => array('Accept: ' . $mime_type))); $this->verbose('GET request to: ' . $url->toString() . '<hr />' . $out); return $out; }
/** * Builds an a absolute URL from a system path or a URL object. * * @param string|\Drupal\Core\Url $path * A system path or a URL. * @param array $options * Options to be passed to Url::fromUri(). * * @return string * An absolute URL stsring. */ protected function buildUrl($path, array $options = array()) { if ($path instanceof Url) { $url_options = $path->getOptions(); $options = $url_options + $options; $path->setOptions($options); return $path->setAbsolute()->toString(); } elseif ($this->container->has('url_generator')) { $force_internal = isset($options['external']) && $options['external'] == FALSE; if (!$force_internal && UrlHelper::isExternal($path)) { return Url::fromUri($path, $options)->toString(); } else { $uri = $path === '<front>' ? 'base:/' : 'base:/' . $path; // Path processing is needed for language prefixing. Skip it when a // path that may look like an external URL is being used as internal. $options['path_processing'] = !$force_internal; return Url::fromUri($uri, $options)->setAbsolute()->toString(); } } else { return $this->getAbsoluteUrl($path); } }
/** * Builds an a absolute URL from a system path or a URL object. * * @param string|\Drupal\Core\Url $path * A system path or a URL. * @param array $options * Options to be passed to Url::fromUri(). * * @return string * An absolute URL stsring. */ protected function buildUrl($path, array $options = array()) { if ($path instanceof Url) { return $path->setAbsolute()->toString(); } else { if ($this->container->has('url_generator')) { $options['absolute'] = TRUE; return $this->container->get('url_generator')->generateFromPath($path, $options); } else { return $this->getAbsoluteUrl($path); } } }
/** * Prior to set the response it check if we can redirect. * * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event * The event object. * @param \Drupal\Core\Url $url * The Url where we want to redirect. */ protected function setResponse(GetResponseEvent $event, Url $url) { $request = $event->getRequest(); $this->context->fromRequest($request); parse_str($request->getQueryString(), $query); $url->setOption('query', $query); $url->setAbsolute(TRUE); // We can only check access for routed URLs. if (!$url->isRouted() || $this->redirectChecker->canRedirect($url->getRouteName(), $request)) { // Add the 'rendered' cache tag, so that we can invalidate all responses // when settings are changed. $headers = ['X-Drupal-Cache-Tags' => 'rendered']; $event->setResponse(new RedirectResponse($url->toString(), 301, $headers)); } }
/** * Tests that the given path provides the correct alternate hreflang links. * * @param \Drupal\Core\Url $url * The path to be tested. */ protected function doTestAlternateHreflangLinks(Url $url) { $languages = $this->container->get('language_manager')->getLanguages(); $url->setAbsolute(); $urls = []; foreach ($this->langcodes as $langcode) { $language_url = clone $url; $urls[$langcode] = $language_url->setOption('language', $languages[$langcode]); } foreach ($this->langcodes as $langcode) { $this->drupalGet($urls[$langcode]); foreach ($urls as $alternate_langcode => $language_url) { // Retrieve desired link elements from the HTML head. $links = $this->xpath('head/link[@rel = "alternate" and @href = :href and @hreflang = :hreflang]', array(':href' => $language_url->toString(), ':hreflang' => $alternate_langcode)); $this->assert(isset($links[0]), format_string('The %langcode node translation has the correct alternate hreflang link for %alternate_langcode: %link.', array('%langcode' => $langcode, '%alternate_langcode' => $alternate_langcode, '%link' => $url->toString()))); } } }
function testURLTokens() { $url = new Url('entity.node.canonical', array('node' => 1)); $tokens = array('absolute' => $url->setAbsolute()->toString(), 'relative' => $url->setAbsolute(FALSE)->toString(), 'path' => 'first-node', 'brief' => preg_replace(array('!^https?://!', '!/$!'), '', $url->setAbsolute()->toString()), 'args:value:0' => 'first-node', 'args:value:1' => NULL, 'args:value:N' => NULL, 'unaliased' => $url->setAbsolute()->setOption('alias', TRUE)->toString(), 'unaliased:relative' => $url->setAbsolute(FALSE)->setOption('alias', TRUE)->toString(), 'unaliased:path' => 'node/1', 'unaliased:brief' => preg_replace(array('!^https?://!', '!/$!'), '', $url->setAbsolute()->setOption('alias', TRUE)->toString()), 'unaliased:args:value:0' => 'node', 'unaliased:args:value:1' => '1', 'unaliased:args:value:2' => NULL, 'alias' => 'first-node'); $this->assertTokens('url', array('url' => new Url('entity.node.canonical', array('node' => 1))), $tokens); }
/** * Prior to set the response it check if we can redirect. * * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event * The event object. * @param \Drupal\Core\Url $url * The Url where we want to redirect. */ protected function setResponse(GetResponseEvent $event, Url $url) { $request = $event->getRequest(); $this->context->fromRequest($request); parse_str($request->getQueryString(), $query); $url->setOption('query', $query); $url->setAbsolute(TRUE); // We can only check access for routed URLs. if (!$url->isRouted() || $this->checker->canRedirect($request, $url->getRouteName())) { // Add the 'rendered' cache tag, so that we can invalidate all responses // when settings are changed. $response = new TrustedRedirectResponse($url->toString(), 301); $response->addCacheableDependency(CacheableMetadata::createFromRenderArray([])->addCacheTags(['rendered'])); $event->setResponse($response); } }
/** * Retrieves a Drupal path or an absolute path. * * @param string|\Drupal\Core\Url $path * Drupal path or URL to load into Mink controlled browser. * @param array $options * (optional) Options to be forwarded to the url generator. * * @return string * The retrieved HTML string, also available as $this->getRawContent() */ protected function drupalGet($path, array $options = array()) { $options['absolute'] = TRUE; if ($path instanceof Url) { $url_options = $path->getOptions(); $options = $url_options + $options; $path->setOptions($options); $url = $path->setAbsolute()->toString(); } // The URL generator service is not necessarily available yet; e.g., in // interactive installer tests. elseif ($this->container->has('url_generator')) { if (UrlHelper::isExternal($path)) { $url = Url::fromUri($path, $options)->toString(); } else { // This is needed for language prefixing. $options['path_processing'] = TRUE; $url = Url::fromUri('base:/' . $path, $options)->toString(); } } else { $url = $this->getAbsoluteUrl($path); } $session = $this->getSession(); $this->prepareRequest(); $session->visit($url); $out = $session->getPage()->getContent(); // Ensure that any changes to variables in the other thread are picked up. $this->refreshVariables(); if ($this->htmlOutputEnabled) { $html_output = 'GET request to: ' . $url . '<hr />Ending URL: ' . $this->getSession()->getCurrentUrl(); $html_output .= '<hr />' . $out; $html_output .= $this->getHtmlOutputHeaders(); $this->htmlOutput($html_output); } return $out; }