Steven
Steven5 min di lettura

Trascrizione dal vivo quando il firewall blocca i WebSocket

Le reti aziendali adorano permettere HTTPS e uccidere in silenzio gli upgrade WebSocket. Questo rompe silenziosamente la trascrizione in tempo reale. GeekBye v2.0.8 ripiega automaticamente su un trasporto solo-HTTPS — e rilasciarlo ha scoperto un bug che avrebbe reso inutile l'intera funzionalità.

Trascrizione
Networking
Engineering
Release GeekBye
Trascrizione dal vivo quando il firewall blocca i WebSocket

C'è un modo specifico ed esasperante in cui la trascrizione in tempo reale fallisce su una rete aziendale. Il tuo Wi-Fi va bene. L'HTTPS funziona — puoi caricare qualsiasi sito. Ma la trascrizione dal vivo semplicemente... non parte, e nulla ti dice perché.

Il colpevole è una categoria di proxy aziendale che permette il traffico HTTPS normale ma blocca l'upgrade WebSocket — l'handshake che trasforma una connessione HTTPS nel canale persistente e bidirezionale di cui la trascrizione in tempo reale ha bisogno. Per il proxy, un WebSocket sembra un tunnel non sorvegliato verso l'esterno della rete, quindi lo uccide. Per te, la trascrizione è rotta in silenzio.

GeekBye v2.0.8 ha aggiunto un ripiego automatico proprio per questo — e costruirlo ha fatto emergere un bug che avrebbe fatto sì che l'intera funzionalità non facesse nulla.

Perché un ripiego, e non solo un nuovo tentativo

Gestiamo già le reti instabili. Se la tua connessione cade a metà sessione, GeekBye si riconnette con backoff e mette in buffer il tuo audio così nulla va perso — quella è una funzionalità separata, trattata in perché il tuo notetaker AI si ferma con un Wi-Fi scadente.

Ma un WebSocket bloccato non è una connessione instabile. Ritentare lo stesso WebSocket contro un proxy che rifiuta i WebSocket fallisce nello stesso modo ogni volta, per sempre. L'unica correzione è un trasporto diverso — uno che assomigli al semplice HTTPS che il proxy già permette.

Quindi la v2.0.8 ripiega su un trasporto solo-HTTPS sullo stesso endpoint autenticato:

  • In discesa (le trascrizioni che ti tornano): server-sent events — una risposta HTTPS di lunga durata che il proxy vede come un normale download in streaming.
  • In salita (il tuo audio in uscita): richieste POST in batch, ciascuna che porta un frammento di audio con un numero di sequenza così che il server possa riassemblarle in ordine anche se la rete le riordina.

Nessun socket persistente, nulla che sembri un tunnel — solo richieste e risposte HTTPS. Se un proxy ti lascia usare un sito web, lascia passare questo.

Il bug che avrebbe rilasciato una funzionalità morta

Ecco la parte che vale la lettura. Il ripiego dovrebbe attivarsi quando la connessione WebSocket esaurisce i suoi tentativi con una firma di trasporto bloccato — ogni tentativo che fallisce sull'upgrade, nessun problema di auth o di quota, almeno un rifiuto in forma di proxy. Un proxy che blocca un WebSocket risponde tipicamente all'upgrade con un HTTP 403 Forbidden o 407.

Il problema: il nostro codice di connessione aveva già una regola secondo cui un 403 significa errore fatale di autenticazione — fermati, mostralo all'utente, non ritentare. Il che è corretto quasi ovunque. Ma significava che il 403 di un proxy bloccante — il segnale esatto che avrebbe dovuto attivare il ripiego — veniva invece lanciato come errore fatale prima che la logica di ripiego potesse anche solo eseguirsi. Solo una caduta brusca di connessione (una chiusura 1006) arrivava fino al ripiego. Quindi la funzionalità avrebbe funzionato per il caso raro e fallito in silenzio per il suo vero bersaglio principale: il proxy aziendale.

Abbiamo colto questo mentre irrobustivamo la release, non in produzione. La correzione: un 403/407 sulla fase di upgrade del WebSocket è ora trattato come recuperabile così che il ciclo di connessione possa esaurirsi verso il ripiego — mentre un genuino fallimento di autenticazione (che arriva in modo diverso, dopo che l'upgrade è riuscito) fallisce ancora in fretta, esattamente come prima. Un test di regressione ora fissa la distinzione: un 403 da proxy bloccante deve ripiegare; un 403 di auth reale non deve.

Il resto dell'irrobustimento ha seguito la stessa linea paranoica: un timeout su ogni POST in salita così che un proxy che accetta una richiesta ma non risponde mai non possa bloccare il flusso audio, e una garanzia che un genuino problema di accesso non possa mai essere mascherato in silenzio dal meccanismo di ripiego.

L'abbiamo testato contro un vero proxy ostile

Una funzionalità il cui intero scopo è sopravvivere a reti ostili non può essere validata solo dagli unit test — gli unit test non hanno proxy. Prima di abilitarla, abbiamo fatto passare l'app reale attraverso un reverse proxy locale configurato per fare esattamente ciò che fanno i proxy aziendali: inoltrare HTTPS, rifiutare gli upgrade WebSocket con un 403.

La traccia nei log è la ricevuta: quattro tentativi WebSocket bloccati, la firma di esaurimento riconosciuta, il passaggio automatico al trasporto HTTPS, e poi una sana sessione di trascrizione di 96 secondi su HTTPS puro — 66 segmenti di trascrizione, zero perdite. Il failover funziona perché l'abbiamo visto fare failover.

Tre lezioni trasferibili

  1. "Funziona con un Wi-Fi instabile" e "funziona dietro un proxy ostile" sono garanzie diverse. Una ha bisogno di riconnessione; l'altra ha bisogno di un trasporto diverso. Confonderle lascia un'intera popolazione di utenti aziendali rotta in silenzio.
  2. La tua classificazione degli errori può nascondere la tua stessa funzionalità a sé stessa. Una regola corretta il 99% delle volte (403 = auth fatale) era esattamente sbagliata per l'1% che questa funzionalità esisteva per servire. Quando aggiungi un ripiego, verifica se la condizione che lo attiva può anche solo raggiungere il ripiego.
  3. Testa l'avversario, non solo il percorso felice. L'unico test onesto di "sopravvive a un proxy che blocca i WebSocket" è un proxy che blocca i WebSocket. Ne abbiamo costruito uno.

GeekBye v2.0.8 ha rilasciato il ripiego HTTPS protetto da flag e validato. Per il lavoro di affidabilità a cui si affianca, vedi perché il tuo notetaker AI si ferma con un Wi-Fi scadente, e per le release vicine di questa serie, perché il tuo notetaker AI smette di registrare a metà riunione (v2.0.9) e perché la trascrizione AI fraintende i termini tecnici (v2.0.11).