Hello,
I'm trying to configure the most simple websocket client (with TSslWebSocketCli) and server (with TSslHttpAppSrv) in order to get them communicate with each other locally.
Worth noting that I'm a beginner in the internet communication protocol world, this is why I'm trying to get the minimum working and then I will build from that.
I'm using the ICS 9.0 C++ package, I believe I have a configuration problem more than a C++ problem.
For the client part, I configured the following (no TLS for now) :
client->SocketFamily = sfAnyIPv4;
client->DebugLevel = DebugHdr;
client->CertVerMethod = CertVerNone;
client->SslCliSecurity = sslCliSecDefault;
client->URL = "ws://127.0.0.1/";
client->WSPingSecs = 10;
event handlers to get something printed in the terminal :
client->OnHttpRestProg = HttpRestProg;
client->OnWSFrameRcvd = FrameRcvd;
client->OnWSConnected = Connected;
client->OnWSDisconnected = Disconnected;
For the server part, based on the Delphi samples OverbyteIcsBasicWebServer1.pas and OverbyteIcsSslMultiWebServ.pas, I configured :
server->AuthRealm = "ics";
server->SocketErrs = wsErrFriendly;
server->ExclusiveAddr = true;
server->SessionTimeout = 300;
server->MaxSessions = 100;
server->OnDisplay = Display;
server->SslEnable = false;
server->SslCliCertMethod = sslCliCertNone;
server->SslCertAutoOrder = false;
server->CertExpireDays = 30;
server->OcspSrvStapling = false;
server->AddGetAllowedPath("/", afBeginBy, "WEB-APP");
server->OnClientConnect = ClientConnect;
I added an host :
server->IcsHosts->Clear();
TIcsHost *host = new TIcsHost(server->IcsHosts);
host->HostEnabled = true;
host->HostNames->Text = "localhost";
host->HostTag = "WEB-APP";
host->Descr = "WebApp Server";
host->BindIpAddr = "127.0.0.1";
host->BindNonPort = 80;
host->BindSslPort = 0;
host->WebDefDoc = "index.html";
host->WebDocDir = dir + "data";
When the client is connecting (TSslWebSocketCli.WSConnect), OnClientConnect is triggered server side, then :
THttpWSSrvConn *conn = (THttpWSSrvConn *)Client;
conn->WSessionCookie = "OverbyteIcsWebAppServer" + server->Port;
conn->OnWSLogEvent = ClientLogEvent;
conn->OnWSHandshake = ClientHandShake;
conn->OnWSDisconnected = ClientDisconnected;
conn->OnWSFrameRcvd = ClientFrameRcvd;
conn->OnWSFrameSent = ClientFrameSent;
conn->OnWSReady = ClientReady;
conn->OnWSPingTimer = ClientPingTimer;
conn->OnBgException = ClientBgException;
Then the server handle the request (these are called : THttpConnection::ProcessRequest(), ::ProcessGet(), ::ProcessGetHeadDel(), ::SendDocument()...) and returns an "HTTP/1.1 200 OK" response to the client. From TSslWebSocketCli.WSConnect I get "WebSocket: Failed to Connect:" but the LastResponse string is empty. It looks like the server treats my websocket upgrade request as a "classic" request, so it returns an "HTTP/1.1 200 OK" response instead of the expected "HTTP/1.1 101 Switching Protocols". To make sure my client part was ok, I quickly tried it on a node.js websocket server, no problem, I get the "101 Switching Protocols" response and the websocket connection is established.
If I do not use TSslWebSocketCli.WSConnect but do a "manual" GET with an upgrade request header and on server side add an url handler (TUrlHandlerIndexHtml) and send a response header through AnswerStream, the connection is established. But if I send frames from the client, OnWSFrameRcvd is not triggred server side (as expected I believe since server has no clue I handled the upgrade "myself").
Hopefully this post makes sense, in short, I don't understand why my upgrade request on url: "ws://127.0.0.1/" fails on the ICS server, any help would be appreciated.
Thanks in advance.