Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.196
diff -u -r1.196 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	9 Feb 2010 12:28:39 -0000	1.196
+++ modules/simpletest/drupal_web_test_case.php	18 Feb 2010 08:52:18 -0000
@@ -1304,8 +1304,7 @@
       $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.
@@ -1337,7 +1336,18 @@
    */
   protected function curlExec($curl_options) {
     $this->curlInitialize();
+
+    // cURL incorrectly handles URLs with fragments, including the
+    // fragment in the request, causing some web servers to reject
+    // the request citing "400 - Bad Request". To prevent this, we
+    // strip the fragment from the request.
+    if (!empty($curl_options[CURLOPT_URL]) && strpos($curl_options[CURLOPT_URL], '#')) {
+      $original_url = $curl_options[CURLOPT_URL];
+      $curl_options[CURLOPT_URL] = array_shift(explode('#', $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
@@ -1352,11 +1362,32 @@
     $this->session_id = NULL;
     $this->headers = array();
 
-    $this->drupalSetContent(curl_exec($this->curlHandle), curl_getinfo($this->curlHandle, CURLINFO_EFFECTIVE_URL));
+    $content = curl_exec($this->curlHandle);
+    $status = curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE);
+
+    // Because cURL incorrectly handles URLs with fragments, we need to
+    // take care of redirecting ourselves in order to prevent fragments
+    // being sent to the web server as part of the request.
+    //
+    // @todo: need to implement max_redirs.
+    if (in_array($status, array(300, 301, 302, 303, 305, 307))) { 
+      foreach ($this->headers as $header) {
+        if (preg_match('/^Location: (.*)$/', $header, $matches)) {
+          $curl_options = array();
+          $curl_options[CURLOPT_URL] = trim($matches[1]);
+          $curl_options[CURLOPT_HTTPGET] = TRUE;
+          unset($curl_options[CURLOPT_POST]);
+          unset($curl_options[CURLOPT_POSTFIELDS]);
+          return $this->curlExec($curl_options);
+        }
+      }
+    }
+
+    $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);
@@ -1963,10 +1994,6 @@
     $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;
