Go-programod megtanítása arra, hogy a Chrome módjára beszéljen

Ha valaha külföldön jártál, és egy tankönyvbe illő mondattal rendeltél kávét, ismered a baristától kapott pillantást. A nyelvtanod rendben van. Minden szó megtalálható a szótárban. Mégis, fél másodpercen belül mindenki a kávézóban tudja, hogy idegen vagy.
A Go szabványos HTTP-kliensének van ebből a problémából egy kicsit. Kiváló alapértelmezett megoldás: megbízható, tiszta, és azonnal használható komoly munkára is. Amikor azonban a programod szervert keres meg, egyértelműen Go programnak látszik. A legtöbbször ezzel senkinek sincs problémája. Ugyanakkor egyes weboldalak, CDN-ek és teszt-környezetek nagy figyelmet fordítanak arra, ki kopogtat az ajtajukon, és másként viselkednek aszerint, milyen típusú kliensnek vélik azt, amellyel kommunikálnak.
Ezért hoztuk létre a gosuda.org/chromenet csomagot. Ahelyett, hogy a Go szabványos kliensét arra tanítanánk, hogy elfogadhatóan utánozza a böngészőt, a chromenet lehetővé teszi, hogy a Go program ugyanazzal a hálózati motorral kommunikáljon a weben, amelyet a Google Chrome használ, vagyis a Chromium saját hálózati kódjával. Akár azt vizsgálod, hogyan kezelik a saját teszt-környezeteid a böngészőforgalmat, akár egy kényes CDN mögötti oldallal kommunikálsz, a Chrome motorján keresztül történő kapcsolattartás egy teljes réteg találgatást szüntet meg.
Nem kell átírnod az alkalmazásodat a használatához. A kódodban a http.Transport közvetlen helyettesítőjeként működik. Továbbra is úgy használod a http.Client típust, ahogy eddig is, a háttérben pedig a chromenet intézi a kommunikációt.
A legújabb kiadás kipróbálásához telepítsd a go get paranccsal:
1go get gosuda.org/chromenet@v0.2.10157081033800
Ezután add át a szállítási rétegét (transport) a klienprevious kliensednek:
1client := http.Client{
2 Transport: chromenet.NewTransport(chromenet.Options{}),
3}
Ezzel a kiadással a modern webforgalom teljes köre a Chrome motorján keresztül halad. Mostantól lefedi a hagyományos webes kéréseket, a WebSocketet és a WebTransportot is. A korábbi verziók csak a hagyományos kéréseket kezelték megfelelően, a WebSocket és a WebTransport pedig csak helyettesítő megoldás volt. Ez azt jelentette, hogy a kezdeti üdvözlésed a bejáratnál Chroménak hangzott, de ha másfajta beszélgetésre váltottál, az álcád könnyen lelepleződhetett. Ez a kiadás ezeket a helyettesítő megoldásokat valódi megvalósítással váltja fel.
Felmerülhet a kérdés: ha a Chromium saját hálózati kódját használjuk, akkor a csendes Go-buildből nem lesz-e óriási C-fordítóval kapcsolatos fejfájás? Szerencsére nem. A Go-kódod továbbra is tiszta Go marad, cgo és C-fordító nélkül.
A chromenet ahelyett, hogy a böngészőkódot közvetlenül a binárisba építené, a motort egy kis, külön programként futtatja a Go-program mellett. Gondolj úgy rá, mint egy folyékonyan beszélő helyi tolmácsra, aki melletted sétál, ahelyett, hogy a saját hangszálaid újjáépítésén fáradoznál. Mivel a motor egy külön programban fut, az abban bekövetkező összeomlás nem állíthatja le a szolgáltatásodat.

A Go-programod tiszta Go marad, miközben egy kis segédprogram a Chromium hálózati motorján keresztül továbbítja a forgalmat.
A munkaállomásodon és a szervereiden sincs semmi további telepítendő. A motor bináris fájljai Linuxhoz, macOS-hez és Windowshoz, Intel/AMD és ARM architektúrákra egyaránt, közvetlenül a Go-modulban érkeznek, és futtatás előtt ellenőrzésre kerülnek.
A binárisok modulon belüli szállítása érthetően felvet egy kérdést mindazokban, akiket a bizalom kérdése foglalkoztat, ezért egyszerű választ szerettünk volna adni. A binárisokat reprodukálható módon, egy meghatározott Chromium-kiadásból építjük, jelenleg a Chromium 157-ből, így bárki újraépítheti őket, és pontosan ugyanazokat a bájtokat kapja. Minden kiadást a GitHub is igazol. A böngészővilág követése kézi munka nélkül a következőképpen történik: egy ütemezett feladat követi a Chromium stabil csatornáját, és automatikusan frissíti a verziót, amint új Chrome-verzió jelenik meg.
Mi a helyzet az uTLS-sel?
Ha korábban próbáltad úgy megjeleníteni a Go-kliensedet, mintha böngésző lenne, valószínűleg találkoztál az uTLS csomaggal. Ez egy szép munka: olyan Go-könyvtár, amely lehetővé teszi, hogy egy biztonságos kapcsolat legelső üzenetét úgy öltöztesd fel, hogy az a Chrome-ra, a Firefoxra vagy bármi másra hasonlítson, amit választasz. Kicsi, tiszta Go-kód, és a programod mellett nem fut semmi extra.
A buktató az, hogy az öltözék meddig terjed. Az uTLS a kézfogást fedi le, vagyis a beszélgetés első néhány szavát. Minden, ami ezután következik, továbbra is a te feladatod: a HTTP/2 réteget kézzel kell bekötni és hangolni, a HTTP/3 egy külön kaland, a WebSocket vagy a WebTransport pedig még több ragasztókódot igényel. A Chrome-profilok ráadásul másolatok, így valakinek minden alkalommal frissítenie kell őket, amikor a Chrome megváltoztatja a szokásait. Ez kissé olyan, mintha valaki akcentusát utánoznánk, miközben a testbeszéde továbbra is elárul minket.
A chromenet az ellenkező utat járja. Nem utánozza a Chrome-ot, hanem arra kéri a Chrome saját motorját, hogy végezze el a kommunikációt. Így a kézfogás, a kapcsolatok újrahasznosításának módja, a protokollfrissítések és a szállítási rétegek mind egy helyről érkeznek, és együtt változnak, amikor a Chromium változik.
A kompromisszum őszinte. Az uTLS könnyebb, és lehetővé teszi, hogy bármilyen elképzelhető üdvözlést megalkoss, míg a chromenet egy 25 MB-os segédprogramot hoz magával, és a Chrome valódi viselkedését adja, nem egy egyéni változatot. Ha kis függőséget és a kézfogás teljes irányítását szeretnéd, az uTLS továbbra is kiváló választás.
Minden megoldásnak vannak kompromisszumai, és itt szeretnénk őszinték lenni a korlátokkal kapcsolatban. Egy valódi böngészőmotor beágyazása nem apró dolog: minden motorbináris körülbelül 25 MB. macOS-en a binárisok nincsenek notarizálva. Linuxon pedig a rendszerednek glibc 2.31-es vagy újabb verzióra van szüksége. Ha ezek a határok megfelelnek a te környezetednek, egyetlen transport mező cseréjével valódi Chrome-hálózatkezelést kapsz.
A projekt a github.com/gosuda/chromenet címen érhető el. Ha ismered a gosuda nyílt forráskódú családjának testvérprojektjeit, a gosuda.org/hqq és a gosuda.org/sqlite3 csomagokat, a szellemiség ismerősnek fog tűnni: a szélesebb szoftvervilág képes, nehéz gépezeteit úgy vesszük át, hogy azok otthonosan érezzék magukat a sima Go-ban.
Tehát ha az uTLS-hez nyúlsz, mert azt szeretnéd, hogy a Go-programod böngészőnek hangozzon, próbáld ki a chromenet csomagot. Jó alternatíva lehet az uTLS helyett, különösen akkor, ha a HTTPS-kéréseknél többre van szükséged: a HTTP/2, a HTTP/3, a WebSocket és a WebTransport mind ugyanazon a Chrome-motoron keresztül haladnak, és nincs szükség ragasztókódra a te oldaladon.