Since just setting CURLOPT_FOLLOWLOCATION on POSTs doesn't work because cURL follows with a GET, I thought I'd share the PHP code that I built yesterday to manually follow 30x's on POSTS (and it does follows on GETs as well).
function APICall($api_url, $require_credentials = false, $http_post = false, $username = '', $password = '', $uri = '') { // $api_url must contain the part of the URL that comes after http://twitter.com/ and before the ? // $uri contains the part of the URL that comes after the ? and must be URL encoded // eg., page=1&count=100 $remote_server = 'http://twitter.com/'; $call_url = $remote_server . $api_url; if (!$http_post && !empty($uri)){ $call_url = $call_url . '?' . $uri; } $redirect_count = 0; while (1) { $cookie = ''; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $call_url); if ($require_credentials) { curl_setopt($ch, CURLOPT_USERPWD, $username.':'.$password); } if ($http_post) { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $uri); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE); } else { curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); } curl_setopt($ch, CURLOPT_USERAGENT, "set your unique user agent here"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_TIMEOUT, 20); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); curl_setopt($ch, CURLOPT_HEADER, TRUE); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); $data = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); $headers = substr($data,0,curl_getinfo($ch, CURLINFO_HEADER_SIZE)); $data = substr($data,curl_getinfo($ch, CURLINFO_HEADER_SIZE)); if ($status > 300 && $status < 310) { preg_match("#Location: ?(.*)#i", $headers, $match); $redirect_url = trim($match[1]); if (!empty($redirect_url)){ $redirect_count++; if ($redirect_count > 20){ // Set $status to something unique here so that you know there was a loop curl_close($ch); break; } $call_url = $redirect_url; $parsed_url = parse_url($call_url); if (!isset($parsed_url['host'])){ $call_url = $remote_server.$call_url; } curl_close($ch); continue; } } curl_close($ch); // Check $status for other response codes here break; } return $data; }