Commit a3134cc2 authored by Dries's avatar Dries

- Patch #671520 by mr.baileys, cha0s, boombatower, andypost: CURL and fragment...

- Patch #671520 by mr.baileys, cha0s, boombatower, andypost: CURL and fragment URLs break testing due to a bug in some CURL versions.
parent 7f96b058
......@@ -697,6 +697,11 @@ class DrupalWebTestCase extends DrupalTestCase {
*/
protected $generatedTestFiles = FALSE;
/**
* The number of redirects followed during the handling of a request.
*/
protected $redirect_count;
/**
* Constructor for DrupalWebTestCase.
*/
......@@ -1297,8 +1302,7 @@ protected function curlInitialize() {
$curl_options = $this->additionalCurlOptions + array(
CURLOPT_COOKIEJAR => $this->cookieFile,
CURLOPT_URL => $base_url,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_MAXREDIRS => 5,
CURLOPT_FOLLOWLOCATION => FALSE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_SSL_VERIFYPEER => FALSE, // Required to make the tests run on https.
CURLOPT_SSL_VERIFYHOST => FALSE, // Required to make the tests run on https.
......@@ -1325,12 +1329,27 @@ protected function curlInitialize() {
*
* @param $curl_options
* Custom cURL options.
* @param $redirect
* FALSE if this is an initial request, TRUE if this request is the result of
* a redirect.
* @return
* Content returned from the exec.
*/
protected function curlExec($curl_options) {
protected function curlExec($curl_options, $redirect = FALSE) {
$this->curlInitialize();
// 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 (!empty($curl_options[CURLOPT_URL]) && 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
......@@ -1341,15 +1360,36 @@ protected function curlExec($curl_options) {
}
curl_setopt_array($this->curlHandle, $this->additionalCurlOptions + $curl_options);
// Reset headers and the session ID.
$this->session_id = NULL;
$this->headers = array();
if (!$redirect) {
// Reset headers, the session ID and the redirect counter.
$this->session_id = NULL;
$this->headers = array();
$this->redirect_count = 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->redirect_count < variable_get('simpletest_maximum_redirects', 5)) {
if ($this->drupalGetHeader('location')) {
$this->redirect_count++;
$curl_options = array();
$curl_options[CURLOPT_URL] = $this->drupalGetHeader('location');
$curl_options[CURLOPT_HTTPGET] = TRUE;
return $this->curlExec($curl_options, TRUE);
}
}
$this->drupalSetContent(curl_exec($this->curlHandle), curl_getinfo($this->curlHandle, CURLINFO_EFFECTIVE_URL));
$this->drupalSetContent($content, 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' => $url,
'@status' => curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE),
'@url' => isset($original_url) ? $original_url : $url,
'@status' => $status,
'!length' => format_size(strlen($this->content))
);
$message = t('!method @url returned @status (!length).', $message_vars);
......@@ -1956,10 +1996,6 @@ protected function clickLink($label, $index = 0) {
$this->assertTrue(isset($urls[$index]), t('Clicked link %label (@url_target) from @url_before', array('%label' => $label, '@url_target' => $url_target, '@url_before' => $url_before)), t('Browser'));
if (isset($url_target)) {
// CURL breaks in drupalGet() if the URL contains a fragment.
// @todo remove when http://drupal.org/node/671520 is fixed.
// Strips off any fragment from the path.
$url_target = array_shift(explode('#', $url_target));
return $this->drupalGet($url_target);
}
return FALSE;
......
......@@ -54,7 +54,8 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
$this->drupalGet($base_url . '/install.php', array('external' => TRUE));
$this->assertResponse(403, 'Cannot access install.php with a "simpletest" user-agent header.');
$this->drupalLogin($this->drupalCreateUser());
$user = $this->drupalCreateUser();
$this->drupalLogin($user);
$headers = $this->drupalGetHeaders(TRUE);
$this->assertEqual(count($headers), 2, t('There was one intermediate request.'));
$this->assertTrue(strpos($headers[0][':status'], '302') !== FALSE, t('Intermediate response code was 302.'));
......@@ -62,6 +63,17 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
$this->assertEqual($this->getUrl(), $headers[0]['location'], t('HTTP redirect was followed'));
$this->assertFalse($this->drupalGetHeader('Location'), t('Headers from intermediate request were reset.'));
$this->assertResponse(200, t('Response code from intermediate request was reset.'));
// Test the maximum redirection option.
$this->drupalLogout();
$edit = array(
'name' => $user->name,
'pass' => $user->pass_raw
);
variable_set('simpletest_maximum_redirects', 1);
$this->drupalPost('user?destination=user/logout', $edit, t('Log in'));
$headers = $this->drupalGetHeaders(TRUE);
$this->assertEqual(count($headers), 2, t('Simpletest stopped following redirects after the first one.'));
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment