Mengajarkan Program Go Anda Agar Berbicara Seperti Chrome

Jika Anda pernah bepergian ke luar negeri dan memesan kopi dengan frasa yang sempurna seperti di buku teks, Anda tentu mengenal tatapan yang diberikan barista kepada Anda. Tata bahasa Anda sudah benar. Setiap kata ada di dalam kamus. Namun, dalam waktu setengah detik, semua orang di kafe itu sudah tahu bahwa Anda berasal dari luar kota.
Klien HTTP standar Go memiliki sedikit masalah serupa. Klien ini merupakan pilihan default yang sangat baik: andal, bersih, dan siap untuk pekerjaan serius sejak awal. Namun, ketika program Anda menghubungi server, program tersebut jelas terlihat seperti program Go. Dalam sebagian besar situasi, tidak ada yang mempermasalahkannya. Meski demikian, sejumlah situs web, CDN, dan pengaturan pengujian memperhatikan dengan cermat siapa yang mengetuk pintu mereka, dan mereka berperilaku cukup berbeda tergantung pada jenis klien yang mereka kira sedang berkomunikasi dengan mereka.
Itulah alasan kami membangun gosuda.org/chromenet. Alih-alih melatih klien standar Go agar menyerupai peramban secara memadai, chromenet memungkinkan program Go berkomunikasi dengan web menggunakan mesin jaringan yang sama dengan yang digunakan Google Chrome, yaitu kode jaringan milik Chromium sendiri. Baik Anda sedang memeriksa bagaimana pengaturan pengujian Anda memperlakukan lalu lintas peramban maupun berkomunikasi dengan situs di balik CDN yang selektif, berbicara melalui mesin Chrome menghilangkan satu lapisan penuh ketidakpastian.
Anda tidak perlu menulis ulang aplikasi Anda untuk menggunakannya. Dalam kode Anda, chromenet berfungsi sebagai pengganti langsung (drop-in replacement) untuk http.Transport. Anda tetap menggunakan http.Client seperti biasa, dan chromenet mengurus komunikasi di baliknya.
Untuk mencoba rilis terbaru, pasang dengan go get:
1go get gosuda.org/chromenet@v0.2.10157081033800
Kemudian, berikan transport-nya ke klien Anda:
1client := http.Client{
2 Transport: chromenet.NewTransport(chromenet.Options{}),
3}
Dengan rilis ini, seluruh rentang lalu lintas web modern melewati mesin Chrome. Kini mencakup permintaan web biasa, WebSocket, dan WebTransport. Versi sebelumnya hanya menangani permintaan biasa dengan baik, sementara WebSocket dan WebTransport hanyalah pengganti sementara. Artinya, sapaan awal Anda di pintu depan terdengar seperti Chrome, tetapi jika Anda beralih ke gaya komunikasi yang berbeda, penyamaran Anda bisa terbongkar. Rilis ini menggantikan pengganti sementara tersebut dengan implementasi yang sebenarnya.
Tunggu, jika kita menggunakan kode jaringan milik Chromium sendiri, apakah itu berarti build Go Anda yang sederhana berubah menjadi masalah kompilasi C yang rumit? Untungnya, tidak. Kode Go Anda tetap Go biasa, tanpa cgo dan tanpa perlu compiler C.
Alih-alih menyisipkan kode peramban langsung ke dalam binary Anda, chromenet menjalankan mesin tersebut sebagai program terpisah yang kecil di samping program Go Anda. Bayangkan seperti mempekerjakan seorang juru bahasa lokal yang fasih yang berjalan di samping Anda, daripada mencoba membangun ulang pita suara Anda sendiri. Karena mesin tersebut berjalan di program terpisah itu, kegagalan di dalamnya tidak akan menjatuhkan layanan Anda.

Program Go Anda tetap Go biasa, sementara program pendamping kecil menyalurkan lalu lintas melalui mesin jaringan Chromium.
Anda juga tidak perlu memasang apa pun tambahan di workstation atau server Anda. Binary mesin untuk Linux, macOS, dan Windows, pada arsitektur Intel/AMD maupun ARM, sudah disertakan di dalam modul Go dan diverifikasi sebelum dijalankan.
Menyertakan binary di dalam modul tentu menimbulkan pertanyaan bagi siapa pun yang peduli pada kepercayaan, dan kami ingin memberikan jawaban yang lugas. Binary dibangun dengan cara yang dapat direproduksi dari rilis Chromium tertentu, saat ini Chromium 157, sehingga siapa pun dapat membangunnya kembali dan memperoleh byte yang persis sama, serta setiap rilis diattestasi oleh GitHub. Untuk tetap mengikuti perkembangan dunia peramban tanpa pekerjaan manual, sebuah job terjadwal mengikuti channel stabil Chromium dan memperbarui versi secara otomatis setiap kali Chrome baru dirilis.
Bagaimana dengan uTLS?
Jika Anda pernah mencoba membuat klien Go terlihat seperti peramban, kemungkinan besar Anda sudah mengenal uTLS. Ini adalah karya yang indah: sebuah pustaka Go yang memungkinkan Anda membungkus pesan pertama sebuah koneksi aman agar menyerupai Chrome, Firefox, atau peramban lain yang Anda inginkan. Ukurannya kecil, murni Go, dan tidak ada program tambahan yang berjalan di samping program Anda.
Namun, batas penyamarannya terbatas. uTLS hanya mencakup handshake, yaitu beberapa kata pertama dalam percakapan. Segala sesuatu setelahnya tetap menjadi tanggung jawab Anda untuk dibangun: lapisan HTTP/2 harus dihubungkan dan disetel secara manual, HTTP/3 merupakan urusan tersendiri, dan WebSocket atau WebTransport membutuhkan lebih banyak kode perekat. Preset Chrome yang digunakan juga berupa salinan, sehingga seseorang harus terus memperbaruinya setiap kali Chrome mengubah kebiasaannya. Ini seperti menirukan aksen seseorang, sementara bahasa tubuhnya tetap memperlihatkan jati dirinya.
chromenet mengambil jalan yang berlawanan. Ia tidak meniru Chrome, melainkan meminta mesin Chrome itu sendiri untuk berkomunikasi, sehingga handshake, cara koneksi digunakan kembali, peningkatan protokol, dan transport semuanya berasal dari satu sumber dan berubah bersama ketika Chromium berubah.
Pertukarannya bersifat jujur. uTLS lebih ringan dan memungkinkan Anda merancang sapaan apa pun yang bisa dibayangkan, sedangkan chromenet membawa helper berukuran 25 MB dan memberikan perilaku Chrome yang sebenarnya, bukan perilaku kustom. Jika Anda menginginkan dependensi yang kecil dan kendali penuh atas handshake, uTLS tetap merupakan pilihan yang sangat baik.
Setiap desain memiliki pertukaran, dan kami ingin terus terang tentang batasannya di sini. Membawa mesin jaringan peramban yang sesungguhnya tidaklah kecil: setiap binary mesin berukuran sekitar 25 MB. Di macOS, binary tidak dinotarisasi. Di Linux, sistem Anda membutuhkan glibc 2.31 atau yang lebih baru. Jika batasan tersebut sesuai dengan pengaturan Anda, Anda mendapatkan jaringan Chrome yang sebenarnya hanya dengan mengganti satu field transport.
Proyek ini berada di github.com/gosuda/chromenet. Jika Anda mengenal proyek saudaranya dalam keluarga open source gosuda, yaitu gosuda.org/hqq dan gosuda.org/sqlite3, semangatnya akan terasa familiar: mengambil perangkat yang kuat dan berat dari dunia perangkat lunak yang lebih luas, lalu membuatnya terasa menyatu dengan Go biasa.
Jadi, jika Anda menggunakan uTLS karena membutuhkan program Go Anda terdengar seperti peramban, cobalah chromenet. Ia bisa menjadi alternatif yang baik untuk uTLS, terutama ketika Anda membutuhkan lebih dari sekadar permintaan HTTPS: HTTP/2, HTTP/3, WebSocket, dan WebTransport semuanya melewati mesin Chrome yang sama, tanpa kode perekat di sisi Anda.