Peacelyk
Peacelyk

Reputation: 1146

How to make an HTTPS POST request in Delphi?

What is the easiest way to do an HTTPS POST request in Delphi? I'm not having problems with making HTTP POST requests, but how can I do it using SSL? I've googled around and haven't found anything that explains this well enough.

Here's the code I tried:

procedure TForm1.FormCreate(Sender: TObject);
var
  responseXML:TMemoryStream;
  responseFromServer:string;
begin
  responseXML := TMemoryStream.Create;
  IdSSLIOHandlerSocketOpenSSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(self);
  with idSSLIOHandlerSocketOpenSSL1 do
    begin
      SSLOptions.Method := sslvSSLv2;
      SSLOptions.Mode := sslmUnassigned;
      SSLOptions.VerifyMode := [];
      SSLOptions.VerifyDepth := 0;
      host := '';
    end;

  IdHTTP1 := TIdHTTP.Create(Self);
  with IdHTTP1 do
    begin
      IOHandler := IdSSLIOHandlerSocketOpenSSL1;
      AllowCookies := True;
      ProxyParams.BasicAuthentication := False;
      ProxyParams.ProxyPort := 0;
      Request.ContentLength := -1;
      Request.ContentRangeEnd := 0;
      Request.ContentRangeStart := 0;
      Request.Accept := 'text/html, */*';
      Request.BasicAuthentication := False;
      Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
      HTTPOptions := [hoForceEncodeParams];
    end;
  responsefromserver := IdHTTP1.Post('https://.../','name1=value1&name2=value2&....');
end;

When I try to run it I get the following error:

Project myProject.exe raised exception class EFOpenError with message 'Cannot open file "C:\...\Projects\Debug\Win32\name1=value1name2=value2 The system cannot find the file specified'.

I don't understand that. I sent parameters, though the errors sounds like I would have sent a file.

Also I have included libeay32.dll and ssleay32.dll within my myProject.exe folder.

Upvotes: 17

Views: 52802

Answers (4)

Max Kleiner
Max Kleiner

Reputation: 1612

So the short answer is simple, use a COM-Object with flexible late binding, example of a translate service with language detection, implements in maXbox script:

function getPostTranslateLibre(feedstream: string): string;
var
  Url,API_KEY, source: string;
  jo, locate: TJSONObject;
  httpReq,hr: Olevariant;
  strm: TStringStream;
begin
  httpReq:= CreateOleObject('WinHttp.WinHttpRequest.5.1');
  // Open the HTTPs connection.  
  try              
    hr:= httpReq.Open('POST','https://libretranslate.pussthecat.org/detect', false);
    httpReq.setRequestheader('user-agent',
          'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0');
    httpReq.setRequestheader('content-type','application/x-www-form-urlencoded');  
    //httpReq.setRequestheader('X-RapidAPI-Host','nlp-translation.p.rapidapi.com');   
    //httpReq.setRequestheader('X-RapidAPI-Key','...333'); 
              
    if hr= S_OK then HttpReq.Send('q='+HTTPEncode(feedstream));
     /// Send HTTP Post Request & get Responses. 
    
    If HttpReq.Status = 200 Then
       result:= HttpReq.responseText
    Else result:= 'Failed at getting response:'+itoa(HttpReq.Status)+HttpReq.responseText;
    //writeln('debug response '+HttpReq.GetAllResponseHeaders);     
  finally
    httpreq:= unassigned;  
  end;                  
end; 

As early binding compiled we use LHttpClient: TALWininetHttpClient; https://github.com/infussolucoes/usercontrol-sd/blob/master/Source/Terceiros/Alcinoe/ALHttpClient.pas

Upvotes: 2

k.bon
k.bon

Reputation: 386

http://chee-yang.blogspot.com/2008/03/using-indy-https-client-to-consume.html

var S: TStringList;
   M: TStream;
begin
 S := TStringList.Create;
 M := TMemoryStream.Create;
 try
   S.Values['Email'] := 'your google account';
   S.Values['Passwd'] := 'your password';
   S.Values['source'] := 'estream-sqloffice-1.1.1.1';
   S.Values['service'] := 'cl';

   IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL1;
   IdHTTP1.Request.ContentType := 'application/x-www-form-urlencoded';
   IdHTTP1.Post('https://www.google.com/accounts/ClientLogin', S, M);
   Memo1.Lines.Add(Format('Response Code: %d', [IdHTTP1.ResponseCode]));
   Memo1.Lines.Add(Format('Response Text: %s', [IdHTTP1.ResponseText]));

   M.Position := 0;
   S.LoadFromStream(M);
   Memo1.Lines.AddStrings(S);
 finally
   S.Free;
   M.Free;
 end;

end;

Upvotes: 2

Darian Miller
Darian Miller

Reputation: 8088

Another alternative to Indy is Synapse.

This class library offers full control of the post, but also offers a simple one liner post method as well:

function HttpPostURL(const URL, URLData: string; const Data: TStream): Boolean;

Upvotes: 0

Mohammed Nasman
Mohammed Nasman

Reputation: 11040

You didn't specified your Delphi version or indy version, but I had some problems before with the bundled Indy with Delphi 2009 and HTTPS, and when I got the latest source from indy svn, the problem solved.

Upvotes: 3

Related Questions