Učenie vášho programu v Go, aby hovoril ako Chrome

Ak ste niekedy cestovali do zahraničia a objednali si kávu frázou, ktorá by sa objavila v učebnici, poznáte pohľad, ktorý vám barista venuje. Vaša gramatika je v poriadku. Každé slovo je v slovníku. A predsa sa v priebehu pol sekundy všetci v kaviarni dozvedia, že ste odniekiaľ zvonku.
Štandardný HTTP klient jazyka Go má trochu podobný problém. Je výborným predvoleným nástrojom: spoľahlivý, prehľadný a pripravený na vážnu prácu hneď po inštalácii. Keď však váš program kontaktuje server, nezameniteľne pôsobí ako program v jazyku Go. Vo väčšine prípadov to nikomu nevadí. Niektoré webové stránky, CDN siete a testovacie prostredia však pozorne sledujú, kto im klope na dvere, a správajú sa výrazne odlišne podľa toho, aký typ klienta si myslia, že s ním komunikujú.
Preto sme vytvorili gosuda.org/chromenet. Namiesto toho, aby sme štandardný klient jazyka Go učili ppôsobiť ako prijateľne vierohodný prehliadač, chromenet umožňuje programu v jazyku Go komunikovať s webom pomocou rovnakého sieťového jadra, aké používa Google Chrome, teda vlastného sieťového kódu projektu Chromium. Či už kontrolujete, ako vaše testovacie prostredia spracúvajú prenos z prehliadača, alebo komunikujete s webovou stránkou za náročnou CDN sieťou, komunikácia cez engine Chrome odstráni celú vrstvu nejasností.
Svoju aplikáciu nemusíte prepisovať, aby ste ju mohli používať. Vo vašom kóde funguje ako priama náhrada za http.Transport. Naďalej používate http.Client tak, ako ste zvyknutí, a chromenet zabezpečuje komunikáciu na pozadí.
Ak chcete vyskúšať najnovšie vydanie, nainštalujte ho pomocou go get:
1go get gosuda.org/chromenet@v0.2.10157081033800
Potom jeho transport odovzdajte svojmu klientovi:
1client := http.Client{
2 Transport: chromenet.NewTransport(chromenet.Options{}),
3}
Od tohto vydania prechádza celá škála moderného webového prenosu cez engine Chrome. Teraz pokrýva bežné webové požiadavky, WebSocket aj WebTransport. Predchádzajúce verzie správne spracúvali iba bežné požiadavky, zatiaľ čo WebSocket a WebTransport boli len náhradné riešenia. To znamenalo, že vaše úvodné pozdravenie pri vchode znelo ako Chrome, no ak ste prešli na iný typ komunikácie, vaša maskovacia vrstva sa mohla prezradiť. Toto vydanie tieto náhradné riešenia nahrádza skutočnou implementáciou.
Počkajte, ak používame vlastný sieťový kód projektu Chromium, znamená to, že váš tichý build v jazyku Go sa zmení na rozsiahly problém s C kompilátorom? Našťastie nie. Váš kód v jazyku Go zostáva čistým Go, bez cgo a bez potreby C kompilátora.
Namiesto vkladania kódu prehliadača priamo do vašej binárnej súčasti chromenet spúšťa engine ako malý samostatný program vedľa vášho programu v jazyku Go. Predstavte si to ako najatie plynulého miestneho tlmočníka, ktorý kráča vedľa vás, namiesto snahy prebudovať vaše vlastné hlasivky. Keďže engine beží v tomto samostatnom programe, pád v ňom nemôže zrútiť vašu službu.

Váš program v jazyku Go zostáva čistým Go, zatiaľ čo malý pomocný program prenáša prenos cez sieťový engine Chromium.
Na vašej pracovnej stanici ani na serveroch nie je potrebné nič ďalšie inštalovať. Binárne súbory enginu pre Linux, macOS a Windows, a to na architektúrach Intel/AMD aj ARM, sú priamo súčasťou modulu Go a pred spustením sa overujú.
Dodávanie binárnych súborov vo vnútri modulu prirodzene vyvoláva otázku pre každého, kto dbá na dôveryhodnosť, a chceli sme na ňu poskytnúť jednoznačnú odpoveď. Binárne súbory sa zostavujú reprodukovateľným spôsobom z konkrétneho vydania Chromium, v súčasnosti Chromium 157, takže ktokoľvek ich môže znovu zostaviť a získať presne rovnaké bajty, a každé vydanie je overené službou GitHub. Aby sme udržali krok so svetom prehliadačov bez manuálnej práce, plánovaná úloha sleduje stabilný kanál Chromium a automaticky aktualizuje verziu, keď vyjde nový Chrome.
Čo je uTLS?
Ak ste sa už niekedy pokúšali, aby klient v jazyku Go vyzeral ako prehliadač, pravdepodobne ste narazili na uTLS. Je to vydarené dielo: knižnica v jazyku Go, ktorá umožňuje prispôsobiť úplne prvú správu zabezpečeného spojenia tak, aby pripomínala Chrome, Firefox alebo ľubovoľný iný prehliadač. Je malá, je čisto v jazyku Go a vedľa vášho programu nebeží nič navyše.
Háčik spočíva v tom, ako ďaleko siaha ten kostým. uTLS pokrýva handshake, teda prvých pár slov konverzácie. Všetko ostatné musíte vytvoriť sami: vrstvu HTTP/2 treba zapojiť a ručne doladiť, HTTP/3 je samostatné dobrodružstvo a WebSocket alebo WebTransport si vyžadujú ešte viac lepidla. Presety pre Chrome sú navyše kópie, takže ich niekto musí udržiavať aktuálne pri každej zmene návykov prehliadača. Je to trochu ako napodobniť prízvuk človeka, zatiaľ čo zvyšok jeho reči tela vás stále prezradí.
chromenet sa vydáva opačnou cestou. Chrome nenapodobňuje, ale žiada vlastný engine Chrome, aby sa postaral o komunikáciu, takže handshake, spôsob opätovného používania spojení, prechody medzi protokolmi aj prenosy pochádzajú z jedného miesta a menia sa spoločne, keď sa mení Chromium.
Tento kompromis je otvorene priznaný. uTLS je ľahšie a umožňuje vytvoriť akékoľvek pozdravenie, na ktoré si spomeniete, zatiaľ čo chromenet prináša pomocný program s veľkosťou 25 MB a poskytuje správanie Chrome namiesto vlastného. Ak chcete malú závislosť a úplnú kontrolu nad handshake, uTLS je stále výbornou voľbou.
Každý návrh má svoje kompromisy a chceme byť tu otvorení ohľadom limitov. Zabalenie skutočného sieťového enginu prehliadača nie je malé: každý binárny súbor enginu má približne 25 MB. Na macOS binárne súbory nie sú notarizované. A na Linuxe váš systém potrebuje glibc 2.31 alebo novšiu verziu. Ak tieto hranice vyhovujú vášmu prostrediu, získate skutočnú sieťovú komunikáciu Chrome výmenou jediného poľa transportu.
Projekt je dostupný na github.com/gosuda/chromenet. Ak poznáte jeho sesterské projekty v rodine open source projektov gosuda, gosuda.org/hqq a gosuda.org/sqlite3, ich duch vám bude povedome: prevziať schopné, ťažké nástroje zo širšieho sveta softvéru a spraviť z nich súčasť čistého jazyka Go.
Ak teda siahate po uTLS, pretože potrebujete, aby váš program v jazyku Go znel ako prehliadač, vyskúšajte chromenet. Môže byť dobrou alternatívou k uTLS, najmä keď potrebujete viac než požiadavky HTTPS: HTTP/2, HTTP/3, WebSocket aj WebTransport prechádzajú cez rovnaký engine Chrome bez potreby lepiaceho kódu na vašej strane.