You are here

protected function WebTestBase::curlExec in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 core/modules/simpletest/src/WebTestBase.php \Drupal\simpletest\WebTestBase::curlExec()

Initializes and executes a cURL request.

Parameters

$curl_options: An associative array of cURL options to set, where the keys are constants defined by the cURL library. For a list of valid options, see http://www.php.net/manual/function.curl-setopt.php

$redirect: FALSE if this is an initial request, TRUE if this request is the result of a redirect.

Return value

The content returned from the call to curl_exec().

See also

curlInitialize()

11 calls to WebTestBase::curlExec()
CommentNewIndicatorTest::renderNewCommentsNodeLinks in core/modules/comment/src/Tests/CommentNewIndicatorTest.php
Get node "x new comments" metadata from the server for the current user.
ContentTranslationContextualLinksTest::renderContextualLinks in core/modules/content_translation/src/Tests/ContentTranslationContextualLinksTest.php
Get server-rendered contextual links for the given contextual link ids.
HistoryTest::getNodeReadTimestamps in core/modules/history/src/Tests/HistoryTest.php
Get node read timestamps from the server for the current user.
HistoryTest::markNodeAsRead in core/modules/history/src/Tests/HistoryTest.php
Mark a node as read for the current user.
NodeContextualLinksTest::renderContextualLinks in core/modules/node/src/Tests/Views/NodeContextualLinksTest.php
Get server-rendered contextual links for the given contextual link ids.

... See full list

2 methods override WebTestBase::curlExec()
RESTTestBase::curlExec in core/modules/rest/src/Tests/RESTTestBase.php
This method is overridden to deal with a cURL quirk: the usage of CURLOPT_CUSTOMREQUEST cannot be unset on the cURL handle, so we need to override it every time it is omitted.
StandardInstallerTest::curlExec in core/modules/system/src/Tests/Installer/StandardInstallerTest.php
Initializes and executes a cURL request.

File

core/modules/simpletest/src/WebTestBase.php, line 1319
Contains \Drupal\simpletest\WebTestBase.

Class

WebTestBase
Test case for typical Drupal tests.

Namespace

Drupal\simpletest

Code

protected function curlExec($curl_options, $redirect = FALSE) {
  $this
    ->curlInitialize();
  if (!empty($curl_options[CURLOPT_URL])) {

    // cURL incorrectly handles URLs with a fragment by including the
    // fragment in the request to the server, causing some web servers
    // to reject the request citing "400 - Bad Request". To prevent
    // this, we strip the fragment from the request.
    // TODO: Remove this for Drupal 8, since fixed in curl 7.20.0.
    if (strpos($curl_options[CURLOPT_URL], '#')) {
      $original_url = $curl_options[CURLOPT_URL];
      $curl_options[CURLOPT_URL] = strtok($curl_options[CURLOPT_URL], '#');
    }
  }
  $url = empty($curl_options[CURLOPT_URL]) ? curl_getinfo($this->curlHandle, CURLINFO_EFFECTIVE_URL) : $curl_options[CURLOPT_URL];
  if (!empty($curl_options[CURLOPT_POST])) {

    // This is a fix for the Curl library to prevent Expect: 100-continue
    // headers in POST requests, that may cause unexpected HTTP response
    // codes from some webservers (like lighttpd that returns a 417 error
    // code). It is done by setting an empty "Expect" header field that is
    // not overwritten by Curl.
    $curl_options[CURLOPT_HTTPHEADER][] = 'Expect:';
  }
  $cookies = array();
  if (!empty($this->curlCookies)) {
    $cookies = $this->curlCookies;
  }

  // In order to debug web tests you need to either set a cookie, have the
  // Xdebug session in the URL or set an environment variable in case of CLI
  // requests. If the developer listens to connection on the parent site, by
  // default the cookie is not forwarded to the client side, so you cannot
  // debug the code running on the child site. In order to make debuggers work
  // this bit of information is forwarded. Make sure that the debugger listens
  // to at least three external connections.
  $request = \Drupal::request();
  $cookie_params = $request->cookies;
  if ($cookie_params
    ->has('XDEBUG_SESSION')) {
    $cookies[] = 'XDEBUG_SESSION=' . $cookie_params
      ->get('XDEBUG_SESSION');
  }

  // For CLI requests, the information is stored in $_SERVER.
  $server = $request->server;
  if ($server
    ->has('XDEBUG_CONFIG')) {

    // $_SERVER['XDEBUG_CONFIG'] has the form "key1=value1 key2=value2 ...".
    $pairs = explode(' ', $server
      ->get('XDEBUG_CONFIG'));
    foreach ($pairs as $pair) {
      list($key, $value) = explode('=', $pair);

      // Account for key-value pairs being separated by multiple spaces.
      if (trim($key, ' ') == 'idekey') {
        $cookies[] = 'XDEBUG_SESSION=' . trim($value, ' ');
      }
    }
  }

  // Merge additional cookies in.
  if (!empty($cookies)) {
    $curl_options += array(
      CURLOPT_COOKIE => '',
    );

    // Ensure any existing cookie data string ends with the correct separator.
    if (!empty($curl_options[CURLOPT_COOKIE])) {
      $curl_options[CURLOPT_COOKIE] = rtrim($curl_options[CURLOPT_COOKIE], '; ') . '; ';
    }
    $curl_options[CURLOPT_COOKIE] .= implode('; ', $cookies) . ';';
  }
  curl_setopt_array($this->curlHandle, $this->additionalCurlOptions + $curl_options);
  if (!$redirect) {

    // Reset headers, the session ID and the redirect counter.
    $this->sessionId = NULL;
    $this->headers = array();
    $this->redirectCount = 0;
  }
  $content = curl_exec($this->curlHandle);
  $status = curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE);

  // cURL incorrectly handles URLs with fragments, so instead of
  // letting cURL handle redirects we take of them ourselves to
  // to prevent fragments being sent to the web server as part
  // of the request.
  // TODO: Remove this for Drupal 8, since fixed in curl 7.20.0.
  if (in_array($status, array(
    300,
    301,
    302,
    303,
    305,
    307,
  )) && $this->redirectCount < $this->maximumRedirects) {
    if ($this
      ->drupalGetHeader('location')) {
      $this->redirectCount++;
      $curl_options = array();
      $curl_options[CURLOPT_URL] = $this
        ->drupalGetHeader('location');
      $curl_options[CURLOPT_HTTPGET] = TRUE;
      return $this
        ->curlExec($curl_options, TRUE);
    }
  }
  $this
    ->setRawContent($content);
  $this->url = isset($original_url) ? $original_url : curl_getinfo($this->curlHandle, CURLINFO_EFFECTIVE_URL);
  $message_vars = array(
    '@method' => !empty($curl_options[CURLOPT_NOBODY]) ? 'HEAD' : (empty($curl_options[CURLOPT_POSTFIELDS]) ? 'GET' : 'POST'),
    '@url' => isset($original_url) ? $original_url : $url,
    '@status' => $status,
    '@length' => format_size(strlen($this
      ->getRawContent())),
  );
  $message = SafeMarkup::format('@method @url returned @status (@length).', $message_vars);
  $this
    ->assertTrue($this
    ->getRawContent() !== FALSE, $message, 'Browser');
  return $this
    ->getRawContent();
}