Enseñando a tu programa en Go a hablar como Chrome

Si alguna vez has viajado al extranjero y has pedido un café con una frase de manual perfecta, conoces la mirada que te dirige el barista. Tu gramática es correcta. Cada palabra está en el diccionario. Y, sin embargo, en medio segundo, todos en la cafetería saben que vienes de otra ciudad.
El cliente HTTP estándar de Go tiene un poco de ese problema. Es una excelente opción por defecto: fiable, limpio y listo para trabajos serios desde el primer momento. Sin embargo, cuando tu programa se comunica con un servidor, inevitablemente parece un programa en Go. La mayoría de las veces, a nadie le importa. Aun así, algunos sitios web, CDN y configuraciones de pruebas prestan mucha atención a quién llama a la puerta, y se comportan de forma bastante distinta según el tipo de cliente que creen tener delante.
Por eso creamos gosuda.org/chromenet. En lugar de entrenar al cliente estándar de Go para que imite de manera aceptable a un navegador, chromenet permite que un programa en Go se comunique con la web usando el mismo motor de red que utiliza Google Chrome, que es el propio código de red de Chromium. Ya sea que quieras comprobar cómo tus configuraciones de pruebas tratan el tráfico de navegadores o que necesites comunicarte con un sitio protegido por un CDN exigente, hablar a través del motor de Chrome elimina una capa completa de incertidumbre.
No es necesario reescribir tu aplicación para usarlo. En tu código, funciona como un reemplazo directo de http.Transport. Sigues usando http.Client como siempre, y chromenet se encarga de la comunicación por debajo.
Para probar la última versión, instálala con go get:
1go get gosuda.org/chromenet@v0.2.10157081033800
Luego, asigna su transporte a tu cliente:
1client := http.Client{
2 Transport: chromenet.NewTransport(chromenet.Options{}),
3}
Con esta versión, todo el abanico del tráfico web moderno pasa por el motor de Chrome. Ahora abarca las solicitudes web habituales, WebSocket y WebTransport. Las versiones anteriores solo gestionaban correctamente las solicitudes habituales, mientras que WebSocket y WebTransport eran solo sustitutos. Eso significaba que tu saludo inicial en la puerta sonaba como Chrome, pero si cambiabas a otro tipo de conversación, tu disfraz podía desvanecerse. Esta versión reemplaza esos sustitutos por las implementaciones reales.
Espera, si estamos usando el código de red propio de Chromium, ¿significa eso que tu sencilla compilación en Go se convierte en un enorme dolor de cabeza con el compilador de C? Afortunadamente, no. Tu código en Go sigue siendo Go puro, sin cgo y sin necesidad de un compilador de C.
En lugar de incrustar código del navegador directamente en tu binario, chromenet ejecuta el motor como un pequeño programa independiente junto a tu programa en Go. Piensa en ello como contratar a un intérprete local con fluidez que camina a tu lado, en lugar de intentar reconstruir tus propias cuerdas vocales. Como el motor se ejecuta en ese programa separado, un fallo en su interior no puede tumbar tu servicio.

Tu programa en Go sigue siendo Go puro mientras un pequeño programa auxiliar transporta el tráfico a través del motor de red de Chromium.
Además, no hay nada extra que instalar en tu estación de trabajo ni en tus servidores. Los binarios del motor para Linux, macOS y Windows, tanto en Intel/AMD como en ARM, se incluyen directamente dentro del módulo de Go y se verifican antes de ejecutarse.
Incluir binarios dentro de un módulo plantea comprensiblemente una pregunta para quien se preocupa por la confianza, y queríamos ofrecer una respuesta clara. Los binarios se compilan de forma reproducible a partir de una versión específica de Chromium, actualmente Chromium 157, de modo que cualquiera puede recompilarlos y obtener exactamente los mismos bytes, y GitHub certifica cada versión. Para mantenerse al día con el mundo de los navegadores sin tareas manuales, un trabajo programado sigue el canal estable de Chromium y actualiza la versión automáticamente cuando se publica una nueva versión de Chrome.
¿Qué pasa con uTLS?
Si alguna vez has intentado que un cliente en Go parezca un navegador, probablemente te hayas encontrado con uTLS. Es un trabajo excelente: una biblioteca en Go que te permite disfrazar el primer mensaje de una conexión segura para que se parezca a Chrome, Firefox o al navegador que prefieras. Es pequeña, es Go puro y no se ejecuta nada adicional junto a tu programa.
La limitación está en el alcance del disfraz. uTLS cubre el handshake, que son las primeras palabras de la conversación. Todo lo que viene después sigue siendo responsabilidad tuya: la capa HTTP/2 debe configurarse y ajustarse a mano, HTTP/3 es una aventura aparte, y WebSocket o WebTransport requieren todavía más código de integración. Además, los perfiles de Chrome son copias, así que alguien debe mantenerlos actualizados cada vez que Chrome cambia sus hábitos. Es un poco como imitar el acento de una persona mientras el resto de su lenguaje corporal sigue delatándola.
chromenet sigue el camino opuesto. No imita a Chrome, sino que pide al propio motor de Chrome que se encargue de la comunicación, de modo que el handshake, la forma en que se reutilizan las conexiones, las actualizaciones de protocolo y los transportes provienen de un mismo origen y evolucionan juntos cuando evoluciona Chromium.
El compromiso es honesto. uTLS es más ligero y te permite diseñar cualquier saludo que imagines, mientras que chromenet incorpora un auxiliar de 25 MB y te ofrece el comportamiento de Chrome en lugar de uno personalizado. Si quieres una dependencia mínima y control total sobre el handshake, uTLS sigue siendo una gran opción.
Todo diseño implica compromisos, y queremos ser claros con los límites aquí. Incluir un motor de red de navegador real no es algo pequeño: cada binario del motor pesa unos 25 MB. En macOS, los binarios no están notarizados. Y en Linux, tu sistema necesita glibc 2.31 o una versión posterior. Si esos límites encajan con tu entorno, obtienes la red real de Chrome cambiando un único campo del transporte.
El proyecto está en github.com/gosuda/chromenet. Si conoces sus proyectos hermanos de la familia de código abierto de gosuda, gosuda.org/hqq y gosuda.org/sqlite3, el espíritu te resultará familiar: tomar maquinaria potente y pesada del ecosistema de software más amplio y hacer que se sienta como en casa en Go puro.
Así que, si recurres a uTLS porque necesitas que tu programa en Go suene como un navegador, prueba chromenet. Puede ser una buena alternativa a uTLS, especialmente cuando necesitas algo más que solicitudes HTTPS: HTTP/2, HTTP/3, WebSocket y WebTransport pasan todos por el mismo motor de Chrome, sin código de integración de tu parte.