hoaproject / Websocket

The Hoa\Websocket library.
https://hoa-project.net/
423 stars 75 forks source link

Only one char read to buffer on secure connection #89

Open avo7 opened 7 years ago

avo7 commented 7 years ago

Hi.

I've got a websocket server and I connect to it both with a PHP client and a browser JS client. On localhost, with unsecure connection it works fine. On production however, where wss:// is used, the PHP client can talk to the server normally, the browser client however encounters "Connection closed before receiving a handshake response".

I dug a bit into it, and found out, that the request from the PHP client looks like this:

GET /{accessToken} HTTP/1.1\r\n
Host: {host.com}\r\n
User-Agent: Hoa\r\n
Upgrade: WebSocket\r\n
Connection: Upgrade\r\n
Pragma: no-cache\r\n
Cache-Control: no-cache\r\n
Sec-WebSocket-Key: {key}==\r\n
Sec-WebSocket-Version: 13\r\n
\r\n

The request from the browser looks like this

G

But if I read from the buffer again (after https://github.com/hoaproject/Websocket/blob/master/Server.php#L98), I'm getting all the rest: ET /{accessToken} ...

I did an ugly hotfix in my project. I extended the Server class and added in doHandshake:

    $buffer = $connection->read(2048);
    if ($buffer === 'G') {
        $buffer .= $connection->read(2048);
    }
    $request = $this->getRequest();
    $request->parse($buffer);

And this way it works. But I have no idea, what the underlying issue is.

Hywan commented 7 years ago

Hello 😄,

I guess @Pierozi can help you. However, can you give us the code of your server please?

avo7 commented 7 years ago

@Hywan https://gitlab.com/Avris/Dibsy/tree/master/app/Service/Socket

Pierozi commented 7 years ago

Hello @avo7 Thanks for this report, this issue is related to #77 It's good you came with fresh information.

Can you share with us your HTML Client snippet ? You can find my test here : https://github.com/Pierozi/Websocket/blob/snippet/tls/snippet/client.html

Interesting your patch with $buffer === 'G' because in my all test, i've endup with empty string, not G The problem is clearly in the SSL handshake but I've still not find the cause.

Best Practice advice

You should prefer deal the encryption between the client and a loadbalancer / webserver proxy because you will be able to have better control of the stream and deal with high availability. In this case only the part between client and proxy are encrypted, then proxy to your server are in non encrypted mode, as this should be done in private subnet where you have high trust.

avo7 commented 7 years ago

Hi. The browser client code is here: https://gitlab.com/Avris/Dibsy/blob/master/app/Asset/coffee/modules/project.coffee

Good luck with finding the cause :)

Hywan commented 7 years ago

@Pierozi Any idea on this one?