Discussion:
Shared TIdSchedulerOfThreadDefault
(too old to reply)
Melih OZAL
2008-06-12 22:47:33 UTC
Permalink
Hi,

I am using a shared TIdSchedulerOfThreadDefault for two of my HTTP and HTTPS
server.
Everything goes fine but when i try to Stop HTTPS server (Active := False)
all connections including HTTP server disconnected.
I just want to disconnect HTTPS server. Is there anyway for that or am i
doing something wrong....

Thanks,
Melih OZAL
Remy Lebeau (TeamB)
2008-06-12 23:30:44 UTC
Permalink
Post by Melih OZAL
I am using a shared TIdSchedulerOfThreadDefault
for two of my HTTP and HTTPS server.
You cannot do that. Schedulers are not sharable. Each server needs its own
individual Scheduler.
Post by Melih OZAL
Everything goes fine but when i try to Stop HTTPS server
(Active := False) all connections including HTTP server
disconnected.
It they should be. TIdTCPServer (which TIdHTTPServer derives from) loops
through all connections of the Scheduler that is assigned to it, because it
assumes that it is the only server attached to the Scheduler (and rightly
so, because that is how it is designed to work).

Rather than using two separate servers, why not just use one server? A
single server can handle both HTTP and HTTPS side-by-side, and you can
determine at run-time which port a client connected to if needed.
Post by Melih OZAL
I just want to disconnect HTTPS server.
Then you need to use a second Scheduler for the second server.
Post by Melih OZAL
am i doing something wrong....
Yes.


Gambit
Philip von Melle
2008-06-13 14:53:02 UTC
Permalink
Post by Remy Lebeau (TeamB)
Rather than using two separate servers, why not just use one server?
A single server can handle both HTTP and HTTPS side-by-side, and you
can determine at run-time which port a client connected to if needed.
I had tried to do that and read in another thread that in the OnConnect
event handler the IOHandler's PassThrough property needs to be set
accordingly. But this does not work.

Basically what I have done is create a TIdHPPTServer and
TIdServerIOHandlerSSLOpenSSL at design-time and set the servers
IOHandler property accordingly. Next I have created two bindings on
ports 80 and 443.

SSL works fine but non-SSL connections fail with the following
exception in the server: EIdOSSLAcceptError: Error accepting connection
with SSL. Then the client hangs (only to report Connection close
gracefully when shutting down the server)!

This happens even before I get a shot at the HTTP servers OnConnect
event handler to set the PassThrough property. This is because
PassThrough is set before in DoConnect() and this calls
OpenEncodedConnection() which fails in Accept().

So, any way to get thos to work? What am I doing wrong?

Regards, Philip


--


ELKNews FREE Edition - Empower your News Reader! http://www.atozedsoftware.com
Remy Lebeau (TeamB)
2008-06-13 17:09:37 UTC
Permalink
Post by Philip von Melle
Basically what I have done is create a TIdHPPTServer
and TIdServerIOHandlerSSLOpenSSL at design-time
and set the servers IOHandler property accordingly.
Next I have created two bindings on ports 80 and 443.
So far, so good.
Post by Philip von Melle
SSL works fine but non-SSL connections fail with the
Error accepting connection with SSL.
When using TIdServerIOHandlerSSLOpenSSL, PassThrough is set to True
initally, so all inbound connections are accepted by the server with SSL
disabled. The only way EIdOSSLAcceptError can be raised is when SSL is
activated for the connection when setting PassThrough to False later on.
Post by Philip von Melle
This happens even before I get a shot at the HTTP servers
OnConnect event handler to set the PassThrough property.
This is because PassThrough is set before in DoConnect()
That should be considered a bug then. DoConnect() should not be forcing SSL
on all connections unconditionally, for exactly this scenerio where a single
server uses both SSL and non-SSL ports together.
Post by Philip von Melle
So, any way to get thos to work?
Until an official fix can be implemented, you can derive a new component
from TIdHTTPServer and override DoConnect() to not set PassThrough to False
for connections on your non-SSL port.


Gambit
Philip von Melle
2008-06-14 16:55:23 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Philip von Melle
This happens even before I get a shot at the HTTP servers
OnConnect event handler to set the PassThrough property.
This is because PassThrough is set before in DoConnect()
That should be considered a bug then. DoConnect() should not be
forcing SSL on all connections unconditionally, for exactly this
scenerio where a single server uses both SSL and non-SSL ports
together.
It does, depending on the class of AContext.Connection.IOHandler:

procedure TIdCustomHTTPServer.DoConnect(AContext: TIdContext);
begin
if AContext.Connection.IOHandler is TIdSSLIOHandlerSocketBase then
begin
TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough:
=false;
end;
inherited DoConnect(AContext);
end;
Post by Remy Lebeau (TeamB)
Post by Philip von Melle
So, any way to get thos to work?
Until an official fix can be implemented, you can derive a new
component from TIdHTTPServer and override DoConnect() to not set
PassThrough to False for connections on your non-SSL port.
Deriving a class is difficult here because I would have to break
inheritance. Of course I can derive a class and override DoConnect() and
choose not to call inherited DoConnect(AContext), but then in order to be
able to use the OnConnect() event handler I would have to re-implement

if Assigned(OnConnect) then begin
OnConnect(AContext);
end;

For now, I have chosen to modify Indys source in order to not set
PassThrough unconditionally but set it depending on AContext.Binding.Port
(either 80 or 443) in OnConnect. This works fine and my server now
handles non-SSL and SSL connections equally well. I hope though, an
official fix will be available some time in the future.

BTW, when using SSL in the server I get a memory leak: 2 strings and 1
TIdSSLContext after the first SSL connection. But it does not increase
with more SSL connections luckily.

Regards, Philip
Remy Lebeau (TeamB)
2008-06-16 17:42:57 UTC
Permalink
I realize that. That is why I am considering it a bug - the code is
assuming that all connections will be all-SSL or all-plain, not mixed. That
needs to be addressed.
Post by Philip von Melle
Deriving a class is difficult here because I would have to break
inheritance.
No, you wouldn't. Why would you think that?
Post by Philip von Melle
Of course I can derive a class and override DoConnect() and choose
not to call inherited DoConnect(AContext), but then in order to be able
to use the OnConnect() event handler I would have to re-implement
if Assigned(OnConnect) then begin
OnConnect(AContext);
end;
That is a small thing to do, though.
Post by Philip von Melle
For now, I have chosen to modify Indys source in order to not set
PassThrough
unconditionally but set it depending on AContext.Binding.Port (either 80
or 443) in OnConnect.
That is the way to do it.
Post by Philip von Melle
BTW, when using SSL in the server I get a memory leak: 2 strings
and 1 TIdSSLContext after the first SSL connection.
That is a known problem in some versions. I think it has already been
fixed, but I am not sure.


Gambit

Loading...