GoSuda

Predarea programului tău Go să vorbească precum Chrome

By Lemon Mint views ...

Dacă ați călătorit vreodată în străinătate și ați comandat o cafea folosind o formulă perfectă din manualul de limbă, cunoașteți privirea pe care o aruncă barista. Gramatica dumneavoastră este corectă. Fiecare cuvânt se află în dicționar. Și totuși, în mai puțin de o jumătate de secundă, toți cei din cafenea își dau seama că sunteți străin.

Clientul HTTP standard din Go are puțin din această problemă. Este o alegere implicită excelentă: fiabil, curat și pregătit pentru lucru serios chiar din prima clipă. Atunci când programul dumneavoastră se conectează la un server, însă, el se recunoaște fără îndoială ca fiind un program Go. În majoritatea cazurilor, nimeni nu se deranjează. Totuși, unele site-uri web, rețele de distribuție a conținutului (CDN) și configurații de testare acordă o atenție deosebită celui care bate la ușă și se comportă destul de diferit în funcție de tipul de client pe care cred că îl au în față.

Din acest motiv am construit gosuda.org/chromenet. În loc să antrenăm clientul standard Go să imite acceptabil un browser, chromenet permite unui program Go să comunice cu web-ul folosind același motor de rețea pe care îl utilizează Google Chrome, adică propriul cod de rețea al Chromium. Fie că verificați modul în care configurațiile de testare tratează traficul generat de browser, fie că comunicați cu un site protejat de un CDN exigent, comunicarea prin motorul Chrome elimină un întreg strat de incertitudine.

Nu trebuie să vă rescrieți aplicația pentru a o utiliza. În codul dumneavoastră, aceasta funcționează ca înlocuitor direct al lui http.Transport. Continuați să folosiți http.Client așa cum ați făcut dintotdeauna, iar chromenet se ocupă de comunicarea din spate.

Pentru a încerca cea mai recentă versiune, instalați-o cu go get:

1go get gosuda.org/chromenet@v0.2.10157081033800

Apoi, atribuiți transportul acesteia clientului dumneavoastră:

1client := http.Client{
2	Transport: chromenet.NewTransport(chromenet.Options{}),
3}

Odată cu această versiune, întreaga gamă de trafic web modern trece prin motorul Chrome. Acesta acoperă acum cererile web obișnuite, WebSocket și WebTransport. Versiunile anterioare tratau corect doar cererile obișnuite, în timp ce WebSocket și WebTransport erau înlocuiri provizorii. Aceasta însemna că salutul inițial de la intrare suna ca Chrome, dar, dacă treceați la un alt tip de comunicare, acoperirea putea să se destrame. Această versiune înlocuiește aceste soluții provizorii cu implementarea reală.

Stați puțin: dacă folosim codul de rețea propriu al Chromium, înseamnă că build-ul dumneavoastră Go liniștit se transformă într-o mare bătaie de cap cu compilatorul C? Din fericire, nu. Codul dumneavoastră Go rămâne Go obișnuit, fără cgo și fără a fi nevoie de un compilator C.

În loc să integreze codul browserului direct în executabil, chromenet rulează motorul ca un program separat, mic, alături de programul dumneavoastră Go. Gândiți-vă la el ca la un interpret local, vorbitor fluent, care merge alături de dumneavoastră, în loc să încercați să vă reconstruiți propriile corzi vocale. Deoarece motorul rulează în acest program separat, o eroare apărută în interiorul lui nu poate doborî serviciul dumneavoastră.

Cum funcționează chromenet: programul dumneavoastră Go solicită un mic program companion, care rulează motorul de rețea Chromium și comunică cu web-ul

Programul dumneavoastră Go rămâne Go obișnuit, în timp ce un mic program companion transmite traficul prin motorul de rețea Chromium.

Nu este nevoie de nimic suplimentar de instalat nici pe stația de lucru, nici pe serverele dumneavoastră. Binarele motorului pentru Linux, macOS și Windows, atât pentru arhitecturile Intel/AMD, cât și pentru ARM, sunt incluse direct în modulul Go și sunt verificate înainte de a fi executate.

Includerea binarelor într-un modul ridică, pe bună dreptate, o întrebare pentru oricine se preocupă de încredere, iar noi am dorit să oferim un răspuns clar. Binarele sunt construite într-un mod reproductibil dintr-o versiune specifică de Chromium, în prezent Chromium 157, astfel încât oricine le poate reconstrui și obține exact aceiași octeți, iar fiecare versiune este atestată de GitHub. Pentru a ține pasul cu lumea browserelor fără intervenții manuale, o sarcină programată urmărește canalul stabil al Chromium și actualizează automat versiunea atunci când apare un nou Chrome.

Ce este uTLS?

Dacă ați încercat deja să faceți un client Go să arate ca un browser, probabil ați întâlnit uTLS. Este o lucrare remarcabilă: o bibliotecă Go care vă permite să îmbrăcați primul mesaj al unei conexiuni securizate astfel încât să semene cu Chrome, Firefox sau cu orice alt browser doriți. Este mică, este scrisă integral în Go și nimic suplimentar nu rulează alături de programul dumneavoastră.

Problema constă în cât de departe ajunge acest costum. uTLS acoperă handshake-ul, adică primele cuvinte ale conversației. Tot ceea ce urmează rămâne în sarcina dumneavoastră: stratul HTTP/2 trebuie configurat și ajustat manual, HTTP/3 reprezintă o aventură separată, iar WebSocket sau WebTransport necesită și mai multe adaptări. Profilurile Chrome sunt, de asemenea, copii, astfel încât cineva trebuie să le mențină actualizate de fiecare dată când Chrome își schimbă obiceiurile. Este asemenea unei persoane care își imită accentul, în timp ce restul limbajului corporal o trădează.

chromenet urmează calea opusă. Nu imită Chrome, ci cere motorului propriu al Chrome să realizeze comunicarea, astfel încât handshake-ul, modul în care conexiunile sunt reutilizate, trecerile la alte protocoale și transporturile provin toate dintr-un singur loc și evoluează împreună atunci când evoluează Chromium.

Compromisul este onest. uTLS este mai ușor și vă permite să creați orice salut vă puteți imagina, în timp ce chromenet aduce un asistent de 25 MB și vă oferă comportamentul Chrome, nu unul personalizat. Dacă doriți o dependență minimă și control deplin asupra handshake-ului, uTLS rămâne o alegere excelentă.

Orice design implică compromisuri, iar aici dorim să fim direcți în privința limitelor. Includerea unui motor real de rețea de browser nu este ceva mic: fiecare binar al motorului are aproximativ 25 MB. Pe macOS, binarele nu sunt notarizate. Iar pe Linux, sistemul dumneavoastră trebuie să aibă glibc 2.31 sau o versiune mai nouă. Dacă aceste limite se potrivesc configurației dumneavoastră, obțineți networking real Chrome prin simpla înlocuire a unui singur câmp de transport.

Proiectul se află la adresa github.com/gosuda/chromenet. Dacă cunoașteți proiectele surori din familia open source gosuda, gosuda.org/hqq și gosuda.org/sqlite3, spiritul va părea familiar: luarea unor instrumente puternice și grele din lumea largă a software-ului și transformarea lor într-un mediu prietenos în Go obișnuit.

Așadar, dacă apelați la uTLS pentru că aveți nevoie ca programul dumneavoastră Go să sune ca un browser, încercați chromenet. Poate fi o alternativă bună la uTLS, mai ales atunci când aveți nevoie de mai mult decât cereri HTTPS: HTTP/2, HTTP/3, WebSocket și WebTransport trec toate prin același motor Chrome, fără cod de legătură din partea dumneavoastră.