chi: github.com/go-chi/chi/middleware Index | Files

package middleware

import "github.com/go-chi/chi/middleware"

Index

Package Files

compress.go content_charset.go content_type.go get_head.go heartbeat.go logger.go middleware.go nocache.go profiler.go realip.go recoverer.go request_id.go strip.go terminal.go throttle.go timeout.go url_format.go value.go wrap_writer.go

Constants

const RequestIDKey ctxKeyRequestID = 0

RequestIDKey is the key that holds the unique request ID in a request context.

Variables

var (
    // LogEntryCtxKey is the context.Context key to store the request log entry.
    LogEntryCtxKey = &contextKey{"LogEntry"}

    // DefaultLogger is called by the Logger middleware handler to log each request.
    // Its made a package-level variable so that it can be reconfigured for custom
    // logging configurations.
    DefaultLogger = RequestLogger(&DefaultLogFormatter{Logger: log.New(os.Stdout, "", log.LstdFlags), NoColor: false})
)
var (
    // URLFormatCtxKey is the context.Context key to store the URL format data
    // for a request.
    URLFormatCtxKey = &contextKey{"URLFormat"}
)

func AllowContentType Uses

func AllowContentType(contentTypes ...string) func(next http.Handler) http.Handler

AllowContentType enforces a whitelist of request Content-Types otherwise responds with a 415 Unsupported Media Type status.

func Compress Uses

func Compress(level int, types ...string) func(next http.Handler) http.Handler

Compress is a middleware that compresses response body of a given content types to a data format based on Accept-Encoding request header. It uses a given compression level.

NOTE: make sure to set the Content-Type header on your response otherwise this middleware will not compress the response body. For ex, in your handler you should set w.Header().Set("Content-Type", http.DetectContentType(yourBody)) or set it manually.

DEPRECATED

func ContentCharset Uses

func ContentCharset(charsets ...string) func(next http.Handler) http.Handler

ContentCharset generates a handler that writes a 415 Unsupported Media Type response if none of the charsets match. An empty charset will allow requests with no Content-Type header or no specified charset.

func DefaultCompress Uses

func DefaultCompress(next http.Handler) http.Handler

DefaultCompress is a middleware that compresses response body of predefined content types to a data format based on Accept-Encoding request header. It uses a default compression level. DEPRECATED

func GetHead Uses

func GetHead(next http.Handler) http.Handler

GetHead automatically route undefined HEAD requests to GET handlers.

func GetReqID Uses

func GetReqID(ctx context.Context) string

GetReqID returns a request ID from the given context if one is present. Returns the empty string if a request ID cannot be found.

func Heartbeat Uses

func Heartbeat(endpoint string) func(http.Handler) http.Handler

Heartbeat endpoint middleware useful to setting up a path like `/ping` that load balancers or uptime testing external services can make a request before hitting any routes. It's also convenient to place this above ACL middlewares as well.

func Logger Uses

func Logger(next http.Handler) http.Handler

Logger is a middleware that logs the start and end of each request, along with some useful data about what was requested, what the response status was, and how long it took to return. When standard output is a TTY, Logger will print in color, otherwise it will print in black and white. Logger prints a request ID if one is provided.

Alternatively, look at https://github.com/pressly/lg and the `lg.RequestLogger` middleware pkg.

func NextRequestID Uses

func NextRequestID() uint64

NextRequestID generates the next request ID in the sequence.

func NoCache Uses

func NoCache(h http.Handler) http.Handler

NoCache is a simple piece of middleware that sets a number of HTTP headers to prevent a router (or subrouter) from being cached by an upstream proxy and/or client.

As per http://wiki.nginx.org/HttpProxyModule - NoCache sets:

Expires: Thu, 01 Jan 1970 00:00:00 UTC
Cache-Control: no-cache, private, max-age=0
X-Accel-Expires: 0
Pragma: no-cache (for HTTP/1.0 proxies/clients)

func Profiler Uses

func Profiler() http.Handler

Profiler is a convenient subrouter used for mounting net/http/pprof. ie.

func MyService() http.Handler {
  r := chi.NewRouter()
  // ..middlewares
  r.Mount("/debug", middleware.Profiler())
  // ..routes
  return r
}

func RealIP Uses

func RealIP(h http.Handler) http.Handler

RealIP is a middleware that sets a http.Request's RemoteAddr to the results of parsing either the X-Forwarded-For header or the X-Real-IP header (in that order).

This middleware should be inserted fairly early in the middleware stack to ensure that subsequent layers (e.g., request loggers) which examine the RemoteAddr will see the intended value.

You should only use this middleware if you can trust the headers passed to you (in particular, the two headers this middleware uses), for example because you have placed a reverse proxy like HAProxy or nginx in front of chi. If your reverse proxies are configured to pass along arbitrary header values from the client, or if you use this middleware without a reverse proxy, malicious clients will be able to make you very sad (or, depending on how you're using RemoteAddr, vulnerable to an attack of some sort).

func Recoverer Uses

func Recoverer(next http.Handler) http.Handler

Recoverer is a middleware that recovers from panics, logs the panic (and a backtrace), and returns a HTTP 500 (Internal Server Error) status if possible. Recoverer prints a request ID if one is provided.

Alternatively, look at https://github.com/pressly/lg middleware pkgs.

func RedirectSlashes Uses

func RedirectSlashes(next http.Handler) http.Handler

RedirectSlashes is a middleware that will match request paths with a trailing slash and redirect to the same path, less the trailing slash.

NOTE: RedirectSlashes middleware is *incompatible* with http.FileServer, see https://github.com/go-chi/chi/issues/343

func RequestID Uses

func RequestID(next http.Handler) http.Handler

RequestID is a middleware that injects a request ID into the context of each request. A request ID is a string of the form "host.example.com/random-0001", where "random" is a base62 random string that uniquely identifies this go process, and where the last number is an atomically incremented request counter.

func RequestLogger Uses

func RequestLogger(f LogFormatter) func(next http.Handler) http.Handler

RequestLogger returns a logger handler using a custom LogFormatter.

func SetEncoder Uses

func SetEncoder(encoding string, fn EncoderFunc)

SetEncoder can be used to set the implementation of a compression algorithm.

The encoding should be a standardised identifier. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding

For example, add the Brotli algortithm:

import brotli_enc "gopkg.in/kothar/brotli-go.v0/enc"

middleware.SetEncoder("br", func(w http.ResponseWriter, level int) io.Writer {
  params := brotli_enc.NewBrotliParams()
  params.SetQuality(level)
  return brotli_enc.NewBrotliWriter(params, w)
})

DEPRECATED

func SetHeader Uses

func SetHeader(key, value string) func(next http.Handler) http.Handler

SetHeader is a convenience handler to set a response header key/value

func StripSlashes Uses

func StripSlashes(next http.Handler) http.Handler

StripSlashes is a middleware that will match request paths with a trailing slash, strip it from the path and continue routing through the mux, if a route matches, then it will serve the handler.

func Throttle Uses

func Throttle(limit int) func(http.Handler) http.Handler

Throttle is a middleware that limits number of currently processed requests at a time across all users. Note: Throttle is not a rate-limiter per user, instead it just puts a ceiling on the number of currentl in-flight requests being processed from the point from where the Throttle middleware is mounted.

func ThrottleBacklog Uses

func ThrottleBacklog(limit int, backlogLimit int, backlogTimeout time.Duration) func(http.Handler) http.Handler

ThrottleBacklog is a middleware that limits number of currently processed requests at a time and provides a backlog for holding a finite number of pending requests.

func Timeout Uses

func Timeout(timeout time.Duration) func(next http.Handler) http.Handler

Timeout is a middleware that cancels ctx after a given timeout and return a 504 Gateway Timeout error to the client.

It's required that you select the ctx.Done() channel to check for the signal if the context has reached its deadline and return, otherwise the timeout signal will be just ignored.

ie. a route/handler may look like:

 r.Get("/long", func(w http.ResponseWriter, r *http.Request) {
	 ctx := r.Context()
	 processTime := time.Duration(rand.Intn(4)+1) * time.Second

	 select {
	 case <-ctx.Done():
	 	return

	 case <-time.After(processTime):
	 	 // The above channel simulates some hard work.
	 }

	 w.Write([]byte("done"))
 })

func URLFormat Uses

func URLFormat(next http.Handler) http.Handler

URLFormat is a middleware that parses the url extension from a request path and stores it on the context as a string under the key `middleware.URLFormatCtxKey`. The middleware will trim the suffix from the routing path and continue routing.

Routers should not include a url parameter for the suffix when using this middleware.

Sample usage.. for url paths: `/articles/1`, `/articles/1.json` and `/articles/1.xml`

 func routes() http.Handler {
   r := chi.NewRouter()
   r.Use(middleware.URLFormat)

   r.Get("/articles/{id}", ListArticles)

   return r
 }

 func ListArticles(w http.ResponseWriter, r *http.Request) {
	  urlFormat, _ := r.Context().Value(middleware.URLFormatCtxKey).(string)

	  switch urlFormat {
	  case "json":
	  	render.JSON(w, r, articles)
	  case "xml:"
	  	render.XML(w, r, articles)
	  default:
	  	render.JSON(w, r, articles)
	  }

}

func WithLogEntry Uses

func WithLogEntry(r *http.Request, entry LogEntry) *http.Request

WithLogEntry sets the in-context LogEntry for a request.

func WithValue Uses

func WithValue(key interface{}, val interface{}) func(next http.Handler) http.Handler

WithValue is a middleware that sets a given key/value in a context chain.

type Compressor Uses

type Compressor struct {
    // contains filtered or unexported fields
}

Compressor represents a set of encoding configurations.

func NewCompressor Uses

func NewCompressor(level int, types ...string) *Compressor

NewCompressor creates a new Compressor that will handle encoding responses.

The level should be one of the ones defined in the flate package. The types are the content types that are allowed to be compressed.

func (*Compressor) Handler Uses

func (c *Compressor) Handler() func(next http.Handler) http.Handler

Handler returns a new middleware that will compress the response based on the current Compressor.

func (*Compressor) SetEncoder Uses

func (c *Compressor) SetEncoder(encoding string, fn EncoderFunc)

SetEncoder can be used to set the implementation of a compression algorithm.

The encoding should be a standardised identifier. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding

For example, add the Brotli algortithm:

import brotli_enc "gopkg.in/kothar/brotli-go.v0/enc"

compressor := middleware.NewCompressor(5, "text/html")
compressor.SetEncoder("br", func(w http.ResponseWriter, level int) io.Writer {
  params := brotli_enc.NewBrotliParams()
  params.SetQuality(level)
  return brotli_enc.NewBrotliWriter(params, w)
})

type DefaultLogFormatter Uses

type DefaultLogFormatter struct {
    Logger  LoggerInterface
    NoColor bool
}

DefaultLogFormatter is a simple logger that implements a LogFormatter.

func (*DefaultLogFormatter) NewLogEntry Uses

func (l *DefaultLogFormatter) NewLogEntry(r *http.Request) LogEntry

NewLogEntry creates a new LogEntry for the request.

type EncoderFunc Uses

type EncoderFunc func(w io.Writer, level int) io.Writer

An EncoderFunc is a function that wraps the provided io.Writer with a streaming compression algorithm and returns it.

In case of failure, the function should return nil.

type LogEntry Uses

type LogEntry interface {
    Write(status, bytes int, elapsed time.Duration)
    Panic(v interface{}, stack []byte)
}

LogEntry records the final log when a request completes. See defaultLogEntry for an example implementation.

func GetLogEntry Uses

func GetLogEntry(r *http.Request) LogEntry

GetLogEntry returns the in-context LogEntry for a request.

type LogFormatter Uses

type LogFormatter interface {
    NewLogEntry(r *http.Request) LogEntry
}

LogFormatter initiates the beginning of a new LogEntry per request. See DefaultLogFormatter for an example implementation.

type LoggerInterface Uses

type LoggerInterface interface {
    Print(v ...interface{})
}

LoggerInterface accepts printing to stdlib logger or compatible logger.

type WrapResponseWriter Uses

type WrapResponseWriter interface {
    http.ResponseWriter
    // Status returns the HTTP status of the request, or 0 if one has not
    // yet been sent.
    Status() int
    // BytesWritten returns the total number of bytes sent to the client.
    BytesWritten() int
    // Tee causes the response body to be written to the given io.Writer in
    // addition to proxying the writes through. Only one io.Writer can be
    // tee'd to at once: setting a second one will overwrite the first.
    // Writes will be sent to the proxy before being written to this
    // io.Writer. It is illegal for the tee'd writer to be modified
    // concurrently with writes.
    Tee(io.Writer)
    // Unwrap returns the original proxied target.
    Unwrap() http.ResponseWriter
}

WrapResponseWriter is a proxy around an http.ResponseWriter that allows you to hook into various parts of the response process.

func NewWrapResponseWriter Uses

func NewWrapResponseWriter(w http.ResponseWriter, protoMajor int) WrapResponseWriter

NewWrapResponseWriter wraps an http.ResponseWriter, returning a proxy that allows you to hook into various parts of the response process.

Package middleware imports 23 packages (graph) and is imported by 411 packages. Updated 2019-10-03. Refresh now. Tools for package owners.