Регистрация ошибок HTTP 404/405 с помощью Golang 1.22+ net/http ServeMux

Я играюсь с net/http после прочтения об обновлениях маршрутизации в версии 1.22. Целью здесь является использование только stdlib, поэтому я намеренно избегаю фреймворков и маршрутизаторов, которые не являются частью stdlib, таких как gin или gorilla/chi. .

...

func main() {
    mux := http.NewServeMux()

    mux.Handle("GET /hello/{$}", handler1)
    mux.Handle("GET /headers/{$}", handler2)


    http.ListenAndServe(port, mux)
}

делает то, что я ожидаю:

GET-запросы на маршрут /hello/ или /hello к обработчику 1

GET-запросы на маршрут /headers/ или /headers к обработчику 2

POST-запросы к обрабатываемым путям возвращают HTTP 405

необработанные пути возвращают HTTP 404

Однако в случае 404 или 405 это просто ответы, которые не записываются в stdout. Есть ли простой способ добавить в журнал эти неверные запросы без добавления дополнительных обработчиков/промежуточного программного обеспечения?

Написание обработчика в качестве ловушки, такого как mux.Handle("/", badHandler), потребует дополнительной сложности для обработки 404 против 405, если есть альтернатива, я бы хотел ее избежать.

создание промежуточного программного обеспечения для шпионажа за responseWriter, проверки statusCode и входа в систему 404/405, похоже, также потенциально будет работать в зависимости от того, что становится общедоступным в пакете http (хотя я еще не рассматривал этот вариант), но это В противном случае я надеюсь, что доступно более сложное решение.

Почему вы не можете добавить промежуточное программное обеспечение?

Markus W Mahlberg 13.07.2024 21:57

Нет причин, мешающих мне использовать промежуточное программное обеспечение, я просто ищу альтернативное решение, так как считал, что есть более простой метод, который я упускал из виду. Однако включение ResponseWriter в промежуточное программное обеспечение создает некоторые проблемы, которые хорошо описаны в этой проблеме GitHub, которую я недавно обнаружил. Похоже, это недостаток stdlib

Andrew Sirolly 14.07.2024 00:17

@AndrewSirolly См. http.ResponseController.

Lorretta McCabe 14.07.2024 02:48
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
1
3
89
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Используйте промежуточное программное обеспечение. Это не очень сложно и является единственным вариантом начиная с Go 1.22.

type logWriter struct {
    http.ResponseWriter
    code int
}

func (lw *logWriter) WriteHeader(code int) {
    lw.code = code
    lw.ResponseWriter.WriteHeader(code)
}

// Unwrap supports http.ResponseController.
func (lw *logWriter) Unwrap() http.ResponseWriter { return lw.ResponseWriter }

func wrap(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        lw := &logWriter{w, http.StatusOK}
        next.ServeHTTP(lw, r)
        fmt.Printf("%d: %s\n", lw.code, r.URL.Path)
    })
}

Используйте промежуточное программное обеспечение следующим образом:

http.ListenAndServe(port, wrap(mux))

Run the middleware on the PlayGround


Обертывание средства записи ответов с использованием промежуточного программного обеспечения раньше было проблемой, поскольку оболочка могла блокировать доступ к дополнительным интерфейсам, таким как http.Flusher и http.Hijacker . Тип http.ResponseController был добавлен в Go 1.20, чтобы устранить этот недостаток. Если оболочка средства записи ответов реализует метод Unwrap() http.ResponseWriter (как это сделано в этом ответе), то приложение может получить доступ к дополнительным интерфейсам через контроллер ответов.

В этом обсуждении на GitHub есть некоторые хорошо обсуждаемые недостатки при использовании промежуточного программного обеспечения, которые я обнаружил после того, как задал вопрос.

Andrew Sirolly 14.07.2024 00:26

@AndrewSirolly Контроллер ответов устраняет этот недостаток. Мой ответ поддерживает контроллер ответа.

Lorretta McCabe 14.07.2024 02:41

Это самое элегантное решение, которое я когда-либо видел.

Markus W Mahlberg 14.07.2024 12:00

Как подробно обсуждалось в этом выпуске Github официального репозитория Go, начиная с go 1.22, нет встроенной возможности добавлять ведение журнала без промежуточного программного обеспечения для перехвата вызова функции WriteHeader().

Другие вопросы по теме