forked from andremussche/DelphiWebsockets
-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
IdServerIOHandlerWebsocketSSL.pas
104 lines (92 loc) · 3.39 KB
/
IdServerIOHandlerWebsocketSSL.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
unit IdServerIOHandlerWebSocketSSL;
interface
uses
IdServerIOHandlerStack, IdIOHandlerWebSocketSSL, IdSocketHandle, IdThread,
IdYarn, IdIOHandler, IdWebSocketTypes, IdIOHandlerWebsocket, IdSSLOpenSSL,
IdSSL;
type
TIdServerIOHandlerWebSocketSSL = class(TIdServerIOHandlerSSLOpenSSL,
ISetWebSocketClosing)
protected
FOnWebSocketClosing: TOnWebSocketClosing;
procedure SetWebSocketClosing(const AValue: TOnWebSocketClosing);
public
procedure InitServerSettings(AIOHandler: TIdIOHandlerWebSocketSSL); overload;
public
function Accept(ASocket: TIdSocketHandle; AListenerThread: TIdThread;
AYarn: TIdYarn): TIdIOHandler; override;
function MakeClientIOHandler(ATheThread: TIdYarn): TIdIOHandler; override;
function MakeClientIOHandler: TIdSSLIOHandlerSocketBase; override;
end;
implementation
uses
System.SysUtils;
function TIdServerIOHandlerWebSocketSSL.Accept(ASocket: TIdSocketHandle;
AListenerThread: TIdThread; AYarn: TIdYarn): TIdIOHandler;
var
LIO: TIdIOHandlerWebSocketSSL;
begin
Assert(ASocket<>nil);
Assert(fSSLContext<>nil);
LIO := TIdIOHandlerWebSocketSSL.Create(Self);
InitServerSettings(LIO);
try
// LIO.PassThrough := True; // passthrough set in InitServerSettings
LIO.Open;
if LIO.Binding.Accept(ASocket.Handle) then begin
// we need to pass the SSLOptions for the socket from the server
LIO.SSLOptions.Free;
LIO.IsPeer := True;
LIO.SSLOptions := fxSSLOptions;
// LIO.SSLSocket.Free;
// LIO.SSLSocket := TIdSSLSocket.Create(Self);
LIO.SSLContext := fSSLContext;
// - Set up an additional SSL_CTX for each different certificate;
// - Add a servername callback to each SSL_CTX using SSL_CTX_set_tlsext_servername_callback();
// - In the callback, retrieve the client-supplied servername with
// SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name). Figure out the right
// SSL_CTX to go with that host name, then switch the SSL object to that
// SSL_CTX with SSL_set_SSL_CTX().
end else begin
FreeAndNil(LIO);
end;
except
LIO.Free;
raise;
end;
Result := LIO;
end;
procedure TIdServerIOHandlerWebSocketSSL.InitServerSettings(AIOHandler: TIdIOHandlerWebSocketSSL);
var
LSetWebSocketClosing: ISetWebSocketClosing;
begin
if AIOHandler <> nil then
begin
AIOHandler.RoleName := 'Server';
AIOHandler.IsServerSide := True; // server must not mask, only client
AIOHandler.UseNagle := False;
AIOHandler.PassThrough := True; // Don't use SSL for now...
// AIOHandler.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2]; // working
AIOHandler.SSLOptions.Method := sslvSSLv23;
AIOHandler.SSLOptions.Mode := sslmUnassigned;
// Do not set the VerifyMode!!!
if Supports(AIOHandler, ISetWebSocketClosing, LSetWebSocketClosing) then
LSetWebSocketClosing.SetWebSocketClosing(FOnWebSocketClosing);
end;
end;
function TIdServerIOHandlerWebSocketSSL.MakeClientIOHandler: TIdSSLIOHandlerSocketBase;
begin
Result := inherited;
end;
function TIdServerIOHandlerWebSocketSSL.MakeClientIOHandler(
ATheThread: TIdYarn): TIdIOHandler;
begin
Result := inherited MakeClientIOHandler(ATheThread);
InitServerSettings(Result as TIdIOHandlerWebSocketSSL);
end;
procedure TIdServerIOHandlerWebSocketSSL.SetWebSocketClosing(
const AValue: TOnWebSocketClosing);
begin
FOnWebSocketClosing := AValue;
end;
end.