Собственно, по поводу хттпс.
Я посидел, покумекал, понял - мирного решения не будет.
Ну, то есть, вот у меня была такая тема, что я мог вешать индигу на несколько портов. Естественно, добавил на один уровень вглубь больше: можно прокидывать свои листенеры. Листенер просто возвращает имплементацию интерфейса net.Listener, и дальше уже индига сама с этим разбирается. Минус - нельзя прокидывать через запрос инфу о том, запрос прилетел по зашифрованному каналу, или нет, а это важно - иначе даже нельзя автоматический редирект на хттпс сделать, помимо как прибегать к HSTS правилам. А это, мягко говоря, не совсем то, чего я ожидаю от проекта.
Поэтому расширяем функционал - теперь можно прокидывать ещё и кастомные хендлеры вместе с листенерами. Под хендлерами подразумевается функция, которая будет отрабатывать каждый раз, как мы имеем новое подключение. Обычно, оно просто тыкает serve.HTTP1(). То есть - ручками зафурычивает хттп движок. Вот где-то на этом этапе я и кладу в объект запроса инфу о том, по защищённому ли каналу был получен запрос. В этом у меня ещё состоялся потенциал добавления хттп2, но о нём попозже.
А вот как это реализовано - ну просто страшная ебака - задействованы фабрики, хуябрики, и господь-упаси-какие-ещё-сущности-из-джавы. Встала проблема - на этом механизме у меня построен хттпс, в гибкости терять нельзя, а привести в порядок - хочется. Решение, кажется, вполне очевидное - вообще убрать из скоупа ответственности net.Listener. Пусть у нас будет просто хендлер - только теперь он ещё и за accept-loop отвечает (accept-loop'ом обычно называют цикл приёма новых подключений). То есть, он у нас теперь суперсолдат - подключения прими, хттп ядро ткни, так ещё и следи за тем, когда тебе скажут остановиться (через *atomic.Bool, кстати; нужно для graceful shutdown). Становится хорошо: код становится проще, избавляемся от довольно ёмких сущностей, оставляя лишь супервизор, который будет следить за тем, чтобы если ошибка произошла в одном хендлере - остановить все остальные. Теперь можно написать хендлер чисто для tcp, а в net.TCPListener есть возможность устанавливать таймаут на accept - это очень хорошо, раньше я оперировал с net.Listener, и должен был проверять низлежащую реализацию на наличие такого метода, что не есть очень приятно. А здесь спокойненько себе. Да и с тлс попроще стало - tls.Listener() просто оборачивает низлежащий листенер. Спокойно могу проинициализировать самостоятельно net.TCPListener для него, и повторить фокус с обычным tcp хендлером. Одним словом - хорошо.
Ниже продолжение
Post #402
260