Операция выполнена!
Закрыть
Хабы: Программирование, Go, Разработка под Linux

Эта заметка будет очень короткой. Но надеюсь, она кому-то спасёт несколько часов жизни.

У меня был код. К счастью, это было в тесте, а не в боевом коде, поэтому никто не пострадал.

Код создавал http.Server, запускал две гороутинки для обслуживания входящих соединений:

go func() {srvr.Serve(p)}()

go func() {srvr.ServeTLS(e, "", "")}()

Ну и дальше создавал клиента, делал к серверу обращения (HTTP GET) попеременно используя http и https ну и чего-то там проверял.

Всё прекрасно работало. До обновления с go1.23.8 до go1.24.2, пришедшего с 42-й Федорой.

А потом перестало. Стало время от времени (но отнюдь не всегда) вываливать разнообразные ошибки. Например, вот такие: Get "https://127.0.0.1:46167/": unexpected EOF. Или такие: Get "https://127.0.0.1:34757/": write tcp 127.0.0.1:54770->127.0.0.1:34757: write: connection reset by peer. Или даже вот такие, совсем загадочные: Get "https://127.0.0.1:42447/": http2: client conn could not be establish. HTTP/2 там, разумеется никто не включал и не собирался. А иногда всё работало и тест проходил правильно.

Самое поганое, что ошибка была плавающей.

В общем, не буду грузить подробностями, как я эту ошибку ловил. Но итог такой. Хотя это нигде и не документировано, но одновременно использовать http.Server.Serve и http.Server.ServeTLS на одном и том же экземпляре сервера нельзя. Тот из них, кто успеет прокрутиться первым, чего-то там инициализирует внутри сервера, прежде, чем уйти в accept loop, и второй после этого ломается. Ломается всегда ServeTLS, не-TLS-овскому Serve вроде как пофигу.

Так что будьте осторожны, и надеюсь, что эта заметка сохранила вам несколько часов жизни :)

Читать далее
Читайте также
СТАТЬ АВТОРОМ
НОВОСТИ

ПИШИТЕ

Техническая поддержка проекта ВсеТут

info@vsetut.pro