It had been a while since I had an intense coding session with Elixir and Phoenix. And I don't recall having one since my last browser switch (I migrated from LibreWolf to Waterfox, both based on Firefox). I was working with Phoenix Channels, and therefore with WebSockets, but a problem kept occurring that, no matter how much I debugged, persisted.
The problem #
The problem I initially observed was a series of failures that randomly caused the WebSocket connection to end with a timeout. Some of those errors, in the browser console, were:
phx-GJlWIewGaCNw6wDF error: unable to join - Object { reason: "timeout" }.phx-GJlWXHagRCy4SQzh join: encountered 0 consecutive reloads - undefined
I started going over everything, trying to understand why this was happening, whether I had really done something unusual with the Channels. But well, after so long without touching them, one can always miss a small piece.
But it turned out that the problem was elsewhere, because while reviewing the logs in iex I noticed two important things:
- No client was connecting via WebSockets.
- Every time I started and connected one, it was connecting using
:longpoll.
Why?
The cause #
After much digging into why they were connecting using :longpoll, I decided to try with Chromium (thinking about it now, I should have done it sooner). And voila! Everything worked perfectly! I opened the browser console and not a single issue. What had happened?
All this development was local, the most traditional thing in the world: http://localhost:xxxx. No security, because I don't need it right now.
So, answering the previous question: Firefox-based browsers have a configuration key called network.websocket.allowInsecureFromHTTPS, which of course, as it should be, is disabled by default.
I must admit this also raises some questions for me:
network.websocket.allowInsecureFromHTTPSis not documented anywhere and it would be good to document this kind of configuration keys.- Since there is no documentation, I must infer what I can from the key itself: does it allow insecure WebSocket connections... from HTTPS?
- But if I enable it, the problem is fixed. The thing is, on localhost I'm not using HTTPS, but HTTP.
- So, as a conclusion, I understand that enabling this key allows any
ws://connection from HTTP or HTTPS.
The solution #
The solution, for this specific case, is to enable network.websocket.allowInsecureFromHTTPS in Waterfox. I emphasize: temporary solution.
The long-term solution would be to avoid having to enable that setting. But that is a topic for another post, if anything.
But why did Chromium allow me that insecure connection? It could be that, due to programming with Flutter for some web project, I configured Chromium to always start with --allow-running-insecure-content. If that's the case, I'll have to look into it, because if even from the terminal it runs with that flag, I'm not too comfortable having it so easy to use. I'm noting this down as a topic to investigate.
Note: it is also possible that I'm missing some aspect of the Phoenix and Channels configuration. If anyone reading this thinks so, please don't hesitate to let me know! I'd be immensely grateful.