Home > Mobile >  Are there SSL behaviour changes in Delphi 11?
Are there SSL behaviour changes in Delphi 11?

Time:04-19

For months, I have used the IdWebSocketSimpleClient unit with Delphi 10.3 provided here to setup a Websocket connection to the discord gateway API. Now, that I changed to Delphi 11, the same code shows another behaviour.

Previously, the component connected to the server, initiated an HTTP Upgrade to a websocket connection, received the 101 - switching protocols response and started to communicate. Now, with Delphi 11, I receive a 400 - Bad request. The inner error message shows "The plain HTTP request was sent to HTTPS port". In both scenarios, the same OpenSSL dll files are sitting in the applications executable folder and an TIdSSLIOHandlerSocketOpenSSL component is used.

At this point, I am really confused why this is happening, as the programs code hasn't been changed. This makes me wonder if there have been any behaviour changes to the indy units involved. I have no clue where to even start my investigation. Can someone help?

CodePudding user response:

Delphi 10.3 was released in late 2018. There was a change made to the TIdSSLIOHandlerSocketBase class in late 2019, to fix a bug where its PassThrough property was being initialized to False when it should have been initialized to True instead (which is now the current behavior).

So, that could easily account for the behavior you are seeing, as the error message is complaining about an unsecured HTTP message being sent to a secure HTTPS port (because PassThrough is likely True).

That change did not affect most Indy components, as internally they explicitly set PassThrough as needed (typically based on a UseTLS property, or a specific URL protocol/port being requested). But, the change does affect end-user code that uses TIdTCPClient directly (as this WebSocket code is doing). In that case, the user is (and always has been) responsible for setting PassThrough as they need, but this WebSocket code is not doing that. When connecting to a secure URL, it assumes that PassThrough has been set to False by the user before TIdSimpleWebSocketClient.Connect() is called, rather than forcing it to False. And PassThrough is certainly not being set to False if TIdSimpleWebSocketClient needs to auto-create its own SSLIOHandler object.

TIdSimpleWebSocketClient.Connect() should internally be setting PassThrough := not lSecure; before calling inherited Connect. I have reported this as a bug to the author for you:

#10: TIdSimpleWebSocketClient TLS error - 400 Bad request, the plain HTTP request was sent to HTTPS port

In the meantime, until the author fixes this bug, you can simply assign your own SSLIOHandler component to the TIdSimpleWebSocketClient.IOHandler property and set it to PassThrough=False before calling TIdSimpleWebSocketClient.Connect() with a wss: URL.

  • Related