middleware

package
v1.1.19 Latest Latest
Warning

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

Go to latest
Published: Sep 20, 2024 License: MIT Imports: 31 Imported by: 0

README

middleware

Gin middleware plugin.


Example of use

logging middleware

You can set the maximum length for printing, add a request id field, ignore print path, customize zap log.

    import "github.com/18721889353/sunshine/pkg/gin/middleware"

    r := gin.Default()

    // default
    r.Use(middleware.Logging()) // simplified logging using middleware.SimpleLog()

    // --- or ---

    // custom
    r.Use(middleware.Logging(    // simplified logging using middleware.SimpleLog(WithRequestIDFromHeader())
        middleware.WithMaxLen(400),
        WithRequestIDFromHeader(),
        //WithRequestIDFromContext(),
        //middleware.WithLog(log), // custom zap log
        //middleware.WithIgnoreRoutes("/hello"),
    ))

Allow cross-domain requests middleware

    import "github.com/18721889353/sunshine/pkg/gin/middleware"

    r := gin.Default()
    r.Use(middleware.Cors())

rate limiter middleware

Adaptive flow limitation based on hardware resources.

    import "github.com/18721889353/sunshine/pkg/gin/middleware"

    r := gin.Default()

    // default
    r.Use(middleware.RateLimit())

    // --- or ---

    // custom
    r.Use(middleware.RateLimit(
        WithWindow(time.Second*10),
        WithBucket(100),
        WithCPUThreshold(100),
        WithCPUQuota(0.5),
    ))

Circuit Breaker middleware

    import "github.com/18721889353/sunshine/pkg/gin/middleware"

    r := gin.Default()
    r.Use(middleware.CircuitBreaker())

jwt authorization middleware

common authorization
import "github.com/18721889353/sunshine/pkg/jwt"
import "github.com/18721889353/sunshine/pkg/gin/middleware"

func main() {
    r := gin.Default()

    r.POST("/user/login", Login)
    r.GET("/user/:id", middleware.Auth(), h.GetByID) // no verify field
    // r.GET("/user/:id", middleware.Auth(middleware.WithVerify(adminVerify)), h.GetByID) // with verify field

    r.Run(serverAddr)
}

func adminVerify(claims *jwt.Claims, tokenTail10 string, c *gin.Context) error {
    if claims.Name != "admin" {
        return errors.New("verify failed")
    }

    // token := getToken(claims.UID) // from cache or database
    // if tokenTail10 != token[len(token)-10:] { return err }

    return nil
}

func Login(c *gin.Context) {
    // generate token
    token, err := jwt.GenerateToken("123", "admin")
    // save token
}

custom authorization
import "github.com/18721889353/sunshine/pkg/jwt"
import "github.com/18721889353/sunshine/pkg/gin/middleware"

func main() {
    r := gin.Default()

    r.POST("/user/login", Login)
    r.GET("/user/:id", middleware.AuthCustom(verify), h.GetByID)

    r.Run(serverAddr)
}

func verify(claims *jwt.CustomClaims, tokenTail10 string, c *gin.Context) error {
    err := errors.New("verify failed")

    // token, fields := getToken(id) // from cache or database
    // if tokenTail10 != token[len(token)-10:] { return err }
	
    id, exist := claims.Get("id")
    if !exist {
        return err
    }
    foo, exist := claims.Get("foo")
    if !exist {
        return err
    }
    if int(id.(float64)) != fields["id"].(int) ||
        foo.(string) != fields["foo"].(string) {
        return err
    }

    return nil
}

func Login(c *gin.Context) {
    // generate token
    fields := jwt.KV{"id": 123, "foo": "bar"}
    token, err := jwt.GenerateCustomToken(fields)
    // save token end fields
}

tracing middleware

import "github.com/18721889353/sunshine/pkg/tracer"
import "github.com/18721889353/sunshine/pkg/gin/middleware"

func InitTrace(serviceName string) {
	exporter, err := tracer.NewJaegerAgentExporter("192.168.3.37", "6831")
	if err != nil {
		panic(err)
	}

	resource := tracer.NewResource(
		tracer.WithServiceName(serviceName),
		tracer.WithEnvironment("dev"),
		tracer.WithServiceVersion("demo"),
	)

	tracer.Init(exporter, resource) // collect all by default
}

func NewRouter(
	r := gin.Default()
	r.Use(middleware.Tracing("your-service-name"))

	// ......
)

// if necessary, you can create a span in the program
func SpanDemo(serviceName string, spanName string, ctx context.Context) {
	_, span := otel.Tracer(serviceName).Start(
		ctx, spanName,
		trace.WithAttributes(attribute.String(spanName, time.Now().String())),
	)
	defer span.End()

	// ......
}

Metrics middleware

    import "github.com/18721889353/sunshine/pkg/gin/middleware/metrics"

    r := gin.Default()

    r.Use(metrics.Metrics(r,
        //metrics.WithMetricsPath("/demo/metrics"), // default is /metrics
        metrics.WithIgnoreStatusCodes(http.StatusNotFound), // ignore status codes
        //metrics.WithIgnoreRequestMethods(http.MethodHead),  // ignore request methods
        //metrics.WithIgnoreRequestPaths("/ping", "/health"), // ignore request paths
    ))

Request id

    import "github.com/18721889353/sunshine/pkg/gin/middleware"

    // Default request id
    r := gin.Default()
    r.Use(middleware.RequestID())

    // --- or ---

    // Customized request id key
    //r.User(middleware.RequestID(
    //    middleware.WithContextRequestIDKey("your ctx request id key"), // default is request_id
    //    middleware.WithHeaderRequestIDKey("your header request id key"), // default is X-Request-Id
    //))
    // If you change the ContextRequestIDKey, you have to set the same key name if you want to print the request id in the mysql logs as well.
    // example: 
    // db, err := mysql.Init(dsn,
        // mysql.WithLogRequestIDKey("your ctx request id key"),  // print request_id
        // ...
    // )

Timeout

    import "github.com/18721889353/sunshine/pkg/gin/middleware"

    r := gin.Default()

    // way1: global set timeout
    r.Use(middleware.Timeout(time.Second*5))

    // --- or ---

    // way2: router set timeout
    r.GET("/userExample/:id", middleware.Timeout(time.Second*3), h.GetByID)

    // Note: If timeout is set both globally and in the router, the minimum timeout prevails

Documentation

Overview

Package middleware is gin middleware plugin.

Index

Constants

View Source
const (
	// HeaderAuthorizationKey http header authorization key
	HeaderAuthorizationKey = "Authorization"
)

Variables

View Source
var (
	// ContextRequestIDKey request id for context
	ContextRequestIDKey = "request_id"

	// HeaderXRequestIDKey header request id key
	HeaderXRequestIDKey = "X-Request-Id"
)
View Source
var ErrLimitExceed = rl.ErrLimitExceed

ErrLimitExceed is returned when the rate limiter is triggered and the request is rejected due to limit exceeded.

ErrNotAllowed error not allowed.

View Source
var RequestHeaderKey = "request_header_key"

RequestHeaderKey request header key

RequestIDKey request_id

Functions

func AdaptCtx

func AdaptCtx(ctx context.Context) (*gin.Context, context.Context)

AdaptCtx adapt context, if ctx is gin.Context, return gin.Context and context of the transformation

func Auth

func Auth(opts ...JwtOption) gin.HandlerFunc

Auth authorization

func AuthCustom

func AuthCustom(verify VerifyCustomFn, opts ...JwtOption) gin.HandlerFunc

AuthCustom custom authentication

func CircuitBreaker

func CircuitBreaker(opts ...CircuitBreakerOption) gin.HandlerFunc

CircuitBreaker a circuit breaker middleware

func Cors

func Cors() gin.HandlerFunc

Cors cross domain

func CtxRequestID

func CtxRequestID(ctx context.Context) string

CtxRequestID get request id from context.Context

func CtxRequestIDField

func CtxRequestIDField(ctx context.Context) zap.Field

CtxRequestIDField get request id field from context.Context

func GCtxRequestID

func GCtxRequestID(c *gin.Context) string

GCtxRequestID get request id from gin.Context

func GCtxRequestIDField

func GCtxRequestIDField(c *gin.Context) zap.Field

GCtxRequestIDField get request id field from gin.Context

func GetFromCtx

func GetFromCtx(ctx context.Context, key string) interface{}

GetFromCtx get value from context

func GetFromHeader

func GetFromHeader(ctx context.Context, key string) string

GetFromHeader get value from header

func GetFromHeaders

func GetFromHeaders(ctx context.Context, key string) []string

GetFromHeaders get values from header

func HeaderRequestID

func HeaderRequestID(c *gin.Context) string

HeaderRequestID get request id from the header

func HeaderRequestIDField

func HeaderRequestIDField(c *gin.Context) zap.Field

HeaderRequestIDField get request id field from header

func Logging

func Logging(opts ...Option) gin.HandlerFunc

Logging print request and response info

func RateLimit

func RateLimit(opts ...RateLimitOption) gin.HandlerFunc

RateLimit an adaptive rate limiter middleware

func RequestID

func RequestID(opts ...RequestIDOption) gin.HandlerFunc

RequestID is an interceptor that injects a 'request id' into the context and request/response header of each request.

func SimpleLog

func SimpleLog(opts ...Option) gin.HandlerFunc

SimpleLog print response info

func Timeout

func Timeout(d time.Duration) gin.HandlerFunc

Timeout request time out

func Tracing

func Tracing(serviceName string, opts ...TraceOption) gin.HandlerFunc

Tracing returns interceptor that will trace incoming requests. The service parameter should describe the name of the (virtual) server handling the request.

func VerifySignatureMiddleware added in v1.0.2

func VerifySignatureMiddleware(signKey string) gin.HandlerFunc

func WrapCtx

func WrapCtx(c *gin.Context) context.Context

WrapCtx wrap context, put the Keys and Header of gin.Context into context

func XSSCrossMiddleware added in v1.0.2

func XSSCrossMiddleware() gin.HandlerFunc

Types

type CircuitBreakerOption

type CircuitBreakerOption func(*circuitBreakerOptions)

CircuitBreakerOption set the circuit breaker circuitBreakerOptions.

func WithDegradeHandler

func WithDegradeHandler(handler func(c *gin.Context)) CircuitBreakerOption

WithDegradeHandler set degrade handler function

func WithGroup

func WithGroup(g *group.Group) CircuitBreakerOption

WithGroup with circuit breaker group. NOTE: implements generics circuitbreaker.CircuitBreaker

func WithValidCode

func WithValidCode(code ...int) CircuitBreakerOption

WithValidCode http code to mark failed

type CtxKeyString

type CtxKeyString string

CtxKeyString for context.WithValue key type

type JwtOption

type JwtOption func(*jwtOptions)

JwtOption set the jwt options.

func WithSwitchHTTPCode

func WithSwitchHTTPCode() JwtOption

WithSwitchHTTPCode switch to http code

func WithVerify

func WithVerify(verify VerifyFn) JwtOption

WithVerify set verify function

type Option

type Option func(*options)

Option set the gin logger options.

func WithIgnoreRoutes

func WithIgnoreRoutes(routes ...string) Option

WithIgnoreRoutes no logger content routes

func WithLog

func WithLog(log *zap.Logger) Option

WithLog set log

func WithLogFrom added in v1.0.2

func WithLogFrom(logFrom string) Option

func WithMaxLen

func WithMaxLen(maxLen int) Option

WithMaxLen logger content max length

func WithRequestIDFromContext

func WithRequestIDFromContext() Option

WithRequestIDFromContext name is field in context, default value is request_id

func WithRequestIDFromHeader

func WithRequestIDFromHeader() Option

WithRequestIDFromHeader name is field in header, default value is X-Request-Id

type RateLimitOption

type RateLimitOption func(*rateLimitOptions)

RateLimitOption set the rate limits rateLimitOptions.

func WithBucket

func WithBucket(b int) RateLimitOption

WithBucket with bucket size.

func WithCPUQuota

func WithCPUQuota(quota float64) RateLimitOption

WithCPUQuota with real cpu quota(if it can not collect from process correct);

func WithCPUThreshold

func WithCPUThreshold(threshold int64) RateLimitOption

WithCPUThreshold with cpu threshold

func WithWindow

func WithWindow(d time.Duration) RateLimitOption

WithWindow with window size.

type RequestIDOption

type RequestIDOption func(*requestIDOptions)

RequestIDOption set the request id options.

func WithContextRequestIDKey

func WithContextRequestIDKey(key string) RequestIDOption

WithContextRequestIDKey set context request id key, minimum length of 4

func WithHeaderRequestIDKey

func WithHeaderRequestIDKey(key string) RequestIDOption

WithHeaderRequestIDKey set header request id key, minimum length of 4

func WithSnow added in v1.0.39

func WithSnow(snow *snowflake.Node) RequestIDOption

type TraceOption

type TraceOption func(*traceConfig)

TraceOption specifies instrumentation configuration options.

func WithPropagators

func WithPropagators(propagators propagation.TextMapPropagator) TraceOption

WithPropagators specifies propagators to use for extracting information from the HTTP requests. If none are specified, global ones will be used.

func WithTracerProvider

func WithTracerProvider(provider oteltrace.TracerProvider) TraceOption

WithTracerProvider specifies a tracer provider to use for creating a tracer. If none is specified, the global provider is used.

type VerifyCustomFn

type VerifyCustomFn func(claims *jwt.CustomClaims, tokenTail10 string, c *gin.Context) error

VerifyCustomFn verify custom function, tokenTail10 is the last 10 characters of the token.

type VerifyFn

type VerifyFn func(claims *jwt.Claims, tokenTail10 string, c *gin.Context) error

VerifyFn verify function, tokenTail10 is the last 10 characters of the token.

Directories

Path Synopsis
Package metrics is gin metrics library, collect five metrics, "uptime", "http_request_count_total", "http_request_duration_seconds", "http_request_size_bytes", "http_response_size_bytes".
Package metrics is gin metrics library, collect five metrics, "uptime", "http_request_count_total", "http_request_duration_seconds", "http_request_size_bytes", "http_response_size_bytes".

Jump to

Keyboard shortcuts

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