package module
v0.0.0-...-2cbf18a Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Nov 7, 2023 License: Apache-2.0, BSD-2-Clause, MIT Imports: 22 Imported by: 62


This project contains middlewares that I often found myself reimplementing in new projects. In addition, it includes a middleware that logs in a format similar to Heroku's, but which includes the request's user agent, and only a single proxy IP address.

See the godoc for more information and documentation.


handlers requires Go 1.8 or newer. Version 0.30 is the last version that works with versions older than Go 1.8.


Donations free up time to make improvements to the library, and respond to bug reports. You can send donations via Paypal's "Send Money" feature to kev@inburke.com. Donations are not tax deductible in the USA.



Package handlers implements a number of useful HTTP middlewares.

The general format of the middlewares in this package is to wrap an existing http.Handler in another one. So if you have a ServeMux, you can simply do:

mux := http.NewServeMux()
h := handlers.Log(handlers.Debug(mux))
http.ListenAndServe(":5050", h)

And wrap as many handlers as you'd like using that idiom.

package main

import (


func main() {
	mux := http.NewServeMux()
	h := handlers.Duration(handlers.Server(mux, "custom-server"))
	req := httptest.NewRequest("GET", "/", nil)
	w := httptest.NewRecorder()
	h.ServeHTTP(w, req)





View Source
const Version = "0.46"


View Source
var Logger *slog.Logger


func All

func All(h http.Handler, serverName string) http.Handler

All wraps h with every handler in this file.

func AppendLog

func AppendLog(r *http.Request, logctx ...interface{})

Append will append the logctx arguments to the log line for this request. The logctx arguments should come in pairs and match those provided to a log15.Logger.

func BasicAuth

func BasicAuth(h http.Handler, realm string, users map[string]string) http.Handler

BasicAuth protects all requests to the given handler, unless the request has basic auth with a username and password in the users map.

func Debug

func Debug(h http.Handler) http.Handler

Debug prints debugging information about the request to stderr if the DEBUG_HTTP_TRAFFIC environment variable is set to "true".

func DebugWriter

func DebugWriter(h http.Handler, output io.Writer) http.Handler

Debug prints debugging information about the request to output if the DEBUG_HTTP_TRAFFIC environment variable is set to "true".

func Duration

func Duration(h http.Handler) http.Handler

Duration sets the start time in the context and sets a X-Request-Duration header on the response, from the time this handler started executing to the time of the first WriteHeader() or Write() call.

func GZip

func GZip(h http.Handler) http.Handler

GZip gzip compresses HTTP responses for clients that support it via the 'Accept-Encoding' header.

Compressing TLS traffic may leak the page contents to an attacker if the page contains user input, known as the CRIME/BEAST attacks: http://security.stackexchange.com/a/102015/12208. Only use the GZip handler with unencrypted traffic, static pages, or pages that only contain public data.

func GetDuration

func GetDuration(ctx context.Context) time.Duration

GetDuration returns the amount of time since the Duration handler ran, or 0 if no Duration was set for this context.

func GetRequestID

func GetRequestID(ctx context.Context) (uuid.UUID, bool)

GetRequestID returns a UUID (if it exists in the context) or false if none could be found.

func GetStartTime

func GetStartTime(ctx context.Context) time.Time

GetStartTime returns the time the Duration handler ran.

func JSON

func JSON(h http.Handler) http.Handler

JSON sets the Content-Type to application/json; charset=utf-8.

func Log

func Log(h http.Handler) http.Handler

Log serves the http request and writes information about the request/response using the default Logger (handlers.Logger). Any errors writing to the Logger are ignored.

func NewLogger

func NewLogger() *slog.Logger

NewLogger returns a new customizable Logger, with the same initial settings as the package Logger. Compared with a default log15.Logger, the 40-char spacing gap between the message and the first key is omitted, and timestamps are written with more precision.

func NewLoggerLevel

func NewLoggerLevel(lvl slog.Level) *slog.Logger

NewLoggerLevel returns a Logger with our customized settings, set to log messages at or more critical than the given level.

func RedirectProto

func RedirectProto(h http.Handler) http.Handler

RedirectProto redirects requests with an "X-Forwarded-Proto: http" header to their HTTPS equivalent.

func STS

func STS(h http.Handler) http.Handler

STS sets a Strict-Transport-Security header on the response.

func Server

func Server(h http.Handler, serverName string) http.Handler

Server attaches a Server header to the response.

func SetRequestID

func SetRequestID(r *http.Request, u uuid.UUID) *http.Request

SetRequestID sets the given UUID on the request context and returns the modified HTTP request.

func TrailingSlashRedirect

func TrailingSlashRedirect(h http.Handler) http.Handler

TrailingSlashRedirect redirects any path that ends with a "/" - say, "/messages/" - to the stripped version, say "/messages".

func UUID

func UUID(h http.Handler) http.Handler

UUID attaches a X-Request-Id header to the request, and sets one on the request context, unless one already exists.

func WithLogger

func WithLogger(h http.Handler, logger *slog.Logger) http.Handler

WithLogger logs information about HTTP requests and responses to the provided Logger, including a detailed timestamp, the user agent, the response time, the number of bytes written, and more. Any errors writing log information to the Logger are ignored.

func WithTimeout

func WithTimeout(h http.Handler, timeout time.Duration) http.Handler

WithTimeout sets the given timeout in the Context of every incoming request before passing it to the next handler.


type Regexp

type Regexp struct {
	// contains filtered or unexported fields

A RegexpHandler is a simple http.Handler that can match regular expressions for routes.

package main

import (


func main() {
	// GET /v1/jobs/:job-name
	route := regexp.MustCompile(`^/v1/jobs/(?P<JobName>[^\s\/]+)$`)

	h := new(handlers.Regexp)
	h.HandleFunc(route, []string{"GET", "POST"}, func(w http.ResponseWriter, r *http.Request) {
		io.WriteString(w, "Hello World!")

func (*Regexp) Handle

func (h *Regexp) Handle(pattern *regexp.Regexp, methods []string, handler http.Handler)

Handle calls the provided handler for requests whose URL matches the given pattern and HTTP method. The first matching route will get called. If methods is nil, all HTTP methods will be allowed. If GET is in the list of methods, HEAD requests will also be allowed.

func (*Regexp) HandleFunc

func (h *Regexp) HandleFunc(pattern *regexp.Regexp, methods []string, handler func(http.ResponseWriter, *http.Request))

HandleFunc calls the provided HandlerFunc for requests whose URL matches the given pattern and HTTP method. The first matching route will get called. If methods is nil, all HTTP methods are allowed. If GET is in the list of methods, HEAD requests will also be allowed.

func (*Regexp) HandleString

func (h *Regexp) HandleString(s string, methods []string, handler http.Handler)

HandleString is like Handle, but will compile s to a regexp first. If s is not a valid regexp HandleString will panic.

func (*Regexp) HandleStringFunc

func (h *Regexp) HandleStringFunc(s string, methods []string, handler func(http.ResponseWriter, *http.Request))

HandleStringFunc is like HandleFunc, but will compile s to a regexp first. If s is not a valid regexp HandleStringFunc will panic.

func (*Regexp) ServeHTTP

func (h *Regexp) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP checks all registered routes in turn for a match, and calls handler.ServeHTTP on the first matching handler. If no routes match, StatusMethodNotAllowed will be rendered.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL