As a follow-on to SSL and Delphi server I have another issue. I’m using the ROSuperHttpServer, loading the certificate in the OnBeforeServerActivate event. It works perfectly well, when I do it on my Mac (or any apple device it seems) using Chrome, but as soon as someone tries to use a browser on a PC or Android device, it times out.
After investigating, I can see that it spends a huge amount of time in TROSocketOpenSSL.Read, because the call to SSL_read comes back as -1which it can do for several minutes and at the same time locking up the server (CPU usage goes to 99%) so the browser will time out. If I run it from a Mac, it comes back first time with a positive value (817 if that means anything) so the logic below the if result>0 then break line never happens.
Any idea what may cause this, or more importantly what I can do to fix it?
The Chrome on the Mac is Version 103.0.5060.53, and the one on the PC I tried is Version 109.0.5414.120, although the same thing seems to happen to any of the PCs we’ve tried using Edge as well.
What certificate you are using? self-signed or issued by trusted CA?
Does your certificate contain Subject Alt Name property?
if you are using self-signed certificate, it may hang at validation such certificates.
I can recommend to install .1557 (should be available on this week) and retest after putting auto-generated CA to trusted store.
It is a trusted (Let’s Encrypt) one, and yes is has a Subject alt name property (two, including a wildcard one).
I’m trying to get a sample to replicate it using the mega demo, but have yet to replicate it exactly. I’m using the MegaClientJS for that.
I have found that it hangs my app, after the service call, and it’s trying to send the result. TROPooledThread.IntExecute is the point it stops (if fOwner.fSemaphore.WaitFor) whilst it waits for the socket to read the ssl.
I can, yes, I’ve been trying to track down which bit has the issue. I have modified the JS client for the mega demo, as attached, to include the option for SSL. MegaDemoJSClient.html.zip (1.9 KB)
(though my version has the localhost replaced with my domain version). One problem with no changes to the server other than adding the certificate load, is this, maybe you could see if you get the same?
Activate the Http Server (RO Socket), no SSL.
Connect (JSON), call sum, see result.
Deactivate server.
Tick SSL, and the server activate again.
Tick use SSL on client, connect, call sum, see result.
Deactivate server. Just hangs the server in TROSocketOpenSSL.Shutdown
If you then change to the super Http server, and repeat the above, it does connect (step 2 above) as I can see the server events (I’ve added logging on the TROSocketOpenSSL class so can see it checks if SSL is enabled) but then if I try any of the methods, it doesn’t seem to do anything.
I can reproduce this step. Looks like client-side doesn’t send close_notify shutdown alert as it should be according to /docs/man3.1/man3/SSL_shutdown.html
as a result, server-side sends close_notify shutdown alert to client in a loop
I’ve spotted the update and am just playing with it. There’s an issue in the mega demo client. The line fCurrentTargetUri.URI := cbTargetUrl.Text; is in the wrong place (it tries this before it’s created), I moved it after the fCurrentTargetUri := TROUri.Create; line.
If that’s an easy fix, let me know and I’ll try it out.
You may want to add the SSL option to the JS client sample as attached above as well, that’s what I’m about to test.
procedure TROSocketOpenSSL.Shutdown;
..
l_cnt: Integer;//<-----------------added
..
l_cnt := 0; //<-----------------added
repeat
..
if l_cnt < 10 then //<-----------------added
case SSL_get_error(fSSL, l_ret) of
SSL_ERROR_WANT_READ,
SSL_ERROR_WANT_WRITE,
SSL_ERROR_WANT_ASYNC,
SSL_ERROR_WANT_ASYNC_JOB: begin
inc(l_cnt); //<-----------------added
Continue; // We just do busy waiting. Nothing clever
end;
Thanks, yes that’s resolved that. I still have the original problem though. If I use the new self-certification stuff, it works great with the Delphi client as per the mega demo, but not with the JS client (it doesn’t accept the certificate - ERR_CERT_AUTHORITY_INVALID ).
Although in the browser, I can get past it to see as per:
I have tried my original certificate with the same result (running a client from chrome on a Mac works fine, but on windows or android, it locks the server as above).
OK, that does work on the mega demo and the JS client works with or without the SSL, but only on the Http Server, not the Super Http Server.
I have also done the same on my bespoke server, though I’m in a worse situation there really, as it now will only work if I add the CA on each computer I want someone testing. I could ask our testers to add this to their PCs for the moment, but it’s not going to work for production of course. The good news is the locking up for that slowness is resolved if I do add this CA file and run it on the PCs.
However, I’m now unclear how to load my original Let’s Encrypt file. If I turn off the four new OpenSSL Options, and load the certificate to CertFile as before, then nothing happens.
I have just tried this on my server on the PC that I noticed the original issue, and it works perfectly, without the slow speed. So, the question is, what is the solution for using another certificate (Let’s Encrypt in my case)?
With Indy, my certificate works fine with the both the mega demo Delphi client, and the JS client.
With WinHttp, it doesn’t even start, you can see this by just dropping one on a new form and trying to activate it at design time. Error is ‘uROHttpAPI: Access is denied’. This is Delphi XE8. I’ve never used one of those before so don’t know if it’s known, but it is repeatable on another Dephi XE8 pc. Also, not clear how to use the certificates (I see the isHttps property but that’s all).
I will now try my React JS client with the indy one.