2023.02.16 07:01 AM - edited 2023.02.16 09:43 AM
Hello there,
I am trying to connect to kdb process from C++ (using the Qt framework) using the very simple example provided by Qt for their QWebSocket class here: https://doc.qt.io/qt-6/echoclient.html
Unfortunately this doesn't work for me. The state moves instantly from 'ConnectingState' to 'UnconnectedState' with a close code of 1000. The kdb server, meanwhile, doesn't seem to register the connection at all (i.e. .z.wo isn't triggered).
As a sanity check, I ran a kdb process on the same host as the C++ process and was able to open the WebSocket fine with the usual command:
r:(`$":ws://host:port")"GET / HTTP/1.1\r\nHost: host:port\r\n\r\n"
Is it known if kdb WebSockets should work with a class such as Qt's QWebSockets? If not, is there anything in the kdb+ C API for usage with WebSockets?
Update: It seems the issue is because the kdb servier is password protected with -U/-u. This doesn't seem to pose an issue for kdb or JavaScript clients but the WebSocket connection from C++ client simply won't work as long as the server is password protected. Unfortunately, the server must be password protected so I'm unsure how we can work around this.
Thank you
2023.02.17 02:24 AM - edited 2023.02.17 02:26 AM
There should be no difference between opening a connection from different clients. Can you compare the HTTP output in both the working and non-working cases?
When using -u, HTTP connections must be authenticated using basic authentication. If you are connecting from a browser, this will result in a small popup window asking for a user name and password. If you are using a non-browser client, you must make sure to pass the "Authorization" header correctly. This also applies to JavaScript and kdb+ clients - if you didn't take care of passing the header, those should not be working either. (Although in the JavaScript case, if the JavaScript code is served by the same server as the one you are trying to connect to, you will have to have entered the user/password to fetch the JS so the credentials from there could get reused for the websocket connection).
2023.02.17 02:24 AM - edited 2023.02.17 02:26 AM
There should be no difference between opening a connection from different clients. Can you compare the HTTP output in both the working and non-working cases?
When using -u, HTTP connections must be authenticated using basic authentication. If you are connecting from a browser, this will result in a small popup window asking for a user name and password. If you are using a non-browser client, you must make sure to pass the "Authorization" header correctly. This also applies to JavaScript and kdb+ clients - if you didn't take care of passing the header, those should not be working either. (Although in the JavaScript case, if the JavaScript code is served by the same server as the one you are trying to connect to, you will have to have entered the user/password to fetch the JS so the credentials from there could get reused for the websocket connection).
2023.02.17 09:03 AM
Thank you very much for the help, Peter. The issue was indeed that I wasn't including the Authorization header with the connection.
Initially, I was trying to create my QWebSocket by providing the credentials in the URL like this
QWebSocket m_websocket = new QWebSocket();
m_websocket.open(QUrl(QStringLiteral("ws://user:pass@host:port")));
I didn't realise there is an option to use the open method with a QNetworkRequest which would allow me to add headers to the request. So I changed it to the below and it worked:
QWebSocket m_websocket = new QWebSocket();
QNetworkRequest req("ws://host:port");
req.setRawHeader("Authorization", "Basic <base64 encoded user:pass>");
m_webSocket.open(req);
Thank you very much again for your help.
EMEA
Tel: +44 (0)28 3025 2242
AMERICAS
Tel: +1 (212) 447 6700
APAC
Tel: +61 (0)2 9236 5700
KX. All Rights Reserved.
KX and kdb+ are registered trademarks of KX Systems, Inc., a subsidiary of FD Technologies plc.