Magno 4 Posted October 1, 2020 I have such class: type TmyNetHTTPClient = class(TNetHTTPClient) private FileName: String; Index: Integer; Downloaded: Boolean; FileStream: TFileStream; public procedure ReceiveData(const Sender: TObject; AContentLength, AReadCount: Int64; var Abort: Boolean); procedure RequestCompleted(const Sender: TObject; const AResponse: IHTTPResponse); end; Now I create my object and have some similar: // consider filestream already created and other needs for the sake of this example begin myNetHTTPClient := TmyNetHTTPClient.Create(self); myNetHTTPClient.Get('http://localhost/file.txt', FileStream); //myNetHTTPClient.onReceiveData; // error, so commented end; Now, what is I am doing wrong here? The ReceiveData(), and also RequestCompleted() are never triggered 😕 procedure TDownloader.ReceiveData(const Sender: TObject; AContentLength, AReadCount: Int64; var Abort: Boolean); begin doSomething(); end; What should I do to make it work? Share this post Link to post
Jacek Laskowski 57 Posted October 1, 2020 In your class constructor, you should assign these events, something like: constructor TmyNetHTTPClient.Create() begin inherited Create; OnReceiveData := ReceiveData; OnRequestComplewted := RequestCompleted; end; 1 Share this post Link to post
Magno 4 Posted October 1, 2020 13 minutes ago, Jacek Laskowski said: In your class constructor, you should assign these events, something like: constructor TmyNetHTTPClient.Create() begin inherited Create; OnReceiveData := ReceiveData; OnRequestComplewted := RequestCompleted; end; YES!!!!! I missed this understanding!! Thank you so much!! 😄 Share this post Link to post
Renate Schaaf 64 Posted October 2, 2020 8 hours ago, Magno said: OnReceiveData := ReceiveData; I'm a bit puzzled here, because usually it is a big no-no to assign code to a published event in a descendant component. Because the event is still published and anybody using your component can assign something else to this event and your added functionality is gone. Usually you should override the method which calls the event, add the functionality and call inherited. Only: Looking at the source code I see that this method (DoReceiveData) is both private and not virtual, so there's no chance to do it this way. I wonder whether there's a reason the Delphi developers did it that way, or why have they abandoned the usual component design patterns? Anyway, I would at least unpublish these events, along the lines in https://stackoverflow.com/questions/53677049/hide-properties-and-events-in-new-component 4 Share this post Link to post
Guest Posted October 2, 2020 1 hour ago, Renate Schaaf said: I wonder whether there's a reason the Delphi developers did it that way, or why have they abandoned the usual component design patterns? Simply put, sloppy work done by developers who don't understand the Delphi soul. Share this post Link to post
Renate Schaaf 64 Posted October 2, 2020 38 minutes ago, Kas Ob. said: Simply put, sloppy work done by developers who don't understand the Delphi soul. I didn't dare to say that, but that's what I thought:) Now I wonder whether there is a way to make this safe short of changing the source code or writing a wrapper component with a TNetHTTPClient as a subcomponent and exposing its things as needed, which seems to be a lot of work. Share this post Link to post
Guest Posted October 2, 2020 2 hours ago, Renate Schaaf said: I didn't dare to say that, but that's what I thought:) Don't do that, you paid them money they asked for, they dared to fail for years to provide the quality after receiving money, at least you should ask for quality worth for your money and time, it might help prevent such sloppy work for the future. I never used this TNetHTTPClient , but i can list few approach's to consider 1) Override with copy and paste, this is ugly and might not work if those methods are using private fields/methods, even it did work might not be compatible with future versions. 2) Have a look at https://github.com/MahdiSafsafi/DDetours it can do magic, but does need special experience level, so the level you must have to use this library range from novice to guru, based on your mission, check it anyway you might need it in the furute. 3) Ditch TNetHTTPClient and look for alternative (there is dozens), most likely will find higher quality and better functionality. Share this post Link to post
Jacek Laskowski 57 Posted October 2, 2020 15 minutes ago, Kas Ob. said: 3) Ditch TNetHTTPClient and look for alternative (there is dozens), most likely will find higher quality and better functionality. NetHTTPClient has one huge advantage... When working with SSL/TLS it uses the system api and you don't have to fight with openssl, certificates etc. 2 Share this post Link to post
David Schwartz 426 Posted October 2, 2020 4 hours ago, Renate Schaaf said: I wonder whether there's a reason the Delphi developers did it that way, or why have they abandoned the usual component design patterns? There are TONS of places throughout the VCL where the original developers could be accused of not thinking through the various use-cases enough to have a clear idea of what methods should have been tagged as protected rather than private. I think they tended to err on the side of keeping things private that didn't have obvious reasons to override them at the time. I see plenty of libs where the devs went the other way and stuffed nearly everything into the protected section instead of private, leaving a huge invitation to hack the crap out of things. I've often run into this situation in my own code, where I needed to override a method in a child class but I left it as private in the parent/base class instead of protected. It just didn't occur to me that I'd ever want to use it in a child class. Honestly, this is an area that you could spend a ton of time sweating over prior to a product release, and if you're in a hurry like most projects, it just never gets addressed. And that's why there are hacks for that ... 2 Share this post Link to post
Guest Posted October 2, 2020 Just now, Jacek Laskowski said: NetHTTPClient has one huge advantage... When working with SSL/TLS it uses the system api and you don't have to fight with openssl, certificates etc. If the point is to have the TLS connection then it is valid point, but many other (may be all) libraries have it too!, it is almost everywhere, even Delphi Html Component implement those ~30 functions, EurekaLog does have it.... And i am not talking about is it security level, i have no idea, i know for sure the IDE itself for years didn't have secure connection and when it did have it, it is useless as trash, as it will accept in expired certificate, even when the name is not matching the connection will be successful established and data will be sent, useless shell with traffic overhead. When it comes for security, don't trust a chef that use a microwave to prepare you "fancy pricey food". Share this post Link to post
Renate Schaaf 64 Posted October 2, 2020 33 minutes ago, David Schwartz said: There are TONS of places throughout the VCL where the original developers could be accused of not thinking through the various use-cases enough That's my limited impression after a break of 12 years from Delphi. I paid for all versions up to 2006, now I'm using the community edition, and I am grateful for having the chance this way to come up to par with the new stuff, so I'm a bit reluctant to bash them. I answered here because of general interest in component design, not because I'm particularly interested in this component. 1 hour ago, Kas Ob. said: 2) Have a look at https://github.com/MahdiSafsafi/DDetours it can do magic, but does need special experience level, so the level you must have to use this library range from novice to guru, based on your mission, check it anyway you might need it in the furute. This looks good, I have it tagged. Share this post Link to post
Fr0sT.Brutal 900 Posted October 2, 2020 4 hours ago, Jacek Laskowski said: NetHTTPClient has one huge advantage... When working with SSL/TLS it uses the system api and you don't have to fight with openssl, certificates etc. If you only deal with Windows, check out my https://github.com/Fr0sT-Brutal/Delphi_SChannelTLS set of classes that allow to add OS-provided TLS to any communication transport (even SendMessage 🙂 ) . But OTOH I wish Emba adopted curl in the form of obj-s. Share this post Link to post
aehimself 396 Posted October 4, 2020 On 10/2/2020 at 7:58 AM, Kas Ob. said: Simply put, sloppy work done by developers who don't understand the Delphi soul. I did this once, when I made a heavily customized DBGrid component. The custom grid had a default popup menu with basic things (copy, copy all, copy with header, etc). So if there was a popup menu assigned design time, I appended my items. If none, I created one. Alas, you don't want these options to be available when the grid is empty. So I made a custom onPopup handler to disable these items based on the selected record / field. But before assigning the new handler, I saved the old handler in a variable and executed it after I enabled / disabled my menu items. I mean, there are things what you only can solve like this, but there is a bad way of doing everything. However, I too prefer overriding the "DoCall" methods, wherever I can. Share this post Link to post
Fr0sT.Brutal 900 Posted October 5, 2020 Honestly I don't think the "private" stuff is important for protecting. It's more like for logical structure, exposed API's and the number of shown items in field list. Private items could be changed freely without care about breaking changes but if someone wants to access them, why not let him do it? Share this post Link to post