Setting HTTP Request Timeouts in Golang

By default, Go doesn’t set timeouts for HTTP requests, which can cause a number of problems and vulnerabilities. A DOS attack, for example, could simply open a large number of connections to your server.

To fix this, create an instance of the http.Server struct and fill in the WriteTimeout and ReadTimeout fields with values you consider appropriate.

Here’s an example:

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())
}

This sets the default timeout values for all HTTP requests.

Setting a timeout for a specific handler is more involved. One option is to create a context with a timeout and use it to avoid taking too long to return from internal calls, effectively canceling slow queries to the database or other resources.

r.Context()
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()

I consider it good practice to pass the context down to functions and set a timeout, since this can avoid unnecessary use of resources if, for example, a user gives up on a request.

Cesar Gimenes

Last modified
Tags: