-
Content Count
2985 -
Joined
-
Last visited
-
Days Won
134
Posts posted by Remy Lebeau
-
-
On 9/29/2023 at 3:51 AM, DelphiUdIT said:In the server connect event you must add:
procedure TFTPServer.ServerConnect(AContext: TIdContext); begin If AContext.Connection.IOHandler is TIdSSLIOHandlerSocketBase then TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough := (UseTLS = utNoTLSSupport); //This function must be set to false for it to handle SSL/TLS functionality. end;
This approach is incorrect. This forces ALL connections to use SSL/TLS implicitly at connect-time. But clients may want to use SSL/TLS explicitly instead, ie via an AUTH or CCC command.
The CORRECT way to handle the PassThrough is to let TIdFTPServer manage it for you. You should not be setting it manually yourself at all.
If TIdFTPServer.UseTLS is set to utNoTLSSupport then TIdFTPServer will not touch PassThrough at all, and neither should you.
If TIdFTPServer.UseTLS is set to utUseRequireTLS or utUseExplicitTLS then TIdFTPServer will set PassThrough according to client commands. You don't need to do anything extra for this. The difference between them is that utUseExplicitTLS allows the client to decide whether SSL/TLS is used, whereas utUseRequireTLS will reject various operations if the client doesn't use SSL/TLS.
If TIdFTPServer.UseTLS is set to utUseImplicitTLS than you need to use the TIdFTPServer.OnQuerySSLPort event to tell the server which port(s) are to use SSL/TLS implicitly (ie, to set PassThrough at connect-time),
-
24 minutes ago, Aztec said:Where can I find those .so files though?
There are some at https://github.com/IndySockets/OpenSSL-Binaries, though those might be for Android not Linux (though Android runs on top of Linux). Otherwise you'll have to look around.
QuoteDoes this require an installation on linux or can I simply place them in the same location as my module?
You can simply put them in your app's folder, or anywhere else you want. If needed, Indy has an IdOpenSSLSetLibPath() function in the IdSSLOpenSSLHeaders unit.
QuoteWill indy support the latest SSLlib in Delphi 12?
I don't know at this time.
I have discussed this matter with Marco Cantu and others, so they are certainly interested in a resolution, and are aware of the PR on GitHub.
They are likely going to ship an up-to-date version of Indy's main code with Delphi 12 (see disclaimer below!), but whether they include the PR code in some form is unclear at this time. It is a pretty big PR, and is not incorporated into the main code.
I suggested maybe putting the PR code into a new package. Marco suggested maybe providing it as an optional add-on via GetIt, but that is something they would have to setup on their end, if at all.
Disclaimer: This blog post is based on a pre-release version of the RAD Studio software and it has been written with specific permission by Embarcadero. No feature is committed until the product GA release.
-
34 minutes ago, Aztec said:he actual inner error is General Exception: Could not load SSL library.
Hmm, that should say EIdOSSLCouldNotLoadSSLLibrary instead of General Exception. But at least the root cause is now known.
QuoteI did a search in here and it seems that everyone is talking about Windows, but could not find anything related to Linux.
Indy dynamically loads OpenSSL at runtime on most platforms, including Linux. You are seeing the error when Indy is not able to load OpenSSL at runtime.
QuoteLooking in the configs, it does seem that the various SSL versions can be allowed or rejected (See screen shot). I have allowed them all for now, but that makes no difference.
In one of those screens, I see libssl.so.3 and libcrypto.so.3 shown. Those are the OpenSSL libs, but are they for OpenSSL v3.0? If so, that version is not compatible with TIdSSLIOHandlerSocketOpenSSL.
By default, Indy loads unversioned .so files before loading versioned files. If those unversioned files are symlinks that map to newer versions, you could get the load error.
On 'Nix platforms, Indy has IdOpenSSLSetCanLoadSymLinks() and IdOpenSSLSetLoadSymLinksFirst() functions in the IdSSLOpenSSLHeaders unit. You can set them to False at runtime before using Indy, that way it load the versioned .so files first/only, and then you can deploy OpenSSL v1.0.2 .so files with your app that are currently compatible with Indy.
If that is not an option, then you can try this WIP SSLIOHandler for newer OpenSSL versions (not sure if it supports v3.0 or Linux, though) instead of TIdSSLIOHandlerSocketOpenSSL.
In any case, one way to handle this error condition a little better in TIdSSLIOHandlerSocketOpenSSL is to call Indy's LoadOpenSSLLibrary() function from the IdSSLOpenSSL unit during your app's startup. If it fails, you can use Indy's WhichFailedToLoad() function from the IdSSLOpenSSLHeaders unit to help diagnose why it failed.
-
10 hours ago, Aztec said:However when we try and send email we get the following error
[ EIdTLSClientTLSHandShakeFailed ] SSL negotiation failedEIdTLSClientTLSHandShakeFailed is an outer exception raised when an earlier exception is caught during the TLS handshake. What does its InnerException say was the initial error?
10 hours ago, Aztec said:the parameters I am assigning are correct
What are the actual values you are using? In particular, which Port are you TRYING to connect to, and which Port is it ACTUALLY connecting to? I notice that you are assigning the Port first, then assigning the IOHandler and UseTLS after. Depending on the particular Port value, the UseTLS setter MIGHT be changing the Port to a different value. Try setting the Port after setting UseTLS, to make sure you are actually using the Port you are expecting.
Aside from that, does the server in question still support TLS 1.1/1.2? Some servers have made the jump to requiring TLS 1.3 nowadays.
-
XE4 was released 10 years ago. And TIdHL7 specifically got a major revamp from its original author a year ago. So, you should upgrade to the latest Indy (if not to a modern Delphi) and see if the problem still occurs.
-
11 hours ago, sBsaidus said:Can someone tel me what's wrong with the code.
There is quite a lot wrong with the server code you have shown.
TIdTCPServer is a multi-threaded component. The listening ports are managed in worker threads. Each connected client is handled in its own worker thread.
Your management of your f_CClients list is not thread-safe, or even accurate in places. It is also redundant, as TIdTCPServer already has a thread-safe list of connected clients in its Contexts property. You should just get rid of your f_CClients list altogether and use the Contexts list by itself. You can store your tCClient objects in the TIdContext.Data property, or you can derive it from TIdServerContext and then set it to the TIdTCPServer.ContextClass property before activating the server.
You are accessing your TMemo and TListView directly in the context of each client worker thread. Any access to the UI from a worker thread must be synchronized with the main UI thread, which you are not doing at all. Use TThread.Synchronize() or TThread.Queue() (or Indy's TIdSync or TIdNotify) for that purpose. Do be careful with TThread.Synchronize()/TIdSync, though. Since they are synchronous, if you deactivate the server in the main UI thread, and then try to sync with the UI thread, you will deadlock the server. So, don't sync synchronously while deactivating the server, or do the deactivation in a separate thread so the main UI thread remains free to process sync requests.
You are directly sending your QUIT commands to clients from the context of the main UI thread. In this example, you are not sending anything else to the clients, but if you were, you would potentially be overlapping any sends those clients' threads may happen to be performing at the same time, which would corrupt your communications. You must serialize access to a client's socket when sending to it across thread boundaries. It is generally best to keep your socket I/O with a given client in that client's worker thread as much as possible.
In short, your server code needs a good amount of rewriting to operate safely in a multi-threaded environment.
-
2 hours ago, Roger Cigol said:If you only have C++ Builder version you cannot use Delphi units in your project
You should be able to, as it should have the command-line Delphi compiler available, so that 3rd party components can still be compiled and installed into the IDE for C++Builder to use.
-
Indy uses blocking sockets and synchronous I/O. The client's OnDisconnected event is fired when the *client* disconnects on its end. If the server disconnects first, there is no real-time notification of that. The client will notify your code only when the client tries to access the connection and gets an error from the OS, at which time it will raise an exception to your code, such as EIdConnClosedGracefully, etc. So, if you want timely notification of a remote disconnect, you need to actively send/read data. If your code is not using the connection for lengths of time, use a timer to poll for incoming data periodically. Or use a reading loop in a worker thread.
-
1
-
-
2 hours ago, David Schwartz said:I don't think you can load any components into the CE versions
Per the CE FAQ:
https://www.embarcadero.com/products/delphi/starter/faq
Quote24. Can I add additional commercial and open source tools and VCL components to Delphi Community Edition or C++Builder Community Edition?
Yes
-
23 minutes ago, rvk said:Why is the date of the files on Fulgan updated each night?
I don't know, I thought they were done maintaining a copy, but I guess not.
23 minutes ago, rvk said:Maybe a readme file there pointing to the new official spot (or at least stating it is decommissioned) would make that more clear.
The readme on that mirror says:
QuoteAs of January 2020, the Indz source code is not available from this mirror anymore:
The indy source control system has been migrated to github. There is therefore no need for extra tools in order to download the latest snapshot.
All source code can be accessed from https://github.com/IndySockets
The Indy SSL libraries will remain here for the time being.
-
7 hours ago, dummzeuch said:Not quite the implementation I would have liked though. Triple quotes '''? Who came up with that? Is that copyied from another programming language?
Influenced by C# (like several features in Delphi have been):
-
1
-
-
7 hours ago, Die Holländer said:Your site (Lebeau Software) is not available anymore.
It is working fine for me.
7 hours ago, Die Holländer said:Are you planning to continue with the site?
Yes. My hosting provider did perform maintenance on my site's server yesterday, so maybe they messed something up, or have already resolved the issue.
-
20 hours ago, DelphiUdIT said:Except for a library for Android ARM64-V8 (64 bit) which is present in Indy and which is not present in Fulgan.
OK, well...
The fulgan mirror has been decommissioned for some time now, the GitHub repo is the official spot now.
-
On 9/17/2023 at 4:07 AM, PeterBelow said:Btw.: TeamB was a group of users offering support to other users on the old Borland newsgroups. As recognition they received goodies like free product licences, a bit like the current Embarcadero MVP program, and we had dedicated support partners at Borland. All that slowly died off after Codegear took over, unfortunately.
But at least we get some of that back via Embarcadero MVP!
-
3 hours ago, DelphiUdIT said:You can look to Indy repository too: https://github.com/IndySockets/OpenSSL-Binaries
Those are the same DLLs that used to be on the indy.fulgan.com site.
-
4 hours ago, domus said:Would anyone know if it's allowed to install a Community Edition of Delphi on two separate PCs simultaneously? (PC and laptop)
Yes, per the EULA:
QuoteINSTALLATION AND USE RIGHTS. You may install and use any number of copies of the software on your devices.
The EULA explains several restrictions on the Community Edition, but this is not one of them.
-
1
-
-
10 hours ago, Rollo62 said:I use ForceQueue and my own implementation of a DelayWorker successfully for years now,
but I never realized that ForceQueue has its own Delay option available too.
The Delay option was added in 10.4 Sydney, so it is a relatively recent addition (2020).
-
1
-
-
4 hours ago, alank2 said:sometimes I have a synchronous process and I want to make sure some VCL elements are updated beforehand. This always worked fine in bcb6.
BCB6 predates Visual Styles and VCL Styles and basically most modern UI practices.
4 hours ago, alank2 said:What could cause the Enabled change to _not_ create an immediate pending message?
For example, when UI changes are animated by the OS or Styles, it would thus take multiple paint cycles to fully animate the complete state change, and ProcessMessages() or Update() may not (likely will not) catch all of the paint cycles in a single call.
51 minutes ago, alank2 said:I realize that putting the "seconds to run" is more ideal in a thread, but that adds creating and managing a thread which I don't want to have to do for every process that takes a few seconds.
You can mitigate that somewhat by using thread pools, for instance.
51 minutes ago, alank2 said:Essentially I am looking for a function that will make sure the UI is fully updated before a period of time where it won't be updated.
There is nothing in UI programming that says like "state change is finished and the UI for it is fully drawn". Not even back in BCB6's day. Although back then, drawing was much simpler, and usually completed in 1 paint cycle. That may not be the case anymore in modern UIs.
51 minutes ago, alank2 said:I tried using calling Repaint for all 3 buttons before a ProcessMessages, but it didn't work.
Whatever is different between versions, perhaps changing a property from true to false takes a number of things to occur in sequence that rely on each other?
That is not really a factor of the property itself, but in the UI rendering behind the scenes, so more oriented to differ between OS versions rather than compiler/VCL versions.
13 minutes ago, alank2 said:DelphiUdIT - I tried the below (with and without the processmessages calls) and it still has the issue
Update() only processes paint messages that are already pending in the message queue. But you also need Invaliidate() to generate those messages in the first place, if they are not already generated for you. So that is where Repaint() comes into play, to signal that a new paint cycle is needed if it hasn't already been signaled.
-
2
-
-
6 hours ago, alank2 said:I think ProcessMessages was supposed to process all messages, right?
Yes, it does. But it can only handle messages that are already in the message queue (or synthetically generated by the queue) at the moment it is called. It does not process future messages. And the behavior you describe sounds like the actions are being delayed such that ProcessMessages() doesn't see all of them right away, which is why calling ProcessMessages() multiple times produces better results.
You really should not be using ProcessMessages() in this manner in the first place. Break up your code logic using TThread::ForceQueue() or a TTimer or equivalent to allow control to flow back into the main message loop so it can continue to process new messages while your desired time interval is waiting to elapse.
For example, using TThread::ForceQueue():
void __fastcall TForm1::Button1Click(TObject *Sender) { Button1->Enabled = false; Button2->Enabled = false; Button3->Enabled = false; TThread::ForceQueue(nullptr, &Step2, 3000); } void __fastcall TForm1::Step2() { Button1->Enabled = true; Button2->Enabled = true; Button3->Enabled = true; TThread::ForceQueue(&Step3, 3000); } void __fastcall TForm1::Step3() { //... } // alternatively void __fastcall TForm1::Button1Click(TObject *Sender) { Button1->Enabled = false; Button2->Enabled = false; Button3->Enabled = false; TThread::ForceQueue(nullptr, [this](){ Button1->Enabled = true; Button2->Enabled = true; Button3->Enabled = true; TThread::ForceQueue(nullpr, [](){ //... }, 3000); }, 3000); }
Or, using TTimer:
void __fastcall TForm1::Button1Click(TObject *Sender) { Button1->Enabled = false; Button2->Enabled = false; Button3->Enabled = false; //Timer1->Interval = 3000; Timer1->Tag = 1; Timer1->Enabled = true; } void __fastcall TForm1::Timer1Timer(TObject *Sender) { if (Timer1->Tag == 1) { Button1->Enabled = true; Button2->Enabled = true; Button3->Enabled = true; //Timer1->Interval = 3000; Timer1->Tag = 2; } else { //... Timer1->Enabled = false; Timer1->Tag = 0; } } // alternatively... void __fastcall TForm1::Button1Click(TObject *Sender) { Button1->Enabled = false; Button2->Enabled = false; Button3->Enabled = false; //Timer1->Interval = 3000; Timer1->OnTimer = Step2; Timer1->Enabled = true; } void __fastcall TForm1::Step2(TObject *Sender) { Button1->Enabled = true; Button2->Enabled = true; Button3->Enabled = true; //Timer1->Interval = 3000; Timer1->OnTimer = Step3; } void __fastcall TForm1::Step3(TObject *Sender) { //... Timer1->Enabled = false; Timer1->OnTimer = nullptr; }
-
3
-
-
2 hours ago, WalkingAway said:Is it possible to get / set through RTTI non standard type value?
I tries, but always got something like 'invalid tapecast' error.
Can you show the actual code you are having trouble with?
2 hours ago, WalkingAway said:What I want - to unified opportunity to set / get "Meta" value ,
it can be FirstFrame.Meta, SecondFrame.Meta, ...
What is "Meta" defined as?
2 hours ago, WalkingAway said:Now I have to write
if FirstFrame.Meta is AccountFrame then ...
else if FirstFrame.Meta is ReportFrame
What is it you are trying to do with "Meta", exactly? We can't really help you without more detail.
2 hours ago, WalkingAway said:If I have 50 frames it is too boring. RTTI may help me
Or maybe mnthere some libraries for that
Or maybe just re-think your design? Perhaps interfaces are more suitable? Hard to say without seeing what you are actually trying to do.
2 hours ago, WalkingAway said:Also I want to link that kind of link to "Meta" to listview (TValue.From) for same purpose. With no success also so far...
I'm sure there are ways to accomplish that, but again, it really depends on what your data looks like and how you are using it.
-
What @DelphiUdIT said. Indy 10 does have .dpk package files for Delphi 7, namely:
IndySystem70.dpk
IndyCore70.dpk
IndyProtocols70.dpk
dclIndyCore70.dpk
dclIndyProtocols70.dpk
-
1
-
1
-
-
57 minutes ago, Todd Grigsby said:I downloaded the latest Indy available on github two nights ago -- 10.6.2 -- and it does not work with TLS 1.3
Did you download only the main code, or did you also download the PR #299 code on top of it?
57 minutes ago, Todd Grigsby said:Any idea when the TLS 1.3 branch will get merged into main?
No ETA at this time. My understanding is that the code works as-is, but still needs to be updated/finalized to include design-time support, added to all of the supported packages, etc.
-
2
-
-
3 hours ago, aehimself said:A ComboBox suffers from the same 2-click issue
What, 1 click to open the list, and 1 click to select? I really don't think that is much of an issue. But if it is, then just use TRadioGroup/3xTRadioButton instead.
-
If UI space is an issue, you could use a TComboBox with Style=csDropDownList instead, and just have 3 items to choose from.
Rad 12 Beta - Link to News
in Community Management
Posted
https://delphiworlds.com/2023/09/yukon-is-coming/
https://dalijap.blogspot.com/2023/09/coming-in-delphi-12-disabled-floating.html
https://blog.marcocantu.com/blog/2023-09-yukonbeta-stringliterals.html
MVPs were given permission to start blogging just a few days ago, but they have to be approved by Embarcadero before they're published. so I'm sure there will be more blog posts coming soon.