02226d61f6
Seis funciones de servidor HTTP con tests usando httptest: - HTTPJSONResponse: escribe JSON con Content-Type y status code - HTTPErrorResponse: escribe HTTPError como JSON estructurado - HTTPParseBody: decode JSON con limite de bytes y campos estrictos - HTTPLoggerMiddleware: loguea method/path/status/duration a io.Writer - HTTPRouter: crea ServeMux con rutas Go 1.22+ (METHOD /path) - HTTPServe: ListenAndServe con graceful shutdown por contexto 23 tests pasando, solo stdlib net/http. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
35 lines
915 B
Go
35 lines
915 B
Go
package infra
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// responseWriter captura el status code escrito al ResponseWriter.
|
|
type responseWriter struct {
|
|
http.ResponseWriter
|
|
status int
|
|
}
|
|
|
|
func (rw *responseWriter) WriteHeader(status int) {
|
|
rw.status = status
|
|
rw.ResponseWriter.WriteHeader(status)
|
|
}
|
|
|
|
// HTTPLoggerMiddleware retorna un Middleware que loguea metodo, path, status y duracion de cada request.
|
|
// El formato de cada linea es: METHOD /path STATUS DURACIONms
|
|
func HTTPLoggerMiddleware(logger io.Writer) Middleware {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
start := time.Now()
|
|
rw := &responseWriter{ResponseWriter: w, status: http.StatusOK}
|
|
next.ServeHTTP(rw, r)
|
|
duration := time.Since(start)
|
|
fmt.Fprintf(logger, "%s %s %d %dms\n",
|
|
r.Method, r.URL.Path, rw.status, duration.Milliseconds())
|
|
})
|
|
}
|
|
}
|