I hit the same issue. I made a bit of code that'll manually follow redirects. Please make sure you read and understand the code, and are aware of any security issues before you use it in production!
function remote_file($f){
$i = 0;
do {
if($i++ > 10) die();
//Pull the headers and check for redirects
$cr = curl_init($f);
curl_setopt($cr, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($cr, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($cr, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($cr, CURLOPT_HEADER, TRUE);
$curl_ret = curl_exec($cr);
//echo $curl_ret;
if(curl_getinfo($cr,CURLINFO_HTTP_CODE)!=200) {
$matches = preg_match_all('~location: ?(.*)~i',$curl_ret,$output);
if($matches) {
$f = $output[1][0];
}
} else $matches = 0;
} while ($matches);
$cr = curl_init($f);
curl_setopt($cr, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($cr, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($cr, CURLOPT_BINARYTRANSFER, TRUE);
//curl_setopt($cr, CURLOPT_FOLLOWLOCATION, TRUE); //Doesn't work with open_basedir retriction in effect
$curl_ret = curl_exec($cr);
curl_close($cr);
return $curl_ret;
}
Edit: In the HttpClient.php, you should have a function like
private function _init($url,$token)
{
$this->_url = $url;
$this->_token = $token;
//init connection
$this->_curlConn = curl_init($this->_url);
curl_setopt($this->_curlConn, CURLOPT_HEADER, false);
curl_setopt($this->_curlConn, CURLOPT_NOBODY, false);
curl_setopt($this->_curlConn, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->_curlConn, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($this->_curlConn, CURLOPT_USERPWD, $this->_token);
curl_setopt($this->_curlConn, CURLOPT_TIMEOUT, 4);
curl_setopt($this->_curlConn, CURLOPT_SSL_VERIFYPEER, FALSE); // Validate SSL certificate
curl_setopt($this->_curlConn, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($this->_curlConn, CURLOPT_USERAGENT, "FreshBooks API AJAX tester 1.0");
return $this;
}
You'll need to rewrite this function, something like
private function _init($url,$token)
{
$this->_url = $url;
$this->_token = $token;
//init connection
$i = 0;
do {
if($i++ > 10) die();
//Pull the headers and check for redirects
$this->_curlConn = curl_init($this->_url);
curl_setopt($this->_curlConn, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($this->_curlConn, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($this->_curlConn, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($this->_curlConn, CURLOPT_HEADER, TRUE);
curl_setopt($this->_curlConn, CURLOPT_USERPWD, $this->_token);
curl_setopt($this->_curlConn, CURLOPT_USERAGENT, "FreshBooks API AJAX tester 1.0");
$curl_ret = curl_exec($cr);
//echo $curl_ret;
if(curl_getinfo($cr,CURLINFO_HTTP_CODE)!=200) {
$matches = preg_match_all('~location: ?(.*)~i',$curl_ret,$output);
if($matches) {
$this->_url = $output[1][0];
}
} else $matches = 0;
} while ($matches);
$this->_curlConn = curl_init($this->_url);
curl_setopt($this->_curlConn, CURLOPT_HEADER, false);
curl_setopt($this->_curlConn, CURLOPT_NOBODY, false);
curl_setopt($this->_curlConn, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($this->_curlConn, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($this->_curlConn, CURLOPT_USERPWD, $this->_token);
curl_setopt($this->_curlConn, CURLOPT_TIMEOUT, 4);
curl_setopt($this->_curlConn, CURLOPT_SSL_VERIFYPEER, FALSE); // Validate SSL certificate
curl_setopt($this->_curlConn, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($this->_curlConn, CURLOPT_USERAGENT, "FreshBooks API AJAX tester 1.0");
return $this;
}
This will effectively keep sending the request to their API until it returns something that isn't a redirect. When it's happy it'll just pass that post-redirect URL onto the standard code, which will pick it up and continue on its way.
Oh, the other thing I'd try before going to this effort... What if you just comment out the offending line in HttpClient.php? Does it actually need to follow any redirects?