
Transcription en direct quand le pare-feu bloque les WebSockets
Les réseaux d'entreprise adorent autoriser HTTPS et tuer discrètement les upgrades WebSocket. Cela casse silencieusement la transcription en temps réel. GeekBye v2.0.8 bascule automatiquement sur un transport tout-HTTPS — et le livrer a révélé un bug qui aurait rendu toute la fonctionnalité inutile.
Il existe une façon précise et exaspérante pour la transcription en temps réel d'échouer sur un réseau d'entreprise. Votre Wi-Fi va bien. HTTPS marche — vous pouvez charger n'importe quel site. Mais la transcription en direct, tout simplement... ne démarre pas, et rien ne vous dit pourquoi.
Le coupable est une catégorie de proxy d'entreprise qui autorise le trafic HTTPS ordinaire mais bloque l'upgrade WebSocket — le handshake qui transforme une connexion HTTPS en le canal persistant et bidirectionnel dont la transcription en temps réel a besoin. Pour le proxy, un WebSocket ressemble à un tunnel non surveillé vers l'extérieur du réseau, alors il le tue. Pour vous, la transcription est cassée en silence.
GeekBye v2.0.8 a ajouté un repli automatique pour exactement ça — et le construire a fait remonter un bug qui aurait fait que toute la fonctionnalité ne fasse rien.
Pourquoi un repli, et pas juste une nouvelle tentative
On gère déjà les réseaux capricieux. Si votre connexion tombe en pleine session, GeekBye se reconnecte avec backoff et met votre audio en tampon pour que rien ne soit perdu — c'est une fonctionnalité distincte, traitée dans pourquoi votre notetaker IA s'arrête sur un mauvais Wi-Fi.
Mais un WebSocket bloqué n'est pas une connexion capricieuse. Réessayer le même WebSocket contre un proxy qui refuse les WebSockets échoue de la même façon à chaque fois, indéfiniment. Le seul correctif est un transport différent — un qui ressemble au HTTPS ordinaire que le proxy autorise déjà.
Donc v2.0.8 bascule sur un transport tout-HTTPS sur le même endpoint authentifié :
- En descente (les transcriptions qui vous reviennent) : server-sent events — une réponse HTTPS de longue durée que le proxy voit comme un téléchargement en streaming ordinaire.
- En montée (votre audio qui part) : des requêtes POST par lots, chacune portant un fragment d'audio avec un numéro de séquence pour que le serveur puisse les réassembler dans l'ordre même si le réseau les réordonne.
Pas de socket persistant, rien qui ressemble à un tunnel — juste des requêtes et des réponses HTTPS. Si un proxy vous laisse utiliser un site web, il laisse passer ça.
Le bug qui aurait livré une fonctionnalité morte
Voici la partie qui vaut la lecture. Le repli est censé se déclencher quand la connexion WebSocket épuise ses tentatives avec une signature de transport bloqué — chaque tentative échouant sur l'upgrade, aucun problème d'auth ni de quota, au moins un rejet en forme de proxy. Un proxy qui bloque un WebSocket répond typiquement à l'upgrade par un HTTP 403 Forbidden ou 407.
Le problème : notre code de connexion avait déjà une règle selon laquelle un 403 signifie erreur fatale d'authentification — arrête, remonte-la à l'utilisateur, ne réessaie pas. Ce qui est correct presque partout. Mais cela signifiait que le 403 d'un proxy bloquant — le signal exact qui aurait dû déclencher le repli — était plutôt levé comme erreur fatale avant même que la logique de repli ne puisse s'exécuter. Seule une coupure brute de connexion (une fermeture 1006) tombait jusqu'au repli. Donc la fonctionnalité aurait marché pour le cas rare et échoué en silence pour sa vraie cible principale : le proxy d'entreprise.
On a attrapé ça pendant le durcissement de la version, pas en production. Le correctif : un 403/407 sur l'étape de l'upgrade WebSocket est désormais traité comme récupérable pour que la boucle de connexion puisse s'épuiser vers le repli — tandis qu'un vrai échec d'authentification (qui arrive autrement, après la réussite de l'upgrade) échoue toujours vite, exactement comme avant. Un test de régression fige maintenant la distinction : un 403 de proxy bloquant doit basculer sur le repli ; un vrai 403 d'auth ne doit pas.
Le reste du durcissement a suivi la même ligne paranoïaque : un timeout sur chaque POST de montée pour qu'un proxy qui accepte une requête mais ne répond jamais ne puisse pas bloquer le flux audio, et une garantie qu'un vrai problème de connexion ne puisse jamais être masqué en silence par la machinerie de repli.
On l'a testé contre un vrai proxy hostile
Une fonctionnalité dont le but entier est de survivre à des réseaux hostiles ne peut pas être validée par des tests unitaires seuls — les tests unitaires n'ont pas de proxys. Avant de l'activer, on a fait passer l'app réelle par un reverse proxy local configuré pour faire exactement ce que font les proxys d'entreprise : relayer HTTPS, rejeter les upgrades WebSocket avec un 403.
La trace dans les logs est le reçu : quatre tentatives WebSocket bloquées, la signature d'épuisement reconnue, la bascule automatique vers le transport HTTPS, puis une session de transcription saine de 96 secondes sur HTTPS pur — 66 segments de transcription, zéro perte. Le failover marche parce qu'on l'a regardé basculer.
Trois leçons transposables
- « Ça marche sur un Wi-Fi capricieux » et « ça marche derrière un proxy hostile » sont des garanties différentes. L'une a besoin de reconnexion ; l'autre a besoin d'un transport différent. Les confondre laisse toute une population d'utilisateurs d'entreprise cassée en silence.
- Votre classification d'erreurs peut cacher votre propre fonctionnalité à elle-même. Une règle correcte 99 % du temps (403 = auth fatale) était exactement fausse pour le 1 % que cette fonctionnalité existait pour servir. Quand vous ajoutez un repli, auditez si la condition de déclenchement peut seulement atteindre le repli.
- Testez l'adversaire, pas juste le chemin heureux. Le seul test honnête de « survit à un proxy bloquant les WebSockets », c'est un proxy bloquant les WebSockets. On en a construit un.
GeekBye v2.0.8 a livré le repli HTTPS derrière un flag et validé. Pour le travail de fiabilité auquel il s'adosse, voyez pourquoi votre notetaker IA s'arrête sur un mauvais Wi-Fi, et pour les versions voisines de cette série, pourquoi votre notetaker IA arrête d'enregistrer en pleine réunion (v2.0.9) et pourquoi la transcription IA écorche les termes techniques (v2.0.11).