nicolasff / webdis

A Redis HTTP interface with JSON output
https://webd.is
BSD 2-Clause "Simplified" License
2.82k stars 307 forks source link

Websocket handshake failed #180

Open azertyBoy opened 3 years ago

azertyBoy commented 3 years ago

Hi,

I think I need some help to configure Webdis cause websocket connection doesn't working.

My webdis configuration :

{
    "redis_host":   "redis",
    "redis_port":   6379,
    "redis_auth":   null,

    "http_host":    "0.0.0.0",
    "http_port":    7379,
    "threads":  4,

    "daemonize": false,

    "database": 0,

    "acl": [
        {
            "enabled": ["SET", "DEBUG", "FLUSHDB", "FLUSHALL", "DEBUG"]
        },
        {
            "http_basic_auth":  "user:password",
            "enabled":      ["DEBUG"]
        }
    ],

    "verbosity": 5,
    "logfile": "/var/log/webdis/webdis.log"
}

When I use this piece of code (taken from documentation) I got error (below) :

<html>
  <head>

  </head>
  <body>
    <script>
      function testJSON() {
        var jsonSocket = new WebSocket("ws://127.0.0.1:7379/.json");
        jsonSocket.onopen = function() {

          console.log("JSON socket connected!");
          jsonSocket.send(JSON.stringify(["SET", "hello", "world"]));
          jsonSocket.send(JSON.stringify(["GET", "hello"]));
        };
        jsonSocket.onmessage = function(messageEvent) {
          console.log("JSON received:", messageEvent.data);
        };
      }
      testJSON();
    </script>
  </body>
</html>

And the error (on google chrome console log) :

test-webdis-websocket.html:5 WebSocket connection to 'ws://127.0.0.1:7379/.json' failed: Error during WebSocket handshake: Unexpected response code: 400

I tried to use nodejs websocket with this code :

const WebSocketClient = require('websocket').client;

const client = new WebSocketClient();

client.on('connectFailed', (error) => {
  console.error('Connection failed');
  console.error(error);
});

client.on('connect', (connection) => {
  console.log('Websocket client connected');
});

client.connect('ws://localhost:7379/');

And I got this error :

Connection failed
Error: Server responded with a non-101 status: 403 Forbidden
Response Headers Follow:
server: Webdis
allow: GET,POST,PUT,OPTIONS
access-control-allow-methods: GET,POST,PUT,OPTIONS
access-control-allow-origin: *
access-control-allow-headers: X-Requested-With, Content-Type, Authorization
connection: Keep-Alive
content-length: 0

    at WebSocketClient.failHandshake (/Users/PATH/TO/MY/SCRIPT_FOLDER/node_modules/websocket/lib/WebSocketClient.js:339:32)
    at ClientRequest.<anonymous> (/Users/PATH/TO/MY/SCRIPT_FOLDER/node_modules/websocket/lib/WebSocketClient.js:278:18)
    at ClientRequest.emit (events.js:198:13)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:565:21)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:111:17)
    at Socket.socketOnData (_http_client.js:451:20)
    at Socket.emit (events.js:198:13)
    at addChunk (_stream_readable.js:288:12)
    at readableAddChunk (_stream_readable.js:269:11)
    at Socket.Readable.push (_stream_readable.js:224:10)

Anyone know why my Websocket handshake failed ?

I seeing in my exemple 2 differents HTTP codes responses : 400 and 403. I got 403 when I use this URL / and I got 400 when I use /.json. It doesn't matter which client is used.

HTTP exemple method given in documentation works well (but I want websocket).

Best regards.

qume commented 3 years ago

Same issue here. Looks like it doesn't get all the way through to ws_execute (or the function before). I stopped tracing at that point. Using firefox on windows to webdis running on a linux host.

nicolasff commented 2 years ago

Sorry for the very late reply, hopefully this can help someone else. The 400s are because WebSocket support is disabled by default on Webdis due to the implementation not being complete and having known issues that can even lead to crashes. A large pull request with significant improvements was just merged (#199) and should make this support much better, but the new code still needs a bit more testing before it can be enabled by default.

To enable this feature, you need "websockets": true in your webdis.json, which I don't see in the post above.

For those who want to test WebSockets in a web browser, there is an updated version of the existing HTML test page in the tests directory. Just serve the file locally with python -m http.server 8000 (add --bind 127.0.0.1 if you're on Python 3.4 and above) and then navigate to http://127.0.0.1:8000/ and open websocket.html.

I'm hoping that these recent improvements and a few more that are already planned will make WebSocket support solid enough that it can be enabled by default in an upcoming release soon.