Jump to content

Remy Lebeau

Members
  • Content Count

    2333
  • Joined

  • Last visited

  • Days Won

    94

Everything posted by Remy Lebeau

  1. Remy Lebeau

    Leak problem

    Indy comes pre-installed in the IDE. If you want to use your own compiled version of Indy, you should remove the pre-installed one to avoid conflicts.
  2. Remy Lebeau

    Leak problem

    Then you are likely not building with the DCUs you just compiled. Did you remove Indy from the IDE first? Did you update the IDE's search paths? https://github.com/IndySockets/Indy/wiki/Updating-Indy Also, which platform are you running your code on? The leaks you have showed are the intentional Indy leaks that should not be appearing on Windows, as they are "registered by pointer", as the dialog says.
  3. Remy Lebeau

    I solved my problem but

    You did not explain what kind of leaks you are actually experiencing (can you provide the actual leak report?), but I suspect the leaks have nothing to do with the TIdHTTP object itself. Are you referring to the intentional leaks in Indy's IdStack.pas and IdThread.pas units? If so, that is a completely separate matter, and one that is not affected by the Owner you assign to the TIdHTTP object.
  4. Remy Lebeau

    Leak problem

    And? The problem is ...? Wow, that is a really dirty and ugly hack. That code is reading the machine instructions of TIdStack.DecUsage() at runtime trying to find where it accesses the global GStackCriticalSection variable, and then it dereferences that variable to get the address of the TIdCriticalSection object, and then register it with FastMM so it won't appear in leak reports. I don't see why that hack is necessary at all when Indy already does that registration during unit initialization when REGISTER_EXPECTED_MEMORY_LEAK is defined, which it is by default when FREE_ON_FINAL is not defined, and either HAS_System_RegisterExpectedMemoryLeak or USE_FASTMM4 are defined. Yes, that is the correct solution. You have to recompile Indy for it to take effect. The simplest way would be to have your project refer to Indy's source files directly so they compile directly into the executable. If you have installed Indy into the IDE, you will have to recompile the installed BPLs instead.
  5. Remy Lebeau

    Why jpg image is not created?

    That is a bad idea in general. It prevents users from being able to set their own working directory when running your app from a command-line window or a shortcut.
  6. Remy Lebeau

    Why jpg image is not created?

    Check with TDirectory.GetCurrentDirectory() or equivalent to make sure that '.' refers to the folder you think it does.
  7. A read timeout error has nothing to do with authentication. Sounds more like the data connection is probably being blocked. Remember, FTP uses multiple TCP connections. I notice in your earlier log that a PORT command is being issued. That means your FTP client is acting in ACTIVE mode, where the server opens a data connection to the client. That is not very friendly to routers/proxies. You should use PASSIVE mode instead, where the client opens a data connection to the server instead. That is less likely to cause problems.
  8. Which version of the DLLs are you using, though? TIdSSLIOHandlerSocketOpenSSL supports OpenSSL 1.0.2 or earlier. If you are trying to use OpenSSL 1.1.x or later, you need to use this SSLIOHandler instead: https://github.com/IndySockets/Indy/pulls/299 The only issue I see with that code is you are creating the SSLIOHandler conditionally. You don't need to do that, you can access non-secure HTTP urls even with the SSLIOHandler assigned. TIdHTTP will handle the underlying TCP connection and SSLIOHandler.PassThrough property for you on a per-request basis, (re)connecting and toggling between TLS/non-TLS as needed. Because of that management, when you do create the SSLIOHandler, you don't need to set its PassThrough property manually at all. The SSLIOHandler will also handle loading the OpenSSL DLLs dynamically only when they are actually needed, so if you never request an HTTPS url then the DLLs won't ever get loaded, and PassThrough will always be True. So, I would suggest just getting rid of your UseSSL config option altogether, it is really not necessary. In fact, it will actually cause a runtime error if it is set to False and then you request a non-secure HTTP url that redirects to a secure HTTPS url. So, best to just have the SSLIOHandler assigned unconditionally instead, so it is always ready to go in case it is needed. procedure THSJSonApiClient.InitHTTP; begin fhttp := TIdHTTP.Create(nil); fopenssl := TIdSSLIOHandlerSocketOpenSSL.Create(fhttp); fopenssl.SSLOptions.VerifyMode := []; fopenssl.SSLOptions.VerifyDepth := 0; fopenssl.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1, sslvTLSv1]; fhttp.IOHandler := fopenssl; fhttp.handleredirects := True; {$IFDEF DEBUG} flog := TIdLogEvent.Create(nil); flog.ReplaceCRLF := False; flog.LogTime := False; flog.Active := True; flog.OnReceived := CatchLogReceived; flog.OnSent := CatchLogSent; flog.OnStatus := CatchLogStatus; fhttp.Intercept := flog; {$ENDIF} end;
  9. Remy Lebeau

    Reading REST response JSON pair

    Use the Value() method instead of the ToString() method: OrderNoRESTResp.RootElement := 'OrderNo'; Result := OrderNoRESTResp.JSONValue.Value; In this example, the JSONValue will point at a TJSONString, which overrides Value() to return the plain content. As it should be, since ToString() is meant for obtaining JSON formatted data, not plain data. You don't need to resort to accessing the JSON pairs directly in this case. Besides, if you are setting the RootElement to 'OrderNo', that code won't work, because the JSONValue will be pointing at a TJSONString not a TJSONObject, so the 'as' operator would raise an exception. But, if you are leaving the RootElement blank, then the JSONValue will be pointing at the whole TJSONObject, yes, and then you are effectively just accessing TJSONObject(JSONValue).Get('OrderNo').Value() in a round-about way. But, notice that you are using Value() instead of ToString() to read the string data? Same solution as above, ultimately.
  10. Remy Lebeau

    Install of RAD Studio, C++Builder 11.1.5

    I think they gave up on incremental updates. IIRC, everything in recent years has always required a full uninstall and reinstall.
  11. Remy Lebeau

    Best way to replace D11 distributed Indy with latest Git Indy?

    Yes, there are some Embarcadero technologies that use Indy internally, and so the installer has included Indy because of that. At one point, the techs were linked directly to the public version of Indy that shipped with the IDE, making it virtually impossible for users to update Indy without breaking those techs. But over the years, Embarcadero has updated their tech to use a private version of Indy instead (or their own libraries), so users can freely update the public version of Indy. But, there have been a few glitches in that process from time to time, causing unwanted linkages to the public Indy again. Nothing in recent years, that I recall, though.
  12. Remy Lebeau

    Best way to replace D11 distributed Indy with latest Git Indy?

    Essentially, yes - with caveats, depending on the IDE version (mostly old ones), which are documented in Indy's install instructions. I rename the pre-installed Indy folders and move the pre-installed Indy binaries to a separate folder (in case I ever need to restore them), and then I compile Indy in my own folder and install the binaries from there. That way, I can make changes to Indy and have them show up in projects/IDE. I install the IDE in the default installation path. Basically, yes. Some caveats similar to that are mentioned in Indy's install instructions, but only in relation to Embarcadero's own technologies that use Indy internally. Yup. And you have to make sure you clean up ONLY the ones that relate to Indy, and not to someone else who might have also used the "Id" prefix (albeit rare)... Cool.
  13. Remy Lebeau

    Best way to replace D11 distributed Indy with latest Git Indy?

    No, it is not optional, it is always pre-installed. Some day, in the future, I would like to get Indy into GetIt (https://github.com/IndySockets/Indy/issues/134) and out of the installer.
  14. Remy Lebeau

    Insert picture in TRichEdit from code

    IRichEditOle is the correct way to insert pictures into a RichEdit. The code should have embedded the image's data directly into the RichEdit's content, not create a link to an external file that is launched separately. If you can wrap the image in an IDataObject instead of an IOleObject, then you might try using IRichEditOle.ImportDataObject() instead of IRichEditOle.InsertObject(). I think that approach should work, provided the generated RTF content is accurate. However, in Delphi 2009+, string is UnicodeString, so the BitmapToRTF() function would need to be changed to use AnsiString or TBytes internally when preparing the RTF, since RTF is an 8-bit format. And also, since the TStringStream used to stream the RTF into the RichEdit would be holding Unicode characters, you probably need to include the SF_UNICODE flag when sending the EM_STREAMIN message. Otherwise, use a TMemoryStream instead to hold 8bit data instead of 16bit data. Also, there are 2 memory leaks in that code's Button1Click() method, Unfortunately, there is no "elegant" way, since Microsoft does not provide an "easy" API to handle this task.
  15. That encoding is really meant as just a means of transporting streaming data for a single resource, rather than pushing individual pieces of data. The response would have to be using a media type where the receiver knows each chunk carries a new piece of data that replaces old data. I'm not aware of any standard media types that use chunked encoding in that manner. But custom media types certainly could, I suppose, as long as you are in control of both sender and receiver. Also, the chunked encoding is hop-to-hop, not end-to-end, so it is subject to interference by proxies.
  16. The FTP protocol spec does not allow the password (or the username, or the account) to be empty, it must have at least 1 character. It is generally not a good idea to simply migrate a project from one major IDE version to another. Migrations are not always smooth. It is usually better to just create a new project fresh in the new IDE and then add your existing source files to it as needed. Did you report that issue? I don't recall seeing anything about that recently.
  17. Those are certainly ways to handle server pushes, but there are also HTTP-based push models as well: multipart/x-mixed-replace (the original server push, dating all the way back to Netscape, and still supported by most browsers today). text/event-stream (built-in to HTML5). HTTP/2 (which Indy doesn't support at this time) has server pushing built-in at the protocol layer. etc...
  18. Yes, you are explicitly calling PassAsync() after UserAsync() is finished, regardless of its outcome. You need to pay attention the StatusCode of UserAsync() before calling PassAsync(), and make sure your password is not empty if the server requires one. No, I don't. You explicitly (and unconditionally) asked it to send a PASS command, but did not provide it with data to send. Throwing an error sounds logical to me. It is an input error on your part. All that would accomplish is to cause the server to return back a failure StatusCode, as the PASS command can't have an empty value. Well, that is your own fault, for not learning the FTP protocol before making use of it, and not having adequate error handling in your code. If you had been paying attention to the StatusCodes of your commands, you would not have been calling PassAsync() unnecessarily to begin with.
  19. Read RFC 959 Yes. I just checked ICS's latest code, and (while it is a bit difficult to follow) it does appear to send PASS after USER only if USER returns 331. So I don't know why your log shows PASS being sent, unless you are calling the client's Pass/Async() method yourself? It would help if you would show your actual code, and your setup of the client's properties.
  20. Did you make sure the rest of TComponentA's code is checking FComponentB for nil before accessing its members? It is hard to diagnose your problem without a complete example.
  21. Reply code 230 on the USER command means the user is fully logged in, so the PASS command should not have been sent at all. If the server had actually wanted a password, the USER command would have sent back a 331 reply code instead.
  22. Under most conditions, yes. I was thinking more along the lines of when server-side pushes are used and there are delays between events, or when a client asks to use HTTP keep-alives and there are delays between requests, etc. Things where the connection is left open but sitting idle for periods of time.
  23. Remy Lebeau

    Dynamic class member names

    And? What exactly about the names being viewable to humans is worrisome to your employer, exactly? It is not like users will be able to USE the displayed names to do anything malicious to your code, since the actual classes and fields are converted into memory addresses, function calls, etc during compiling. You are likely just viewing the RTTI or Debug info. What is the actual CONCERN, before you waste your time trying to IMPLEMENT something that, quite frankly, can and will be worked around by anyone who actually intends to be malicious?
  24. Makes me wonder now if I should add a NATKeepAlive property to TIdHTTP, similar to what TIdFTP has. I've opened a ticket for that: https://github.com/IndySockets/Indy/issues/413
  25. Remy Lebeau

    auto close or logout when no mouse activity

    That would happen only if you are interpreting the actual value of the DWORD. I would just use my own timestamp (that doesn't roll over) to keep track of when the DWORD changes value between successive calls to GetLastInputInfo(), regardless of its actual value, Even if the DWORD rolls over, it is still a change in value. Even the documentation says that the DWORD is "not guaranteed to be incremental".
×