Я играюсь с 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 (хотя я еще не рассматривал этот вариант), но это В противном случае я надеюсь, что доступно более сложное решение.
Нет причин, мешающих мне использовать промежуточное программное обеспечение, я просто ищу альтернативное решение, так как считал, что есть более простой метод, который я упускал из виду. Однако включение ResponseWriter в промежуточное программное обеспечение создает некоторые проблемы, которые хорошо описаны в этой проблеме GitHub, которую я недавно обнаружил. Похоже, это недостаток stdlib
@AndrewSirolly См. http.ResponseController.

Используйте промежуточное программное обеспечение. Это не очень сложно и является единственным вариантом начиная с 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 есть некоторые хорошо обсуждаемые недостатки при использовании промежуточного программного обеспечения, которые я обнаружил после того, как задал вопрос.
@AndrewSirolly Контроллер ответов устраняет этот недостаток. Мой ответ поддерживает контроллер ответа.
Это самое элегантное решение, которое я когда-либо видел.
Как подробно обсуждалось в этом выпуске Github официального репозитория Go, начиная с go 1.22, нет встроенной возможности добавлять ведение журнала без промежуточного программного обеспечения для перехвата вызова функции WriteHeader().
Почему вы не можете добавить промежуточное программное обеспечение?