grantful 3 Posted October 16, 2023 i am using Delphi 11CE I am trying to send a basic email with indy; procedure SendTestEmail2; var SMTP: TIdSMTP; Message: TIdMessage; SSLHandler: TIdSSLIOHandlerSocketOpenSSL; begin SMTP := TIdSMTP.Create(nil); Message := TIdMessage.Create(nil); //SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); SSLHandler.SSLOptions.Method := sslvTLSv1_2; // or sslvTLSv1, sslvTLSv1_1, etc. try SSLHandler.SSLOptions.Method := sslvTLSv1_2; SSLHandler.SSLOptions.Mode := sslmUnassigned; SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); SMTP.IOHandler := SSLHandler; SMTP.Host := 'smtp.gmail.com'; SMTP.Port := 465; // or 465, depending on your server SMTP.UseTLS := utUseExplicitTLS; // or utUseImplicitTLS SMTP.Username := 'UserName'; SMTP.Password := 'Pass'; Message.From.Address := 'men@gmail.com'; Message.Recipients.EMailAddresses := 'grantful@yahoo.com'; Message.Subject := 'Test Subject'; Message.Body.Add('Test message.'); try SMTP.Connect; SMTP.Send(Message); except on E: Exception do begin ShowMessage('Error: ' + E.Message); end; end; finally SMTP.Free; Message.Free; SSLHandler.Free; end; end; Never worked with indy before . on the android phone i get Error Sending Email External exception 4e on my iphone i get error Sending Email: acces violation at address0000000000104b-d0788 Thanks for any help and or point me to a working example. Share this post Link to post
Virgo 18 Posted October 16, 2023 3 hours ago, grantful said: procedure SendTestEmail2; var SMTP: TIdSMTP; Message: TIdMessage; SSLHandler: TIdSSLIOHandlerSocketOpenSSL; begin SMTP := TIdSMTP.Create(nil); Message := TIdMessage.Create(nil); //SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); SSLHandler.SSLOptions.Method := sslvTLSv1_2; // or sslvTLSv1, sslvTLSv1_1, etc. SSLHandler variable is not initialized... So Access Violation is mandatory. Share this post Link to post
Remy Lebeau 1436 Posted October 16, 2023 (edited) 16 hours ago, grantful said: procedure SendTestEmail2; var ... SSLHandler: TIdSSLIOHandlerSocketOpenSSL; begin ... //SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); SSLHandler.SSLOptions.Method := sslvTLSv1_2; // or sslvTLSv1, sslvTLSv1_1, etc. try SSLHandler.SSLOptions.Method := sslvTLSv1_2; SSLHandler.SSLOptions.Mode := sslmUnassigned; SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); ... finally ... end; end; Look at that code very carefully. You have commented out the creation of an SSLHandler object, but then are accessing its members. Crash. And, if that one line were not commented out, you would then be creating a 2nd SSLHandler object and assigning it to the same variable, leaking the 1st object. You need to fix your object creation. This is not specific to Indy, this is a fundamental issue to how Pascal/OOP programming works in general. You have to create an object before you can use it. Now, after fixing that, your code has another problem - SMTP port 465 is an implicit TLS port, but you are setting the TIdSMTP.UseTLS property to utUseExplicitTLS. SMTP port 587 is the explicit TLS port. Use utUseImplicitTLS for port 465, and utUseExplicitTLS for port 587 (and optionally 25). Try this: procedure SendTestEmail2; var SMTP: TIdSMTP; SSLHandler: TIdSSLIOHandlerSocketOpenSSL; Message: TIdMessage; begin try SMTP := TIdSMTP.Create(nil); try SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(SMTP); SSLHandler.SSLOptions.SSLVersions := [sslvTLSv1_2]; // and/or sslvTLSv1, sslvTLSv1_1, etc. SSLHandler.SSLOptions.Mode := sslmClient; SMTP.IOHandler := SSLHandler; SMTP.Host := 'smtp.gmail.com'; SMTP.Port := 465; // or 587, depending on your server SMTP.UseTLS := utUseImplicitTLS; // or utUseExplicitTLS, depending on your server SMTP.Username := 'UserName'; SMTP.Password := 'Pass'; Message := TIdMessage.Create(nil); try Message.From.Address := 'men@gmail.com'; Message.Recipients.EMailAddresses := 'grantful@yahoo.com'; Message.Subject := 'Test Subject'; Message.Body.Add('Test message.'); SMTP.Connect; try SMTP.Send(Message); finally SMTP.Disconnect; end; finally Message.Free; end; finally SMTP.Free; end; except on E: Exception do begin ShowMessage('Error: ' + E.Message); end; end; end; Edited October 16, 2023 by Remy Lebeau Share this post Link to post
grantful 3 Posted October 17, 2023 Thanks for all comments and corrected code . Remy I was using (nil) and trying to take care of freeing the objects. I noticed you used (smpt) what advantage is there to doing it that way. Thanks i am trying to learn I am trying to use this code but on ios and android Share this post Link to post
Remy Lebeau 1436 Posted October 18, 2023 2 hours ago, grantful said: Remy I was using (nil) and trying to take care of freeing the objects. I noticed you used (smpt) what advantage is there to doing it that way. My example assigns the TIdSMTP object as the Owner of the SSLIOHandler object. When the TIdSMTP object is freed, it will free the SSLIOHandler object for you. This is a memory management mechanism that is implemented by all TComponent descendants. If you want to free the object yourself, you certainly can do so, eg: procedure SendTestEmail2; var SMTP: TIdSMTP; SSLHandler: TIdSSLIOHandlerSocketOpenSSL; Message: TIdMessage; begin try SMTP := TIdSMTP.Create(nil); try SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); try SSLHandler.SSLOptions.SSLVersions := [sslvTLSv1_2]; // and/or sslvTLSv1, sslvTLSv1_1, etc. SSLHandler.SSLOptions.Mode := sslmClient; SMTP.IOHandler := SSLHandler; SMTP.Host := 'smtp.gmail.com'; SMTP.Port := 465; // or 587, depending on your server SMTP.UseTLS := utUseImplicitTLS; // or utUseExplicitTLS, depending on your server SMTP.Username := 'UserName'; SMTP.Password := 'Pass'; Message := TIdMessage.Create(nil); try Message.From.Address := 'men@gmail.com'; Message.Recipients.EMailAddresses := 'grantful@yahoo.com'; Message.Subject := 'Test Subject'; Message.Body.Add('Test message.'); SMTP.Connect; try SMTP.Send(Message); finally SMTP.Disconnect; end; finally Message.Free; end; finally SSLHandler.Free; end; finally SMTP.Free; end; except on E: Exception do begin ShowMessage('Error: ' + E.Message); end; end; end; It is customary to assign a nil Owner when you want to free an object yourself. But it is safe to manually free an object that has an Owner assigned, as the freed object will simply remove itself from its Owner to avoid being freed again. 2 hours ago, grantful said: I am trying to use this code but on ios "Error: Access violation at address 000000010474D588, accessing address 0900000001000204" and android "Error: External exception 85" Are you debugging your app on those platforms to see what is actually going on? Which line of code is actually raising those errors? Share this post Link to post
grantful 3 Posted October 18, 2023 Thanks remy i will look into it some more tomarry after work. Share this post Link to post
grantful 3 Posted October 18, 2023 (edited) well on android in debug i got constructor TIdSSLContext.Create; begin inherited Create; //an exception here probably means that you are using the wrong version //of the openssl libraries. refer to comments at the top of this file. if not LoadOpenSSLLibrary then begin raise EIdOSSLCouldNotLoadSSLLibrary.Create(RSOSSLCouldNotLoadSSLLibrary); end; fVerifyMode := []; fMode := sslmUnassigned; fSessionId := 1; end; I will have to check this out Edited October 18, 2023 by grantful Share this post Link to post