GoSuda

Обучение на вашата Go програма да говори като Chrome

By Lemon Mint views ...

Ако някога сте пътували в чужбина и сте поръчали кафе с фраза, взета директно от учебник, знаете погледа, който бариста ви отправя. Граматиката ви е наред. Всяка дума се съдържа в речника. И все пак за половин секунда всички в кафенето разбират, че сте от друг край.

Стандартният HTTP клиент на Go има малко от този проблем. Той е отлична отправна точка: надежден, чист и готов за сериозна работа веднага след инсталирането. Когато вашата програма се свърже със сървър, обаче, тя безпогрешно изглежда като програма на Go. В повечето случаи никой не обръща внимание. Все пак някои уебсайтове, CDN мрежи и тестови среди обръщат голямо внимание на това кой почуква на вратата и се държат доста различно в зависимост от това с какъв тип клиент смятат, че общуват.

Затова създадохме gosuda.org/chromenet. Вместо да обучаваме стандартния клиент на Go да имитира приемливо браузър, chromenet позволява на програма на Go да комуникира с уеба чрез същия мрежов двигател, който използва Google Chrome, а именно собствения мрежов код на Chromium. Независимо дали проверявате как вашите тестови среди третират браузърния трафик или общувате със сайт зад взискателна CDN мрежа, комуникацията чрез двигателя на Chrome премахва цял слой предположения.

За да го използвате, не е необходимо да пренаписвате приложението си. В кода ви той работи като директна замяна на http.Transport. Продължавате да използвате http.Client по познатия начин, а chromenet поема комуникацията на по-ниско ниво.

За да изпробвате най-новата версия, инсталирайте я с go get:

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

След това предайте неговия транспорт на вашия клиент:

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

С тази версия целият спектър на съвременния уеб трафик преминава през двигателя на Chrome. Сега той обхваща обикновените уеб заявки, WebSocket и WebTransport. По-ранните версии обработваха правилно само обикновените заявки, докато WebSocket и WebTransport бяха заместители. Това означаваше, че първоначалният ви поздрав на входната врата звучеше като Chrome, но ако преминехте към различен стил на комуникация, прикритието ви можеше да се провали. Тази версия замества тези заместители с истинските неща.

Почакайте, ако използваме собствения мрежов код на Chromium, нима това означава, че тихият ви Go билд се превръща в разрастваща се главоболие с C компилатор? За щастие, не. Вашият Go код остава чист Go, без cgo и без нужда от C компилатор.

Вместо да вграждаме браузърния код директно във вашия двоичен файл, chromenet стартира двигателя като малка отделна програма до вашата Go програма. Представете си го като наемане на течен местен преводач, който върви до вас, вместо да се опитвате сами да възстановите собствените си гласни връзки. Тъй като двигателят работи в тази отделна програма, срив в него не може да спре вашата услуга.

Как работи chromenet: вашата Go програма изпраща заявка към малка помощна програма, която изпълнява мрежовия двигател на Chromium и комуникира с уеба

Вашата Go програма остава чист Go, докато малка помощна програма пренася трафика през мрежовия двигател на Chromium.

Освен това няма нищо допълнително за инсталиране на вашата работна станция или на вашите сървъри. Двоичните файлове на двигателя за Linux, macOS и Windows, както за Intel/AMD, така и за ARM, се доставят директно в Go модула и се проверяват преди да бъдат стартирани.

Доставянето на двоични файлове в рамките на модул естествено поражда въпрос за всеки, който се грижи за доверието, и ние искахме ясен отговор. Двоичните файлове се изграждат по възпроизводим начин от конкретна версия на Chromium, в момента Chromium 157, така че всеки може да ги пресъздаде и да получи точно същите байтове, а всяка версия се удостоверява от GitHub. За да следва света на браузърите без ръчна работа, планирана задача следи стабилния канал на Chromium и автоматично обновява версията, когато излезе нов Chrome.

Какво да кажем за uTLS?

Ако сте се опитвали да накарате Go клиент да изглежда като браузър, вероятно сте се срещали с uTLS. Това е прекрасно постижение: Go библиотека, която ви позволява да облечете първото съобщение на защитена връзка така, че да прилича на Chrome, Firefox или на какъвто и да е друг браузър. Тя е малка, чисто Go и до вашата програма не работи нищо допълнително.

Уловката е в това колко далеч стига костюмът. uTLS обхваща ръкостискането, което е първите няколко думи на разговора. Всичко след това все още трябва да изградите сами: слоят HTTP/2 трябва да бъде свързан и настроен ръчно, HTTP/3 е отделно приключение, а WebSocket или WebTransport означават още повече лепило. Предварително зададените настройки на Chrome също са копия, така че някой трябва да ги поддържа актуални всеки път, когато Chrome промени навиците си. Това е донякъде като да имитирате акцента на човек, докато останалият му език на тялото все още ви издава.

chromenet следва обратния път. Той не имитира Chrome, а моли собствения двигател на Chrome да води разговора, така че ръкостискането, начинът на повторно използване на връзките, надграждането на протоколите и транспортите идват от едно място и се променят заедно, когато се променя Chromium.

Компромисът е честен. uTLS е по-лек и ви позволява да създадете всякакъв поздрав, който можете да си представите, докато chromenet носи помощна програма от 25 MB и ви дава поведението на Chrome, а не персонализирано. Ако искате миниатюрна зависимост и пълен контрол върху ръкостискането, uTLS все още е отличен избор.

Всеки дизайн има компромиси и искаме да бъдем откровени относно ограниченията тук. Включването на истински мрежов двигател за браузър не е малко: всеки двоичен файл на двигателя е около 25 MB. На macOS двоичните файлове не са нотариално заверени. А на Linux системата ви трябва glibc 2.31 или по-нова версия. Ако тези граници отговарят на вашата среда, получавате истинска мрежова функционалност на Chrome, като замените само едно поле на транспорта.

Проектът е достъпен на github.com/gosuda/chromenet. Ако познавате сродните проекти от семейството с отворен код на gosuda, gosuda.org/hqq и gosuda.org/sqlite3, духът ще ви е познат: вземане на способна, тежка техника от по-широкия софтуерен свят и правенето ѝ да се чувства като у дома си в чист Go.

Така че, ако се насочвате към uTLS, защото искате вашата Go програма да звучи като браузър, опитайте chromenet. Той може да бъде добра алтернатива на uTLS, особено когато имате нужда от повече от HTTPS заявки: HTTP/2, HTTP/3, WebSocket и WebTransport преминават през един и същ двигател на Chrome, без необходимост от допълнителен код от ваша страна.