Configurando timeout para requisições HTTP em Golang
Por padrão Go não tem timeout para requisições HTTP, isso pode acarretar vários problemas e vulnerabilidades, por exemplo, um ataque DOS pode simplesmente abrir várias conexões com seu servidor.
Para resolver crie uma instancia da struct http.Server e preencha os campos WriteTimeout e ReadTimeout com os tempos que achar adequados.
Veja o exemplo de código.
func main() {
r := mux.NewRouter().StrictSlash(true)
r.HandleFunc("/", mainHandler)
...
srv := &http.Server{
Handler: r,
Addr: ":8000",
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Println("Listen at port :8000")
log.Fatal(srv.ListenAndServe())
}
Isso vai definir os tempos de timeout default para todas as requisições HTTP.
Para definir o timeout para um handler especifico é bem mais complexo, uma opção é definir um contexto com timeout e usar esse contexto para evitar que demoremos demais para retornar nas chamadas internas, efetivamente cancelando consultas muito demoraras a base de dados e outros recursos.
r.Context()
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()
Particularmente eu considero uma boa pratica passar o contexto para as funções e definir um timeout, isso pode evitar o uso desnecessário de recursos caso, por exemplo, um usuário desista de uma requisição.