PHP cURL error: "Empty reply from server"
Asked Answered
B

5

9

I have a class function to interface with the RESTful API for Last.FM - its purpose is to grab the most recent tracks for my user. Here it is:

private static $base_url = 'http://ws.audioscrobbler.com/2.0/';

public static function getTopTracks($options = array())
{
  $options = array_merge(array(
    'user' => 'bachya',
    'period' => NULL,
    'api_key' => 'xxxxx...', // obfuscated, obviously
  ), $options);

  $options['method'] = 'user.getTopTracks';

  // Initialize cURL request and set parameters
  $ch = curl_init();
  curl_setopt_array($ch, array(
    CURLOPT_URL            => self::$base_url,
    CURLOPT_POST           => TRUE,
    CURLOPT_POSTFIELDS     => $options,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
  ));

  $results = curl_exec($ch);
  return $results;
}

This returns "Empty reply from server". I know that some have suggested that this error comes from some fault in network infrastructure; I do not believe this to be true in my case. If I run a cURL request through the command line, I get my data; the Last.FM service is up and accessible.

Before I go to those folks and see if anything has changed, I wanted to check with you fine folks and see if there's some issue in my code that would be causing this.

Thanks!

ANSWER: @Jan Kuboschek helped me stumble onto what is (maybe) going on here. By giving CURLOPT_POSTFIELDS an associative array, a particular content-type is specified that may not work with certain RESTful services. A smarter solution is to manually create a URL-encoded version of that data and pass that as the CURLOPT_POSTFIELDS.

For more info, check out: http://www.brandonchecketts.com/archives/array-versus-string-in-curlopt_postfields

Bohannon answered 10/6, 2010 at 20:46 Comment(0)
A
12

A common issue are spaces in the URL - beginning, in the middle, or trailing. Did you check that out?

Edit - per comments below, spacing is not the issue.

I ran your code and had the same problem - no output whatsoever. I tried the URL and with a GET request, the server talks to me. I would do the following:

  1. Use the following as $base_url: $base_url = 'http://ws.audioscrobbler.com/2.0/?user=bachya&period=&api_key=xxx&method=user.getTopTracks';

  2. Remove the post fields from your request.

Edit I moved your code out of the class since I didn't have the rest and modified it. The following code runs perfect for me. If these changes don't work for you, I suggest that your error is in a different function.

<?php


function getTopTracks()
{
  $base_url = 'http://ws.audioscrobbler.com/2.0/?user=bachya&period=&api_key=8066d2ebfbf1e1a8d1c32c84cf65c91c&method=user.getTopTracks';
  $options = array_merge(array(
    'user' => 'bachya',
    'period' => NULL,
    'api_key' => 'xxxxx...', // obfuscated, obviously
  ));

  $options['method'] = 'user.getTopTracks';

  // Initialize cURL request and set parameters
  $ch = curl_init($base_url);
  curl_setopt_array($ch, array(
    CURLOPT_URL            => $base_url,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
  ));

  $results = curl_exec($ch);
  return $results;
}

echo getTopTracks();

?>
Aboral answered 10/6, 2010 at 20:55 Comment(7)
Unfortunately, that's not the problem - I updated my original post to show the URL ($base_url) that I use. Thanks, though. :-\Bohannon
Updated my answer. Let me know if this still doesn't work. I couldn't test further since the server told me that I needed a valid API key.Aboral
Okay, tried that - it seems to hang ("work") a little longer. I var dump the curl_exec results and get false in return... I'd rather not put out my API key, but they're easy enough to get.Bohannon
Ok, this is bugging me now. How do I get an API key?Aboral
Check here: last.fm/api/account - thanks for being as bugged as I am! :)Bohannon
Okay - you hit on something that I've updated my original post with. Thank you for your help! :)Bohannon
I was having the same issue.. infact space creates problems with curl request.. i had keyowrd=iphone 5 in my url and i was always getting empty response.. When i replaced keyowrd=iphone+5, it worked fine :)Olinger
B
8

The server received your request, but sent an empty response. Check the result of curl_getinfo($ch, CURLINFO_HTTP_CODE) to find out if the server responded with an HTTP error code.

Update: Ok so the server responds with the 100 Continue HTTP status code. In that case, this should solve your problem:

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));

I found this here: PHP and cURL: Disabling 100-continue header. Hope it works!

Bosun answered 10/6, 2010 at 21:15 Comment(2)
Var-dumping this returns 100 - helpful, I hope?Bohannon
One more update: Jan's solution above uses GET instead of POST, and as Michał pointed out that's actually better for read API calls. The 100 Continue stuff doesn't apply to GET, so it neatly avoids the real problem. If you want to access write services as well, then you should use POST for those calls, and try my answer.Bosun
C
1

And here's the code for get Album Info from Laft.FM even if return error:

The Function:

function getAlbum($xml,$artist,$album)
{
  $base_url = $xml;
  $options = array_merge(array(
    'user' => 'YOUR_USERNAME',
    'artist'=>$artist,
    'album'=>$album,
    'period' => NULL,
    'api_key' => 'xYxOxUxRxxAxPxIxxKxExYxx', 
  ));

  $options['method'] = 'album.getinfo';

  // Initialize cURL request and set parameters
  $ch = curl_init($base_url);
  curl_setopt_array($ch, array(
    CURLOPT_URL            => 'http://ws.audioscrobbler.com/2.0/',
    CURLOPT_POST           => TRUE,
    CURLOPT_POSTFIELDS     => $options,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_HTTPHEADER        => array( 'Expect:' ) ,
    CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
  ));

  $results = curl_exec($ch);
  unset ($options);
  return $results;
}

Usage:

// Get the XML
$xml_error = getAlbum($xml,$artist,$album);

// Show XML error
if (preg_match("/error/i", $xml_error)) {
    echo " <strong>ERRO:</strong> ".trim(strip_tags($xml_error));
}
Cabalistic answered 5/5, 2011 at 17:0 Comment(0)
T
1

I came acorss the same issue. My Http_code returned 200 but my response was empty. There could be many reasons for this as i experienced.

--Your hedaers might be incorrect

CURLOPT_HTTPHEADER => array('Content-Type:application/json', 'Expect:')

--You might need to send data as post fields in culr and not attached to the URl like url?p1=a1&p2=a2

$data = array (p1=>a1, p2=>a2)
CURLOPT_POSTFIELDS => $data

So your options array would be similar to the below

array(
    CURLOPT_URL => $url,
    CURLOPT_FAILONERROR => TRUE, // FALSE if in debug mode
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT => 4,
    CURLOPT_HTTPHEADER => array('Content-Type:application/json', 'Expect:'),
    CURLOPT_POST => TRUE,
    CURLOPT_POSTFIELDS => $data,
);
Thylacine answered 21/8, 2013 at 5:14 Comment(0)
P
0

According to Last.FM API documentation you should use GET method instead of POST to pass parameters. When I've changed POST to GET I've received the answer about incorrect key.

Peer answered 10/6, 2010 at 21:35 Comment(2)
I don't see anything in that document that specifies the required use of a GET request in passing parameters. Could you show me where?Bohannon
"Generally speaking, you will send a method parameter expressed as 'package.method' along with method specific arguments to the root URL" "For example.: ws.audioscrobbler.com/2.0/…... If you are accessing a write service, you will need to submit your request as an HTTP POST request."Phosphorus

© 2022 - 2024 — McMap. All rights reserved.