Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Apr 18th, 2013  |  syntax: PHP  |  size: 3.82 KB  |  views: 319  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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. ?>
clone this paste RAW Paste Data