snapview / tokio-tungstenite

Future-based Tungstenite for Tokio. Lightweight stream-based WebSocket implementation
MIT License
1.88k stars 236 forks source link

"WebSocket protocol error: httparse error: invalid token" when connect from ngrok tcp tunnel. #319

Open Atlinx opened 10 months ago

Atlinx commented 10 months ago

When I tried using an ngrok tcp tunnel to point towards a tokio-tungstenite websocket server on my localhost, I get an "httparse error: invalid token" error. Does anyone know why this is happening?

daniel-abramov commented 10 months ago

Sounds like an invalid header line or something. This error originates from the httparse dependency that parses the HTTP. And here is the error, i.e. I think a simple example with httparse would fail for the same reason, so maybe you could check what you're getting from the server that makes it fail.

Atlinx commented 10 months ago

I've made a simple tcp server to listen for websocket connections, but the initial message sent to the server seems to be garbled.

Here's a request I got on this test TCP server via ngrok:

Opened connection from 127.0.0.1:64160
  Got string: ▬♥☺☻.☺☻*♥♥u�h��&�►�2�v51�↨��d:�♣0���◄ 0��x�R��Y�x� �↓/(�}S;?F'�������� ZZ‼☺‼☻‼♥�+�/�,�0̨̩�‼�¶��/5☺☺ ☺���Di♣♥☻h2↨‼◄0.tcp.ngrok.io#�☺☺-☻☺☺+♠JJ♥♦♥♥

[�7!�ۅ���+↓�W�h↓Х ,?���▼�♣5♥AB��v�A��↔l&↨↑H∟�d�@=m�)�fJ$v̜��FO��qČ�}z��݂�=)S��E����↕�0Ά���→:�↓���?s��G޺�G�W�R�nm[ [r�����:
�F���]0C��'q��d,�'�9����2��7}Q�#�__Q☺◄��o"&�1C�A�����<���f@�♠c��{♣w��Ft
↕►♦♦♦☺♣♣♣♠♠☺↕►
       http/1.1♥☻☻

☻☺J☺

Could this maybe have something to do with connecting with secure websockets (wss://) over ngrok?

daniel-abramov commented 10 months ago

This certainly depends on the configuration of the ngrok. I think without an additional configuration it would indeed expect non-encrypted traffic. So it depends on which endpoints you're exposing.

Atlinx commented 10 months ago

I'm running a tcp tunnel through ngrok without tls (using ngrok tcp 9000, however I have to connect to the tcp endpoint using wss:// because unsecure websockets are not allowed when content is loaded from secure sites. I think if I tried using an http tunnel ngrok should translate the encrypted traffic to unencrypted traffic. But I'll need to pass a header to bypass the browser warning.

agalakhov commented 10 months ago

The "Got string" message looks like TLS encryption. Can it be that the client expects unencrypted HTTP headers while the server sends encrypted ones? In this case you would get a httparse error message just like you actually got. How exactly do you connect?

physics515 commented 2 months ago

@Atlinx Any solution to this problem? I am implementing websockets between onion services using the new arti_client and I'm running into a similar issue.

I seem to bounce between the error you received and "WebSocket protocol error: httparse error: invalid HTTP version".

I think @agalakhov is right, the headers are being encrypted as part of the message, which is required because proxies must remove the Connection header per HTTP spec. Which is why ws:// connection are not possible through a proxy, only wss://.

Atlinx commented 2 months ago

I never figured out how to get ngrok to work, so I ended up using the rathole, which forwards traffic from a cloud server to my location machine. Hope that helps :)