Steven
Steven5 min läsning

Livetranskribering när brandväggen blockerar WebSockets

Företagsnätverk älskar att tillåta HTTPS och tyst döda WebSocket-uppgraderingen. Det bryter livetranskribering utan att märkas. GeekBye v2.0.8 faller automatiskt tillbaka på en ren HTTPS-transport — och att skeppa det avslöjade en bugg som hade gjort hela funktionen värdelös.

Transkribering
Nätverk
Utveckling
GeekBye-releaser
Livetranskribering när brandväggen blockerar WebSockets

Det finns ett specifikt, vansinnesframkallande sätt för livetranskribering att misslyckas på ett företagsnätverk. Din Wi-Fi är okej. HTTPS fungerar — du kan ladda vilken webbplats som helst. Men livetranskribering bara... startar inte, och ingenting berättar varför.

Boven är en klass av företagsproxyer som tillåter vanlig HTTPS-trafik men blockerar WebSocket-uppgraderingen — handskakningen som förvandlar en HTTPS-anslutning till den beständiga, tvåvägskanal som livetranskribering behöver. För proxyn ser en WebSocket ut som en oövervakad tunnel ut ur nätverket, så den dödar den. För dig är transkriberingen tyst trasig.

GeekBye v2.0.8 lade till en automatisk fallback för exakt detta — och att bygga den grävde fram en bugg som hade fått hela funktionen att inte göra någonting.

Varför en fallback, inte bara ett nytt försök

Vi hanterar redan ostabila nätverk. Om din anslutning bryts mitt i en session återansluter GeekBye med backoff och buffrar ditt ljud så att inget går förlorat — det är en separat funktion som täcks i varför ditt AI-anteckningsverktyg stannar på dålig Wi-Fi.

Men en blockerad WebSocket är inte en ostabil anslutning. Att försöka igen med samma WebSocket mot en proxy som vägrar WebSockets misslyckas på samma sätt varje gång, för evigt. Den enda lösningen är en annan transport — en som ser ut som den vanliga HTTPS som proxyn redan tillåter.

Så v2.0.8 faller tillbaka på en ren HTTPS-transport över samma autentiserade endpoint:

  • Nedåt (transkript som kommer tillbaka till dig): server-sent events — ett långlivat HTTPS-svar som proxyn ser som en vanlig strömmad nedladdning.
  • Uppåt (ditt ljud som går ut): buntade POST-förfrågningar, var och en bär ett ljudsegment med ett sekvensnummer så att servern kan sätta ihop dem i ordning även om nätverket ändrar ordningen.

Ingen beständig socket, inget som ser ut som en tunnel — bara HTTPS-förfrågningar och -svar. Om en proxy låter dig använda en webbplats låter den detta.

Buggen som hade skeppat en död funktion

Här är delen värd att läsa. Fallbacken ska utlösas när WebSocket-anslutningen förbrukar sina försök med en signatur för blockerad transport — varje försök misslyckas på uppgraderingen, inget autentiserings- eller kvotproblem, minst ett proxyformat avslag. En proxy som blockerar en WebSocket svarar typiskt på uppgraderingen med en HTTP 403 Forbidden eller 407.

Problemet: vår anslutningskod hade redan en regel om att en 403 betyder fatalt autentiseringsfel — stopp, visa det för användaren, försök inte igen. Vilket är korrekt nästan överallt. Men det innebar att 403:an från en blockerande proxy — exakt den signal som borde ha utlöst fallbacken — istället kastades som ett fatalt fel innan fallback-logiken någonsin kunde köra. Bara en rå anslutningsbrytning (en 1006-stängning) föll igenom till fallbacken. Så funktionen hade fungerat för det sällsynta fallet och tyst misslyckats för sitt faktiska primära mål: företagsproxyn.

Vi fångade detta medan vi härdade releasen, inte i produktion. Fixen: en 403/407 på WebSocket-uppgraderingsbenet behandlas nu som återhämtningsbart så att anslutningsloopen kan förbrukas ner i fallbacken — medan ett genuint autentiseringsfel (som kommer annorlunda, efter att uppgraderingen lyckats) fortfarande misslyckas snabbt, precis som förut. Ett regressionstest fäster nu skillnaden: en blockerad proxys 403 måste falla tillbaka; en verklig auth-403 får inte.

Resten av härdningen följde samma paranoida linje: en timeout på varje uppströms-POST så att en proxy som accepterar en förfrågan men aldrig svarar inte kan stanna av ljudströmmen, och en garanti att ett genuint inloggningsproblem aldrig tyst kan maskeras av fallback-maskineriet.

Vi testade det mot en verklig fientlig proxy

En funktion vars hela syfte är att överleva fientliga nätverk kan inte valideras enbart med enhetstester — enhetstester har inga proxyer. Innan vi aktiverade den körde vi den faktiska appen genom en lokal reverse proxy konfigurerad att göra exakt vad företagsproxyer gör: vidarebefordra HTTPS, avvisa WebSocket-uppgraderingar med en 403.

Spåret i loggarna är kvittot: fyra blockerade WebSocket-försök, den igenkända förbrukningssignaturen, det automatiska bytet till HTTPS-transporten, och sedan en frisk 96-sekunders transkriberingssession över ren HTTPS — 66 transkriptsegment, noll bortfall. Failovern fungerar för att vi såg den failova.

Tre överförbara lärdomar

  1. "Det fungerar på ostabil Wi-Fi" och "det fungerar bakom en fientlig proxy" är olika garantier. Den ena behöver återanslutning; den andra behöver en annan transport. Att blanda ihop dem lämnar en hel population av företagsanvändare tyst trasig.
  2. Din felklassificering kan dölja din egen funktion för sig själv. En regel som är korrekt 99 % av tiden (403 = fatal auth) var precis fel för de 1 % som denna funktion existerade för att betjäna. När du lägger till en fallback, granska om utlösningsvillkoret ens kan nå fallbacken.
  3. Testa motståndaren, inte bara den lyckliga vägen. Det enda ärliga testet av "överlever en WebSocket-blockerande proxy" är en WebSocket-blockerande proxy. Vi byggde en.

GeekBye v2.0.8 skeppade HTTPS-fallbacken flaggstyrd och validerad. För tillförlitlighetsarbetet den står bredvid, se varför ditt AI-anteckningsverktyg stannar på dålig Wi-Fi, och för de närliggande releaserna i den här serien, varför din AI-anteckningsapp slutar spela in mitt i mötet (v2.0.9) och varför AI-transkribering hör fel på tekniska termer (v2.0.11).