Insegnare al Tuo Programma Go a Parlare come Chrome

Se hai mai viaggiato all'estero e ordinato un caffè con una frase da manuale, conosci lo sguardo che ti rivolge il barista. La tua grammatica è corretta. Ogni parola si trova nel dizionario. Eppure, nel giro di mezzo secondo, tutti nel caffè capiscono che vieni da fuori.
La client HTTP standard di Go soffre un po' dello stesso problema. È un'ottima impostazione predefinita: affidabile, pulita e pronta per un lavoro serio già al primo utilizzo. Quando però il tuo programma si connette a un server, appare inequivocabilmente come un programma Go. Nella maggior parte dei casi nessuno se ne preoccupa. Tuttavia, alcuni siti web, CDN e configurazioni di test prestano molta attenzione a chi bussa alla porta, e si comportano in modo sensibilmente diverso a seconda del tipo di client che ritengono di avere davanti.
Ecco perché abbiamo realizzato gosuda.org/chromenet. Invece di addestrare il client standard di Go a imitare passabilmente un browser, chromenet consente a un programma Go di comunicare con il web utilizzando lo stesso motore di rete di Google Chrome, cioè il codice di rete dello stesso Chromium. Che tu stia verificando il modo in cui le tue configurazioni di test trattano il traffico dei browser o che tu debba comunicare con un sito protetto da una CDN esigente, parlare attraverso il motore di Chrome elimina un intero livello di incertezza.
Non devi riscrivere la tua applicazione per usarlo. Nel tuo codice funziona come sostituto diretto (drop-in replacement) di http.Transport. Continui a usare http.Client come hai sempre fatto, e chromenet gestisce la comunicazione sottostante.
Per provare l'ultima versione, installala con go get:
1go get gosuda.org/chromenet@v0.2.10157081033800
Quindi assegna il suo transport al tuo client:
1client := http.Client{
2 Transport: chromenet.NewTransport(chromenet.Options{}),
3}
Con questa release, l'intera gamma del traffico web moderno passa attraverso il motore di Chrome. Ora copre le normali richieste web, WebSocket e WebTransport. Le versioni precedenti gestivano correttamente solo le richieste ordinarie, mentre WebSocket e WebTransport erano soluzioni provvisorie. Ciò significava che il tuo saluto iniziale alla porta suonava come Chrome, ma se passavi a un diverso tipo di conversazione, la tua copertura poteva saltare. Questa release sostituisce quelle soluzioni provvisorie con la versione reale.
Ma se usiamo il codice di rete di Chromium, significa che la tua tranquilla build Go si trasforma in un'intricata questione di compilatori C? Per fortuna no. Il tuo codice Go resta Go puro, senza cgo e senza bisogno di un compilatore C.
Invece di integrare il codice del browser direttamente nel tuo binario, chromenet esegue il motore come un piccolo programma separato accanto al tuo programma Go. Immagina di assumere un interprete locale madrelingua che ti accompagna, anziché tentare di ricostruire le tue corde vocali. Poiché il motore viene eseguito in quel programma separato, un arresto anomalo al suo interno non può far crollare il tuo servizio.

Il tuo programma Go resta Go puro, mentre un piccolo programma companion gestisce il traffico attraverso il motore di rete di Chromium.
Non c'è nulla di aggiuntivo da installare sulla tua postazione di lavoro o sui tuoi server. I binari del motore per Linux, macOS e Windows, su architetture Intel/AMD e ARM, sono inclusi direttamente nel modulo Go e vengono verificati prima dell'esecuzione.
Includere dei binari all'interno di un modulo solleva comprensibilmente una domanda per chiunque si occupi di affidabilità, e abbiamo voluto offrire una risposta semplice. I binari sono costruiti in modo riproducibile a partire da una specifica release di Chromium, attualmente Chromium 157, pertanto chiunque può ricostruirli e ottenere esattamente gli stessi byte, e ogni release è certificata da GitHub. Per tenere il passo con il mondo dei browser senza interventi manuali, un job pianificato segue il canale stable di Chromium e aggiorna automaticamente la versione quando esce una nuova versione di Chrome.
E uTLS?
Se hai già provato a far sembrare un client Go un browser, probabilmente hai incontrato uTLS. È un lavoro pregevole: una libreria Go che ti permette di vestire il primissimo messaggio di una connessione sicura così da somigliare a Chrome, Firefox o a quello che preferisci. È piccola, è Go puro e nulla di aggiuntivo viene eseguito accanto al tuo programma.
Il limite sta nella portata del travestimento. uTLS copre l'handshake, cioè le prime battute della conversazione. Tutto il resto resta da costruire a tuo carico: il livello HTTP/2 va collegato e messo a punto a mano, HTTP/3 è un'avventura a parte, e WebSocket o WebTransport richiedono ancora più collante. Anche i preset di Chrome sono copie, quindi qualcuno deve tenerli aggiornati ogni volta che Chrome cambia abitudini. È un po' come imitare l'accento di una persona mentre il resto del suo linguaggio del corpo continua a tradirla.
chromenet segue la strada opposta. Non imita Chrome: chiede al motore di Chrome stesso di parlare, quindi l'handshake, il modo in cui le connessioni vengono riutilizzate, i passaggi di protocollo e i trasporti provengono tutti da un'unica fonte e si aggiornano insieme quando si aggiorna Chromium.
Il compromesso è onesto. uTLS è più leggero e ti permette di costruire qualsiasi saluto tu possa immaginare, mentre chromenet porta con sé un helper da 25 MB e ti offre il comportamento di Chrome anziché uno personalizzato. Se desideri una dipendenza minima e il pieno controllo dell'handshake, uTLS resta un'ottima scelta.
Ogni progetto comporta dei compromessi, e vogliamo essere chiari sui limiti. Includere un vero motore di rete di un browser non è leggero: ciascun binario del motore pesa circa 25 MB. Su macOS, i binari non sono notarizzati. E su Linux, il sistema deve avere glibc 2.31 o successiva. Se questi vincoli sono compatibili con il tuo ambiente, ottieni il vero networking di Chrome semplicemente sostituendo un singolo campo transport.
Il progetto si trova all'indirizzo github.com/gosuda/chromenet. Se conosci i progetti affini della famiglia open source gosuda, gosuda.org/hqq e gosuda.org/sqlite3, lo spirito ti sarà familiare: prendere macchinari potenti e pesanti dal più ampio mondo del software e farli sentire a proprio agio in Go puro.
Quindi, se ricorri a uTLS perché il tuo programma Go deve sembrare un browser, prova chromenet. Può essere una buona alternativa a uTLS, soprattutto quando ti servono più delle semplici richieste HTTPS: HTTP/2, HTTP/3, WebSocket e WebTransport passano tutti attraverso lo stesso motore di Chrome, senza codice di collegamento da parte tua.