baka0815 12 Posted April 18 At first: I searched the forum but couldn't find a topic matching my case, however my search-fu might be lacking, so please send me to the right place, if this was asked before. Thanks! I'm using a TIdHTTPWebBrokerBridge to serve incoming connections and that works flawlessly, with and without TLS (<= 1.2). However, if TLS is activated, I want to force the usage of TLS. What I'm currently doing is to implement OnQuerySSLPort(APort: TIdPort; var VUseSSL: Boolean) ans set VUseSLL to True, so SSL/TLS is forced and connections without TLS are not possible. But when I try to connect to the server without TLS (http://localhost:8080) I'm getting (via Bruno) Error invoking remote method 'send-http-request': TypeError: Cannot read properties of undefined (reading 'data') or "connection reset" via Firefox. When debugging I see that an exception is raised in procedure TIdSSLSocket.Accept(const pHandle: TIdStackSocketHandle); EIdOSSLAcceptError.RaiseException(fSSL, error, RSSSLAcceptError); How am I supposed to implement a redirect to the correct HTTPS-URL (or raise an error that TLS is required or something along those lines=? Share this post Link to post
DelphiUdIT 178 Posted April 18 (edited) (This is for TIdHTTPServer component, hope to be useful for you component). You must use the "TIdSSLIOHandlerSocketBase.PassThrough" property ... if you set it to FALSE then TLS is required, if you set to TRUE only clear connection (NO TLS) are managed. Do it in the "create connection" event: procedure TForm1.Server1Connect(AContext: TIdContext); begin If AContext.Connection.IOHandler is TIdSSLIOHandlerSocketBase then TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough := false; //If True the authentication is not managed (only in clear text) or is used for STARTTLS, if false it manages the TLS/SSL authentication end; Edited April 18 by DelphiUdIT Share this post Link to post
baka0815 12 Posted April 18 (edited) That's exactly what I'm doing with the implementation of OnQuerySSLPort(). if AContext.Connection.IOHandler is TIdSSLIOHandlerSocketBase then begin TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough := not DoQuerySSLPort(AContext.Connection.Socket.Binding.Port); end; inherited DoConnect(AContext); This is the code where DoQuerySSLPort calls the event and sets it's Result to True, therefor setting PassThrough. When I then try to connect via http://... (as said earlier https:// works flawlessly!) the exception raised is error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number The log from Postman is just Error: socket hang up The reply from curl is * Trying [fe80::64b3:3bf5:dfb6:3b7c]:8080... * Connected to server (fe80::64b3:3bf5:dfb6:3b7c) port 8080 > GET / HTTP/1.1 > Host: server:8080 > User-Agent: curl/8.4.0 > Accept: */* > * Empty reply from server * Closing connection curl: (52) Empty reply from server But what I would like to get is either a redirect to https or at least deliver some error message to the client to know what's wrong. Edited April 18 by baka0815 Share this post Link to post
DelphiUdIT 178 Posted April 18 (edited) For me is working, but I have the github version of Indy (I don't think this change something). I think that the "socket" is still trying to use TLS for connection, but I'm not sure about that and I don't know how to help you. Look this article of @Remy Lebeau to redirect the connection from "http" to "https": https://www.atozed.com/forums/thread-367-post-834.html#pid834 Edited April 18 by DelphiUdIT Share this post Link to post
Remy Lebeau 1403 Posted April 18 13 hours ago, baka0815 said: What I'm currently doing is to implement OnQuerySSLPort(APort: TIdPort; var VUseSSL: Boolean) ans set VUseSLL to True, so SSL/TLS is forced and connections without TLS are not possible. That is not the correct way to handle this. 13 hours ago, baka0815 said: How am I supposed to implement a redirect to the correct HTTPS-URL (or raise an error that TLS is required or something along those lines=? You need to accept non-TLS connections on the HTTP port, and for any request that is received on that port, send an HTTP redirect response specifying the desired HTTPS port. That way, the client can then retry the same HTTP request on the HTTPS port using TLS. 9 hours ago, DelphiUdIT said: You must use the "TIdSSLIOHandlerSocketBase.PassThrough" property ... if you set it to FALSE then TLS is required, if you set to TRUE only clear connection (NO TLS) are managed. You don't need to handle that manually in TIdHTTPServer. Use the OnQuerySSLPort event instead, and let TIdHTTPServer handle the PassThrough for you. Any port that OnQuerySSLPort returns VUseSSL=True for will use PassThrough=False, and vice versa. 1 hour ago, DelphiUdIT said: Look this article of @Remy Lebeau to redirect the connection from "http" to "https": https://www.atozed.com/forums/thread-367-post-834.html#pid834 ☝️☝️☝️ This is the way! Share this post Link to post
baka0815 12 Posted April 22 Thank you both for the latest information, that looks promising! However I'm not using different ports, but maybe I will still figure something out. Share this post Link to post
DelphiUdIT 178 Posted April 22 40 minutes ago, baka0815 said: However I'm not using different ports, but maybe I will still figure something out. In the article that I signal in the last post there are also some suggestions to use only one port ... like you need. Share this post Link to post
Remy Lebeau 1403 Posted April 22 2 hours ago, baka0815 said: However I'm not using different ports, but maybe I will still figure something out. You should use different ports for HTTP and HTTPS. While it is technically possible to handle both HTTP and HTTPS on a single port, it requires extra coding to peek the raw TCP data before the HTTP server processes it. It is usually not worth the effort unless you are dealing with network restrictions. Share this post Link to post
baka0815 12 Posted April 23 In my case it's configurable what the port should be and if SSL/TLS is active for that port. Because of that I want to redirect incoming non-TLS requests to the TLS variant or at least send an error message that TLS is required. I'll take a look at the post later and come back if I have additional questions. Thank you! Share this post Link to post
baka0815 12 Posted April 23 I'm using a TIdHTTPWebBrokerBridge and therefore assigning OnCommandGet (via TIdHTTPWebBrokerBridgeAccess) or OnCommandOther didn't do anything, those events never happen. What works for me is assigning OnConnect as in the link posted and to check if it's a TLS handshake and therefore setting PassThrough. In the OnAction-event of the WebModule-Actions I then check if I wanted to have a TLS connection and return a 400 statuscode with a message that encryption is required. Is that a feasible way or am I holding it the wrong way up? Share this post Link to post