middleware

package
v4.1.3 Latest Latest
Warning

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

Go to latest
Published: Jan 18, 2024 License: MIT Imports: 12 Imported by: 2

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Authentication

func Authentication(authenticateFunc AuthenticateFunc, options ...AuthOption) httpware.Middleware

Authentication middleware delegate the authentication process to the AuthenticateFunc

func CorrelationId

func CorrelationId(options ...correlation_id.Option) httpware.Middleware

CorrelationId middleware get request id header if provided or generate a request id It will add the request ID to request context and add it to response header to

Example
// Example Need a random ephemeral port (to have a free port)
ln, err := net.Listen("tcp", ":0")
if err != nil {
	log.Fatal(err)
}

// we recommend to use MiddlewareStack to simplify managing all wanted middlewares
// caution middleware order matters
stack := httpware.MiddlewareStack(
	middleware.CorrelationId(
		correlation_id.WithHeaderName("my-personal-header-name"),
		correlation_id.WithIdGenerator(func(request *http.Request) string {
			return "my-fixed-request-id"
		}),
	),
)

srv := &http.Server{
	Handler: stack.DecorateHandler(http.NewServeMux()),
}
go func() {
	if err := srv.Serve(ln); err != nil {
		panic(err)
	}
}()

resp, err := http.Get("http://" + ln.Addr().String())
if err != nil {
	fmt.Println(err)
} else if resp != nil {
	fmt.Printf("%s: %v\n", "my-personal-header-name", resp.Header.Get("my-personal-header-name"))
}
Output:

my-personal-header-name: my-fixed-request-id

func DefaultCredentialFinder

func DefaultCredentialFinder(request *http.Request) auth.Credential

func DefaultErrorHandler

func DefaultErrorHandler(err error, writer http.ResponseWriter, _ *http.Request) bool

func DefaultRateLimitErrorCallback

func DefaultRateLimitErrorCallback(err error, writer http.ResponseWriter, _ *http.Request) bool

func Enable

func Enable(enable bool, middleware httpware.Middleware) httpware.Middleware

Enable middleware is used to conditionnaly add a middleware to a MiddlewareStack See Skip middleware to active a middleware in function of request

Example
// Example Need a random ephemeral port (to have a free port)
ln, err := net.Listen("tcp", ":0")
if err != nil {
	log.Fatal(err)
}

enableDummyMiddleware := true // or false
dummyMiddleware := func(next http.Handler) http.Handler {
	return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		request.Header.Set("FakeHeader", "this header is set when not /home url")
		next.ServeHTTP(writer, request)
	})
}
stack := httpware.MiddlewareStack(
	middleware.Enable(enableDummyMiddleware, dummyMiddleware),
)

// create a server in order to show it work
srv := &http.Server{
	Handler: stack.DecorateHandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		fmt.Println("server receive request with request:", request.Header.Get("FakeHeader"))
	}),
}
go func() {
	if err := srv.Serve(ln); err != nil {
		panic(err)
	}
}()

_, _ = http.Get("http://" + ln.Addr().String())
Output:

server receive request with request: this header is set when not /home url

func Interceptor

func Interceptor(options ...InterceptorOption) httpware.Middleware

Interceptor middleware allow multiple req.Body read and allow to set callback before and after roundtrip

func Metrics

func Metrics(recorder metrics.Recorder, options ...metrics.Option) httpware.Middleware
Example
// Example Need a random ephemeral port (to have a free port)
ln, err := net.Listen("tcp", ":0")
if err != nil {
	log.Fatal(err)
}

recorder := prom.NewRecorder(prom.Config{}).RegisterOn(nil)

// we recommend to use MiddlewareStack to simplify managing all wanted middleware
// caution middleware order matter
stack := httpware.MiddlewareStack(
	middleware.Metrics(recorder, metrics.WithIdentifierProvider(func(req *http.Request) string {
		return req.URL.Host + " -> " + req.URL.Path
	})),
)

// create a server in order to show it work
mux := http.NewServeMux()
mux.Handle("/metrics", stack.DecorateHandler(promhttp.Handler()))
srv := &http.Server{
	Handler: mux,
}
go func() {
	if err := srv.Serve(ln); err != nil {
		panic(err)
	}
}()

func RateLimit

func RateLimit(limiter rate_limit.RateLimiter, options ...RateLimitOption) httpware.Middleware
Example
// Example Need a random ephemeral port (to have a free port)
ln, err := net.Listen("tcp", ":0")
if err != nil {
	log.Fatal(err)
}

limiter := rate_limit.NewTokenBucket(1*time.Second, 1)
defer limiter.Stop()

// we recommend to use MiddlewareStack to simplify managing all wanted middlewares
// caution middleware order matters
stack := httpware.MiddlewareStack(
	middleware.RateLimit(limiter),
)

srv := &http.Server{
	Handler: stack.DecorateHandlerFunc(func(writer http.ResponseWriter, request *http.Request) {}),
}
go func() {
	if err := srv.Serve(ln); err != nil {
		panic(err)
	}
}()

resp, _ := http.Get("http://" + ln.Addr().String())
fmt.Println(resp.StatusCode)

resp, _ = http.Get("http://" + ln.Addr().String())
fmt.Println(resp.StatusCode)

time.Sleep(2 * time.Second)
resp, _ = http.Get("http://" + ln.Addr().String())
fmt.Println(resp.StatusCode)
Output:

200
429
200

func RequestListener

func RequestListener(listeners ...func(*http.Request)) httpware.Middleware

func Skip

func Skip(condition skip.Condition, middleware httpware.Middleware) httpware.Middleware

Skip middleware is used to conditionnaly activate a middleware in function of request See Enable middleware to conditionnaly add middleware to a stack

Example
// Example Need a random ephemeral port (to have a free port)
ln, err := net.Listen("tcp", ":0")
if err != nil {
	panic(err)
}

dummyMiddleware := func(next http.Handler) http.Handler {
	return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		request.Header.Set("FakeHeader", "this header is set when not /home url")
		next.ServeHTTP(writer, request)
	})
}
stack := httpware.MiddlewareStack(
	middleware.Skip(func(request *http.Request) bool {
		return request.URL.Path == "/home"
	}, dummyMiddleware),
)

srv := &http.Server{
	Handler: stack.DecorateHandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		fmt.Printf("server receive request %s with request: %s\n", request.URL.Path, request.Header.Get("FakeHeader"))
	}),
}
go func() {
	if err := srv.Serve(ln); err != nil {
		panic(err)
	}
}()

_, _ = http.Get("http://" + ln.Addr().String())
_, _ = http.Get("http://" + ln.Addr().String() + "/home")
Output:

server receive request / with request: this header is set when not /home url
server receive request /home with request:

Types

type AuthConfig

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

func NewAuthConfig

func NewAuthConfig(options ...AuthOption) *AuthConfig

type AuthFuncConfig

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

func NewAuthFuncConfig

func NewAuthFuncConfig(options ...AuthFuncOption) *AuthFuncConfig

type AuthFuncOption

type AuthFuncOption func(*AuthFuncConfig)

AuthFuncOption defines a AuthenticateFunc configuration option

func WithCredentialFinder

func WithCredentialFinder(credentialFinder CredentialFinder) AuthFuncOption

WithCredentialFinder will configure AuthenticateFunc option

type AuthOption

type AuthOption func(*AuthConfig)

AuthOption defines a interceptor middleware configuration option

func WithErrorHandler

func WithErrorHandler(errorHandler ErrorHandler) AuthOption

WithErrorHandler will configure ErrorHandler option

func WithSuccessMiddleware

func WithSuccessMiddleware(middleware httpware.Middleware) AuthOption

WithSuccessMiddleware will configure successMiddleware option

type AuthenticateFunc

type AuthenticateFunc func(req *http.Request) (*http.Request, error)

func NewAuthenticateFunc

func NewAuthenticateFunc(authenticator auth.Authenticator, options ...AuthFuncOption) AuthenticateFunc

NewAuthenticateFunc is an AuthenticateFunc that find, authenticate and hydrate credentials on the request context

type CredentialFinder

type CredentialFinder func(r *http.Request) auth.Credential

type ErrorHandler

type ErrorHandler func(err error, writer http.ResponseWriter, req *http.Request) bool

type InterceptorConfig

type InterceptorConfig struct {
	CallbackBefore func(*ResponseWriterInterceptor, *http.Request)
	CallbackAfter  func(*ResponseWriterInterceptor, *http.Request)
}

func NewInterceptorConfig

func NewInterceptorConfig(options ...InterceptorOption) *InterceptorConfig

NewInterceptorConfig returns a new interceptor middleware configuration with all options applied

type InterceptorOption

type InterceptorOption func(*InterceptorConfig)

InterceptorOption defines a interceptor middleware configuration option

func WithAfter

func WithAfter(callbackAfter func(*ResponseWriterInterceptor, *http.Request)) InterceptorOption

WithAfter will configure CallbackAfter interceptor option

func WithBefore

func WithBefore(callbackBefore func(*ResponseWriterInterceptor, *http.Request)) InterceptorOption

WithBefore will configure CallbackBefore interceptor option

type RateLimitConfig

type RateLimitConfig struct {
	ErrorCallback RateLimitErrorCallback
}

func NewRateLimitConfig

func NewRateLimitConfig(options ...RateLimitOption) *RateLimitConfig

type RateLimitErrorCallback

type RateLimitErrorCallback func(err error, writer http.ResponseWriter, req *http.Request) (next bool)

type RateLimitOption

type RateLimitOption func(*RateLimitConfig)

func WithRateLimitErrorCallback

func WithRateLimitErrorCallback(callback RateLimitErrorCallback) RateLimitOption

type ResponseWriterInterceptor

type ResponseWriterInterceptor struct {
	http.ResponseWriter
	StatusCode int
	Body       []byte
}

func NewResponseWriterInterceptor

func NewResponseWriterInterceptor(writer http.ResponseWriter) *ResponseWriterInterceptor

Jump to

Keyboard shortcuts

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