1
votes

I'm trying to use the last.fm api using Indy's TIdHTTP component. When I send a request, I keep receiving Connection closed gracefully without receiving any data. However, when I copy the same URL from the component (directly to the clipboard) into a web browser such as Chrome or Firefox, it works perfectly fine.

I'm trying to implement the album.search call, and am trying to GET the data from this sample URL:

http://ws.audioscrobbler.com/2.0/?format=json&api_key=MY_API_KEY&method=album.search&album=believe&limit=30&page=1

This request is documented here

I have a helper function to concatenate the common URL structure:

function TLastFm.ApiUrl(const Method: String): String;
begin
  Result:= Format('http://ws.audioscrobbler.com/%s/?format=json&api_key=%s&method=%s',
    [FVersion, FKey, Method]); //FVersion = '2.0', FKey = my API key
end;

And then I make the actual call like this:

var
  S, R: String;
begin
  S:= ApiUrl('album.search')+'&album='+Album; //Album = 'believe'
  S:= S + '&limit=30&page=1';
  Clipboard.AsText:= S; //Used to paste into browser to test
  FHTTP.Request.UserAgent:= 'Mozilla/3.0 (compatible; JD Test)';
  R:= FHTTP.Get(S); //<-- Connection closed gracefully
  // ...
end;

How do I make this call successfully using Indy's TIdHTTP?

1
What's different between the HTTP request your program sends and the one the browser sends? I'd use a packet sniffer like Wireshark to check. I think there might be more specialized programs for that nowadays.Rob Kennedy
A good example of high-level ispection for modelling Firefox behaviour is Firebug extension.Free Consulting
Fiddler is a good one to use, Wireshark is good as well though.Shambhala

1 Answers

2
votes

I just created an account and got my API Key. I set up these constants:

const
  FVersion = '2.0';
  FKey = 'MYAPIKEY';
  Album = 'believe';
function ApiUrl(const Method: String): String;

I have the IdHTTP component set on the form where you are manually creating it though.

procedure TForm1.btnGetRequestClick(Sender: TObject);
var
  S, R: String;
begin
  S := ApiUrl('album.search')+'&album='+Album; //Album = 'believe'
  S := S + '&limit=30&page=1';
  IdHTTP1.Request.UserAgent := 'Mozilla/3.0 (compatible; JD Test)';
  mem.Lines.Text := IdHTTP1.Get(S);
end;

I got a memo back full of json results.

EDIT:

I have done a few more subsequent tests and it seems that if there is a space in the search keyword you will get the Connection Closed error.

If you try:

Album = 'believe '; // Connection closed gracefully

If you try:

Album = 'believe'; // I get a json response back