Search code examples
restdelphicurlindy10delphi-10.1-berlin

Using/Parsing curl in Delphi XE10.1


I have this curl sequence, that works in MS Windows and I am trying to use the equivalence with Indy in Delphi XE 10.1 Berlin.

The curl code is this:

curl -k "https://fakeweb.com/options" --data-binary "{\"name\":\"Name of the Client\",\"email\":\"fake@gmail.com\"}"

I have tried the following code, but it does not work

procedure TForm2.Button4Click(Sender: TObject);
const
  COMI = Char(34);
var
  data: string;
  DataToSend : TStringStream;
  IdHTTP: TIdHTTP;
  Answer: string;
begin
  try
    data := '{\' + COMI  + 'name\' + COMI  + ':\' + COMI  + 'Name of the Client\' + COMI  +
          ',\' + COMI  + 'email\' + COMI  + ':\' + COMI   + 'fake@gmail.com\' + COMI  + '}' ;

    DataToSend := TStringStream.Create(data);

    IdHTTP := TIdHTTP.Create(Application);

    IdHTTP.Request.Accept := 'application/json, text/plain; q=0.9, text/html;q=0.8,';
    IdHTTP.Request.ContentType := 'application/json, text/plain; q=0.9, text/html;q=0.8,';

    Answer := IdHTTP.Post('https://fakeweb.com/options', DataToSend);    //its not the real URL

    ShowMessage(Answer);
  except on E: Exception do
    ShowMessage('Error: '+E.ToString);
  end;
end;

Always I get the same messagge : HTTP/1.1 500 Internal Srever Error. Can someone helps me?

Thank you.


Solution

  • There are three problems with your code:

    1. You are corrupting your JSON string, which may cause the HTTP error. The slash character is not used as an escape sequence in Delphi string literals (it is not even an escape sequence in curl itself, either. It is the command-line processor that requires it), so you are posting actual slash characters that do not belong in your JSON data at all. Also, while not technically wrong, your COMI constant is unnecessary, since Delphi strings use ' for quoting, so you can safely use " as-is in the string data.

    2. You are setting the TIdHTTP.Request.ContentType property to an invalid value, which may also cause the HTTP error.

    3. You are leaking the objects you are creating, if this code is run on Windows or OSX (well, the TIdHTTP object is not "leaked" exactly, but it is not destroyed until the app exits). There is no leaking if the code is run on iOS or Android.

    Try this instead:

    procedure TForm2.Button4Click(Sender: TObject);
    var
      data: string;
      DataToSend : TStringStream;
      IdHTTP: TIdHTTP;
      Answer: string;
    begin
      try
        data := '{"name":"Name of the Client","email":"fake@gmail.com"}';
        DataToSend := TStringStream.Create(data, TEncoding.UTF8);
        try
          IdHTTP := TIdHTTP.Create(nil);
          try
            IdHTTP.Request.Accept := 'application/json, text/plain;q=0.9, text/html;q=0.8';
            IdHTTP.Request.ContentType := 'application/json';
            Answer := IdHTTP.Post('https://fakeweb.com/options', DataToSend);    
          finally
            IdHTTP.Free;
          end;
        finally
          DataToSend.Free;
        end;
        ShowMessage(Answer);
      except
        on E: Exception do
          ShowMessage('Error: '+E.ToString);
      end;
    end;