delphi 2006 indy https post time out - delphi

I have to use Delphi 2006. I have to use Indy 10.1.5 - comes with Delphi 2006 or not, but I have to use these versions! I found an example how to use indy SSL https get but now I completely lost my head and close to to do another 'bad day' video!
Finally, the SSL library loaded without any problem.
But... Why I get always 'EidReadTimeout with message 'Read Timeout'
here is my code:
var
IdHTTP1: TIdHTTP;
ParamStringList: TStringList;
s1: String;
IdSSLIOHandlerSocket1: TIdSSLIOHandlerSocketOpenSSL;
begin
IdHTTP1 := TIdHTTP.Create(nil);
IdSSLIOHandlerSocket1 := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
IdSSLIOHandlerSocket1.ReadTimeout := 10000;
IdHTTP1.IOHandler := IdSSLIOHandlerSocket1;
IdHTTP1.ConnectTimeout := 10000;
IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv23; // Which one is the good for...
IdSSLIOHandlerSocket1.SSLOptions.Mode := sslmClient;
IdSSLIOHandlerSocket1.SSLOptions.VerifyMode := [];
IdSSLIOHandlerSocket1.SSLOptions.VerifyDepth := 0;
ParamStringList := TStringList.Create;
ParamStringList.Text := '';
s1 := IdHTTP1.Post('https://msp.f-secure.com/web-test/common/test.html', ParamStringList);
Memo1.Text := s1;
ParamStringList.Free;
IdSSLIOHandlerSocket1.Free;
IdHTTP1.Free;
end;
Any idea? What can I missed?
I changed the timeout between 3 and 100 seconds, but no changes when I tried to ran my code.
Thanks in advance!

Related

Delphi EIdOSSLUnderlyingCryptoError Exception - SSL3_GET_RECORD Wrong Version Number

I tried using TRESTClient to connect to an HTTPS web service using TLS 1.2. But NO LUCK with sending multipart/form-data.
So now I am trying with Indy. I got this "Wrong Version Number" error.
I think there is nothing wrong with the code since it worked with HTTP.
Probably my Delphi is missing something. What should I install and how?
procedure TForm10.Button2Click(Sender: TObject);
var
HTTP: TIdHTTP;
RequestBody: TStream;
ResponseBody: string;
myssl: TIdSSLIOHandlerSocketOpenSSL;
Input: TIdMultipartFormDataStream;
begin
ResponseBody := '';
try
try
HTTP := TIdHTTP.Create;
try
Input := TIdMultipartFormDataStream.Create;
try
Input.Clear;
Input.AddFormField('Email', 'xx#xx.com.tr');
Input.AddFormField('Password', 'xx');
myssl := TIdSSLIOHandlerSocketOpenSSL.Create(HTTP);
HTTP.IOHandler := myssl;
myssl.SSLOptions.Mode := sslmUnassigned;
myssl.SSLOptions.Method := sslvTLSv1_2;
myssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
HTTP.HTTPOptions := [hoForceEncodeParams];
HTTP.Request.CustomHeaders.FoldLines := False;
ResponseBody := HTTP.Post('https://xxx.com.tr/api/Mobile/MobileLoginControl', Input);
finally
Input.Free;
end;
finally
HTTP.Free;
end;
finally
end;
except
ResponseBody := '"-20"';
end;
end;
The code is fine, though you are enabling only TLS 1.2 on the SSLIOHandler. Maybe the website in question doesn't support TLS 1.2? Try enabling TLS 1.0 and 1.1 as well:
myssl.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
And don't set the SSLOptions.Method at all. Setting the SSLVersions updates the Method and vice versa. So set one or the other, not both.

TIdhttp HTTPS handshake Failed

I am using Indy 10 to connect to a SOAP Web Service. When I run the code with Fiddler running I find the webserver is not negotiating our Handshake. I have attached a screen shot of the Fiddler Inspectors.
We have been able to successfully connect to the server using the shareware application "SoapUI". I have attached a screen shot of the inspectors when using SoapUI.
One thing I notice is SoapUI is using a different version of SSL/TLS. How do I configure Indy to use the same version?
Any other insight as to why my call is failing?
procedure TForm6.Button1Click(Sender: TObject);
var
idhttp: TIdhttp;
IdSSLIOHandlerSocket1 : TIdSSLIOHandlerSocketOpenSSL;
Params : TStringStream;
begin
idhttp := TIdhttp.Create(nil);
IdSSLIOHandlerSocket1 := TIdSSLIOHandlerSocketOpenSSL.create(nil);
idhttp.ProxyParams.ProxyServer := '127.0.0.1';
idhttp.ProxyParams.ProxyPort := 8888 ;
idhttp.Request.ContentType := 'text/xml';
idhttp.Request.CharSet:='utf-8';
idhttp.request.connection := 'keep-alive';
idhttp.Request.CustomHeaders.AddValue('Content-Type','text/xml;charset=UTF-8');
idhttp.Request.CustomHeaders.AddValue('SOAPAction','"http://ws.nemsis.org/SubmitData"');
idhttp.Request.CustomHeaders.AddValue('Host','nemsis.org:443');
idhttp.Request.BasicAuthentication := True;
idhttp.request.username := 'xxxxx';
idhttp.request.password := 'yyyyy';
with IdSSLIOHandlerSocket1 do begin
SSLOptions.Method := sslvTLSv1_2;
SSLOptions.SSLVersions := [sslvTLSv1_2];
SSLOptions.VerifyMode := [];
SSLOptions.VerifyDepth := 2;
end;
with IdHTTP do begin
IOHandler := IdSSLIOHandlerSocket1;
end;
Params := TStringStream.Create(filetostring(ExtractFileDir(ParamStr(0))+'\sample.xml'));
idhttp.Post('https://nemsis.org:443/NemsisV3Validator4/NemsisWsService',Params);
end;
Failed Call:
Successful Call using SoapUI:

Error connecting with SSL using IdHttp Indy

I have a problem in IdHttp using Indy (Delphi).
I try to using IdHttp to post XML in web service SOAP, but dont work. Return "Error connecting with SSL." in IdSSLOpenSSL.Connect#1437 from indy.
My code is simple:
procedure TForm1.Button1Click(Sender: TObject);
var
vRequest : TStringStream;
s : String;
begin
vRequest := TStringStream.Create((Memo1.Lines.Text));
try
IdHTTP1.Host := edHost.Text;
IdHTTP1.Request.ContentLength := length(Memo1.Lines.Text);
IdHTTP1.Request.ContentType := edContentType.Text;
IdHTTP1.Request.CustomHeaders.Text := 'SOAPAction: "removed for safe"'#13#10;
IdHTTP1.request.CacheControl := 'no-cache';
IdHTTP1.Request.AcceptEncoding := edAccept.Text;
IdHTTP1.HTTPOptions := [hoKeepOrigProtocol];
IdHTTP1.ProtocolVersion := pv1_1;
Memo2.Clear;
try
s := IdHTTP1.post(Edit1.Text, vRequest);
Memo2.Lines.Text := s;
except
on e: EIdHTTPProtocolException do begin
Label1.Caption := e.Message;
MEMO2.LINES.TEXT := e.Message;
end;
on e:Exception do begin
Label1.Caption := e.Message;
MEMO2.LINES.TEXT := e.Message;
end;
end;
requestHeaders.Lines.Text := IdHTTP1.Request.RawHeaders.Text;
responseHeaders.Lines.Text := IdHTTP1.Response.RawHeaders.Text;
finally
vRequest.Free;
end;
end;
In exe folder contain libeay32.dll and ssleay32.dll. Any sugestion?
I Used delphi 5, but in delphi 7 is the same problem.
By default, the SSLVersions property of TIdSSLIOHandlerSockOpenSSL is set to enable only TLS 1.0 1. But many websites are starting to phase out TLS 1.0 and only accept TLS 1.1+. So try enabling TLS 1.1 and TLS 1.2 in the SSLVersions property and see if it helps.
1: there is an open ticket in Indy's issue tracker to also enable TLS 1.1 and TLS 1.2 by default.
On a side note, there are some further tweaks you should make to your code:
do not assign any values to TIdHTTP's Host or ContentLength properties. They are populated automatically by TIdHTTP.
if you set the AcceptEncoding property manually, make sure NOT to include deflate or gzip unless you have a Compressor assigned to TIdHTTP, otherwise it will fail to decode a compressed response. You really should not assign anything to AcceptEncoding unless you are prepared to handle custom encodings. The Compressor handles deflate/gzip and TIdHTTP will update AcceptEncoding accordingly if a Compressor is assigned and ready for use.
use the CustomHeaders.Values property to set individual headers, not the CustomHeaders.Text property.
you do not need to catch EIdHTTPProtocolException explicitly, since that exception handler is not doing anything extra that the more generic Exception handler is not doing.
the RawHeaders property is a TStringList descendant, so it is more efficient to use Lines.Assign(RawHeaders) instead of Lines.Text := RawHeaders.Text.
Try this:
procedure TForm1.Button1Click(Sender: TObject);
var
vRequest : TStringStream;
s : String;
begin
IdHTTP1.Request.ContentType := edContentType.Text;
IdHTTP1.Request.CustomHeaders.Values['SOAPAction'] := 'removed for safe';
IdHTTP1.Request.CacheControl := 'no-cache';
IdHTTP1.HTTPOptions := [hoKeepOrigProtocol];
IdHTTP1.ProtocolVersion := pv1_1;
Memo2.Clear;
try
vRequest := TStringStream.Create(Memo1.Lines.Text);
try
s := IdHTTP1.Post(Edit1.Text, vRequest);
finally
vRequest.Free;
end;
Memo2.Lines.Text := s;
except
on e: Exception do begin
Label1.Caption := e.Message;
Memo2.Lines.Text := e.Message;
end;
end;
RequestHeaders.Lines.Assign(IdHTTP1.Request.RawHeaders);
ResponseHeaders.Lines.Assign(IdHTTP1.Response.RawHeaders);
end;

Seeing Indy Traffic in Fiddler

I think this is an easy question for someone familiar with Indy. I'm using Delphi 2010 and Indy 10. I am trying to get off the ground accessing an SSL web service. I think it will be a lot easier if I can get Fiddler to see my HTTP traffic. I have seen posts on StackOverflow that indicate it's no big thing to get Fiddler to see your Indy traffic, that you just have to configure the port to make it work. My question is how do you do that?
Here is my code so far:
procedure TForm1.Button1Click(Sender: TObject);
var slRequest: TStringList;
sResponse,
sFileName: String;
lHTTP: TIdHTTP;
lIOHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
sFileName := 'Ping.xml';
slRequest := TStringList.Create;
try
slRequest.LoadFromFile(sFileName);
lHTTP := TIdHTTP.Create(nil);
lHTTP.Intercept := IdLogDebug1;
lIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
lHTTP.IOHandler := lIOHandler;
sResponse := lHTTP.Post('https://FSETTESTPROD.EDD.CA.GOV/fsetservice', slRequest);
Memo1.Lines.Text := sResponse;
finally
lIOHandler.Free;
end;
finally
slRequest.Free;
end;
end;
Edit: If I don't use the proxy for Fiddler and click the button while Wireshark is running, I get this traffic in Wireshark.
You can set Indy to use the proxy fiddler provides easily by setting the ProxyParams:
try
lHTTP.IOHandler := lIOHandler;
lHTTP.ProxyParams.ProxyServer := '127.0.0.1';
lHTTP.ProxyParams.ProxyPort := 8888;
sResponse := lHTTP.Post('<URL>', slRequest);
Memo1.Lines.Text := sResponse;
finally
lIOHandler.Free;
end;
You should be able to see all traffic in Fiddler then.
Edit: If that does not work you can add a TIdLogDebug component and add it as interceptor (like you did in your question).
The OnReceive and OnSend events contain the complete headers sent and received aswell as the reply data:
procedure TForm10.captureTraffic(ASender: TIdConnectionIntercept;
var ABuffer: TArray<Byte>);
var
i: Integer;
s: String;
begin
s := '';
for i := Low(ABuffer) to High(ABuffer) do
s := s + chr(ABuffer[i]);
Memo1.Lines.Add(s);
end;

Post problems with Indy TIdHTTP

I am having issues posting to Amazon's SES Service using Indy's TIdHTTP.
Here is an example of the code i am using:
procedure TMainFrm.btnAmazonSESClick(Sender: TObject);
var
SSLHandler: TIdSSLIOHandlerSocket;
HttpClient: TIdHTTP;
Params: TStringStream;
begin
SSLHandler := TIdSSLIOHandlerSocket.Create(Self);
HttpClient := TIdHTTP.Create(Self);
Params := TStringStream.create('');
try
with SSLHandler do
SSLOptions.Method := sslvSSLv3
with HttpClient do
begin
IOHandler := SSLHandler;
AllowCookies := True;
HandleRedirects := True;
HTTPOptions := [hoForceEncodeParams];
Request.ContentType := 'application/x-www-form-urlencoded';
end;
PageMemo.Text := HttpClient.Post('https://email.us-east-1.amazonaws.com?Action=VerifyEmailAddress&AWSAccessKeyId=012Some123Key46&EmailAddress=test#test%2Ecom', Params);
finally
SSLHandler.Free;
HttpClient.Free;
Params.Free;
end;
end;
Result
Under Indy 10.5.7 I get the error: HTTP/1.1 404 Not Found
Under Indy 9.0.14 I get the error: Socket Error # 11004
Debugging Trials
This same demo can successfully GET the HTML from an HTTPS web page.
If i paste the URL above into a browser it displays the expected XML result.
I would appreciate any advice on the cause.
This post is just an incomplete wild guess.
Maybe Remy might help you to correct it. With the following code I'm getting HTTP/1.1 400 Bad Request but I'm not wondering because the API reference talks about Common Query Parameters where is at least required the digital signature you'll create for the request what I don't know how to do.
I can't test this at all because I have no account there. But I think the
procedure TForm1.Button1Click(Sender: TObject);
var
HTTPClient: TIdHTTP;
Parameters: TStrings;
SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
HTTPClient := TIdHTTP.Create(nil);
Parameters := TStringList.Create;
try
SSLHandler.SSLOptions.Method := sslvSSLv3;
SSLHandler.SSLOptions.Mode := sslmUnassigned;
HTTPClient.IOHandler := SSLHandler;
HTTPClient.HTTPOptions := [hoForceEncodeParams];
HTTPClient.Request.ContentType := 'application/x-www-form-urlencoded';
Parameters.Add('Action=VerifyEmailAddress');
Parameters.Add('EmailAddress=test#test.com');
Parameters.Add('AWSAccessKeyId=012Some123Key46');
Parameters.Add('SignatureVersion=2');
Parameters.Add('Expires='); // ???
Parameters.Add('Signature='); // ???
PageMemo.Text := HTTPClient.Post('https://email.us-east-1.amazonaws.com', Parameters);
finally
SSLHandler.Free;
HTTPClient.Free;
Parameters.Free;
end;
end;
Basically, you need to use the right library, i.e.:
For Indy 10.5.7 use openssl-1.0.1e-i386-win32 or openssl-1.0.1e-x64_86-win64 from http://indy.fulgan.com/SSL/
You may want to download an ssl demo from: http://indy.fulgan.com/ZIP/
Regards
Jose

Resources