HTTP servers in Go
This example is for plain HTTP. You should use HTTPS, either in Go directly or by putting the Go server behind a reverse proxy.
import (
"fmt"
"log"
"net/http"
)
func handleIndex(writer http.ResponseWriter, req *http.Request) {
// req.URL.Query()
// req.URL.Path
// req.Header["Hostname"]
// req.RemoteAddr
// writer.WriteHeader(http.StatusInternalServerError)
// writer.Header().Set("Content-Type", "application/json")
}
handler := &http.ServeMux{}
handler.HandleFunc("/", handleIndex)
addr := fmt.Sprintf(":%d", port)
server := &http.Server{
ReadHeaderTimeout: readHeaderTimeout,
ReadTimeout: readTimeout,
WriteTimeout: writeTimeout,
IdleTimeout: idleTimeout,
Addr: addr,
Handler: handler,
}
log.Fatal("server failed", server.ListenAndServe())
- Use your own
http.ServeMux
rather thanhttp.HandleFunc
andhttp.ListenAndServe
; libraries likenet/http/pprof
can add their own endpoints to the latter, which you don't want to accidentally expose to the public. - Each request is handled in its own goroutine. So you must synchronize access to shared state. Panics are caught by the framework and transformed into HTTP 500 errors.
- Handlers that do long-running work should terminate when the
req.Context().Done()
channel is closed. - URL patterns ending with
/
match a prefix, not a whole path. So the URL pattern/static/
matches not just/static/
but also/static/index.js
(unless already matched by a more specific pattern).
Links
net/http
docs- "REST Servers in Go" (Eli Bendersky, 2021)
- "On concurrency in Go HTTP servers" (Eli Bendersky, 2019)
- "Graceful shutdown of a TCP server in Go" (Eli Bendersky, 2020)
- "So you want to expose Go on the Internet" (Filippo Valsorda @ Cloudflare, 2016)
- "Make resilient Go net/http servers" (Ilija Eftimov, 2020)
Examples: