Advertisement
Guest User

Untitled

a guest
Apr 18th, 2013
1,036
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 3.82 KB | None | 0 0
  1. <?php
  2. function curl_exec_follow($ch, $max=5) {
  3.     $response = false;
  4.    
  5.     // Common cURL options that need to be turned on for this to work and return consistently
  6.     curl_setopt($ch, CURLOPT_HEADER,true);
  7.     curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
  8.        
  9.     if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) {
  10.         // Can just use FOLLOWLOCATION, still need to parse the headers/status/content though.
  11.         // to maintain a consistent return.
  12.         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  13.         curl_setopt($ch, CURLOPT_MAXREDIRS, $max);
  14.         $response = curl_exec($ch);
  15.        
  16.         if ($response !== false) {
  17.             $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  18.             $response = array(
  19.                 'headers' => substr($response, 0, $headerSize),
  20.                 'content' => substr($response, $headerSize),
  21.                 'status' => curl_getinfo($ch, CURLINFO_HTTP_CODE)
  22.             );
  23.         }
  24.     }
  25.     else {
  26.         // explicitly turn FOLLOWLOCATION off, just in case servers do weird things.
  27.         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
  28.         // use a local copy of the cURL handle.
  29.         $local = curl_copy_handle($ch);
  30.         $redirected = false;
  31.        
  32.         $target = curl_getinfo($local, CURLINFO_EFFECTIVE_URL);
  33.         $last = parse_url($target); // need to maintain a reference to the last redirect in case following redirects are relative paths.
  34.         if (empty($last['hostname'])) {
  35.             // relative path on the server, very trivial attempt to build a correct path so it may not work in all cases
  36.             $last = parse_url("http" . (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 's://' : '://') . $_SERVER['HTTP_HOST'] . $target);
  37.         }
  38.        
  39.         $redirectCodes = array(301,302,307); // no support for 305 proxy redirects...yet :)
  40.         $headers = array(); // maintain the headers throughout the redirection.
  41.        
  42.         do {
  43.             curl_setopt($local, CURLOPT_URL, $target);
  44.             if (!($response = curl_exec($local))) {
  45.                 break;
  46.             }
  47.            
  48.             $code = curl_getinfo($local, CURLINFO_HTTP_CODE);
  49.             $headerSize = curl_getinfo($local, CURLINFO_HEADER_SIZE);
  50.             $header = substr($response, 0, $headerSize);
  51.             $headers[] = rtrim($header);
  52.             $redirected = in_array($code, $redirectCodes);
  53.            
  54.             if ($redirected) {
  55.                 if (preg_match('/^(?:Location|URI):\\s*([^\\r\\n]+)/m', $header, $matches) !== 1) {
  56.                     trigger_error("Requested resource is redirecting incorrectly.", E_USER_WARNING);
  57.                     $redirected = false; // set the loop-breaking condition.
  58.                     $response = false; // invalidate the response
  59.                 }
  60.                
  61.                 $target = parse_url(trim($matches[1]));
  62.                 if (empty($target['scheme'])) { // relative redirect, use the last url
  63.                     $target = $last['scheme'] . '://' . $last['host'] . $target['path'];
  64.                     $last = parse_url($target);
  65.                 }
  66.                 elseif ($target['scheme'] === 'file') {
  67.                     // Redirecting into the file:// protocol, can be unsafe
  68.                     trigger_error("Requested resource is attempting to redirect to files on the local system.", E_USER_WARNING);
  69.                     $redirected = false; // set the loop-breaking condition.
  70.                     $response = false; // invalidate the response
  71.                 }
  72.                 else {
  73.                     $target = trim($matches[1]);
  74.                     $last = parse_url($target);
  75.                 }
  76.                
  77.                 if ($code === 302) {
  78.                     // Many browsers implemented the 302-redirect in this way. i.e subsequent redirects
  79.                     // used the GET method, even when the original method used POST.
  80.                     // See http://en.wikipedia.org/wiki/HTTP_302 for more information.
  81.                     curl_setopt($local, CURLOPT_HTTPGET, true);
  82.                 }  
  83.             }
  84.         } while($redirected && --$max >= 0);
  85.  
  86.         if ($response !== false) {
  87.             $response = array(
  88.                 'headers' => implode("\r\n\r\n", $headers), // standard is an CRLF seperator between headers as far as I know.
  89.                 'content' => substr($response, curl_getinfo($local, CURLINFO_HEADER_SIZE)),
  90.                 'status' => curl_getinfo($local, CURLINFO_HTTP_CODE)
  91.             );
  92.         }
  93.        
  94.         curl_close($local);
  95.     }
  96.    
  97.     return $response;
  98. }
  99. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement