Search code examples
restdelphipostdelphi-10-seattle

Delphi Seattle - Sending Post Request with custom body Responds bad Request 400


I would like to send a Post Request to a Rest Server of external Provider. I Have tried with Curl and everything works perfect. Here is the CURL Code:

    curl -X POST -H 'PRODUCT-KEY: SUperL0ngAndSpecialSecretCode' -H 'Content-Type: application/json' -H 'Authorization: Basic CrytedWorksalsowellwithotherget' -i 'http://myserver:8080/rest.svc/v1.0/query' --data '{
"query":"SELECT Name from Address where name like '\''%me%'\''"
}'

In Curl Everything works fine. I have tried for a bunch of hours to get this Code working in Delphi. At this time my code looks like this:

function GetSomeInformation: string;
var
  lrestrequest: TRESTRequest;
  lRestClient: TRESTClient;
  lRestResponce: TRESTResponse;
begin
  result := '';
  lRestClient := TRESTClient.Create('http://myserver:8080/rest.svc/v1.0/query');
  try
    lrestrequest := TRESTRequest.Create(nil);
    try
      lRestResponce := TRESTResponse.Create(nil);
      try
        lrestrequest.Client := lRestClient;
        lrestrequest.Response := lRestResponce;
        lrestrequest.Method := rmPost;
        lrestrequest.Params.AddItem('PRODUCT-KEY',
          'SUperL0ngAndSpecialSecretCode',
          TRESTRequestParameterKind.pkHTTPHEADER);
        lrestrequest.Params.AddItem('Content-Type', 'application/json',
          TRESTRequestParameterKind.pkHTTPHEADER);
        lrestrequest.Params.AddItem('query',
          ansitoutf8('SELECT Name from Address where Name like ' +
          quotedstr('%me%')), TRESTRequestParameterKind.pkREQUESTBODY);
        lrestrequest.Execute;
        if not lRestResponce.Status.Success then
          showmessage(lRestResponce.StatusText + ' ' +
            inttostr(lRestResponce.StatusCode))
        else
          result := lRestResponce.Content;
      finally
        lRestResponce.Free;
      end;
    finally
      lrestrequest.Free
    end;
  finally
    lRestClient.Free;
  end;
end;

I have no idea what to do next to get the Work done? Any ideas or ways I can Debug the problem better.

--Update

Okay I Used Wireshark to check if there are any differences between the Post commands, it look like Delphi ignores or broke my Header. In the Wireshark snippet there is a Value Content-Type. It should be

Content-Type: application/json

But with Delphi I get

Content-Type: application%2Fjson, application/x-www-form-urlencoded

And I also miss the Procduct-Key Value. Any Suggestions?


Solution

  • after some Research and some Wireshark I got my Work done at least here ist the way I throw the parameters into my Request.

    function GetSomeInformation: string;
    var
      lrestrequest: TRESTRequest;
      lRestClient: TRESTClient;
      lRestResponce: TRESTResponse;
    begin
      result := '';
      lRestClient := TRESTClient.Create('http://myserver:8080/rest.svc/v1.0/query');
      try
        lrestrequest := TRESTRequest.Create(nil);
        try
          lRestResponce := TRESTResponse.Create(nil);
          try
            lrestrequest.Client := lRestClient;
            lrestrequest.Response := lRestResponce;
            RESTRequest1.Params.Clear;
            RESTRequest1.Method:=rmpost;
            RESTResponse1.RootElement := '';
            lparam := RESTRequest1.Params.AddItem;
            lparam.name := 'PRODUCT-KEY';
            lparam.Value := 'SpecialKeyButWithSomeTrickyCharsLike==';
            lparam.ContentType := ctNone;
            lparam.Kind := pkHTTPHEADER;
            //This one is Important otherwise the '==' will get url encoded
            lparam.Options := [poDoNotEncode];
    
            lparam := RESTRequest1.Params.AddItem;
            lparam.name := 'data';
            lparam.Value := '{"query":"' + SelectString + '"}';
            lparam.ContentType := ctAPPLICATION_JSON;
            lparam.Kind := pkGETorPOST;
            lrestrequest.Execute;
            if not lRestResponce.Status.Success then
              showmessage(lRestResponce.StatusText + ' ' +
                inttostr(lRestResponce.StatusCode))
            else
              result := lRestResponce.Content;
          finally
            lRestResponce.Free;
          end;
        finally
          lrestrequest.Free
        end;
      finally
        lRestClient.Free;
      end;
    end;
    

    Thanks for Supporting!

    PJM