Documentation
¶
Overview ¶
Package throttle provides configurable middleware for throttling HTTP requests on the server side.
Example ¶
package main
import (
"bytes"
"fmt"
stdlog "log"
"net/http"
"net/http/httptest"
"regexp"
"strconv"
"time"
"github.com/acronis/go-appkit/config"
"github.com/acronis/go-appkit/httpserver/middleware/throttle"
)
const apiErrDomain = "MyService"
func main() {
configReader := bytes.NewReader([]byte(`
rateLimitZones:
rl_zone1:
rateLimit: 1/s
burstLimit: 0
responseStatusCode: 503
responseRetryAfter: auto
dryRun: false
rl_zone2:
rateLimit: 5/m
burstLimit: 0
responseStatusCode: 429
responseRetryAfter: auto
key:
type: "identity"
dryRun: false
inFlightLimitZones:
ifl_zone1:
inFlightLimit: 1
backlogLimit: 0
backlogTimeout: 15s
responseStatusCode: 503
dryRun: false
rules:
- routes:
- path: "/hello-world"
methods: GET
excludedRoutes:
- path: "/healthz"
rateLimits:
- zone: rl_zone1
tags: all_reqs
- routes:
- path: "= /long-work"
methods: POST
inFlightLimits:
- zone: ifl_zone1
tags: all_reqs
- routes:
- path: ~^/api/2/tenants/([\w\-]{36})/?$
methods: PUT
rateLimits:
- zone: rl_zone2
tags: authenticated_reqs
`))
configLoader := config.NewLoader(config.NewViperAdapter())
cfg := &throttle.Config{}
if err := configLoader.LoadFromReader(configReader, config.DataTypeYAML, cfg); err != nil {
stdlog.Fatal(err)
return
}
const longWorkDelay = time.Second
srv, err := makeExampleTestServer(cfg, longWorkDelay)
if err != nil {
stdlog.Fatal(err)
return
}
defer srv.Close()
// Rate limiting.
// 1st request finished successfully.
resp1, _ := http.Get(srv.URL + "/hello-world")
_ = resp1.Body.Close()
fmt.Println("[1] GET /hello-world " + strconv.Itoa(resp1.StatusCode))
// 2nd request is throttled.
resp2, _ := http.Get(srv.URL + "/hello-world")
_ = resp2.Body.Close()
fmt.Println("[2] GET /hello-world " + strconv.Itoa(resp2.StatusCode))
// In-flight limiting.
// 3rd request finished successfully.
resp3code := make(chan int)
go func() {
resp3, _ := http.Post(srv.URL+"/long-work", "", nil)
_ = resp3.Body.Close()
resp3code <- resp3.StatusCode
}()
time.Sleep(longWorkDelay / 2)
// 4th request is throttled.
resp4, _ := http.Post(srv.URL+"/long-work", "", nil)
_ = resp4.Body.Close()
fmt.Println("[3] POST /long-work " + strconv.Itoa(<-resp3code))
fmt.Println("[4] POST /long-work " + strconv.Itoa(resp4.StatusCode))
// Unmatched (unspecified) routes are not limited.
resp5code := make(chan int)
go func() {
resp5, _ := http.Post(srv.URL+"/long-work-without-limits", "", nil)
_ = resp5.Body.Close()
resp5code <- resp5.StatusCode
}()
time.Sleep(longWorkDelay / 2)
resp6, _ := http.Post(srv.URL+"/long-work", "", nil)
_ = resp6.Body.Close()
fmt.Println("[5] POST /long-work-without-limits " + strconv.Itoa(<-resp5code))
fmt.Println("[6] POST /long-work-without-limits " + strconv.Itoa(resp6.StatusCode))
// Throttle authenticated requests by username from basic auth.
const tenantPath = "/api/2/tenants/446507ba-2f9b-4347-adbc-63581383ba25"
doReqWithBasicAuth := func(username string) *http.Response {
req, _ := http.NewRequest(http.MethodPut, srv.URL+tenantPath, http.NoBody)
req.SetBasicAuth(username, username+"-password")
resp, _ := http.DefaultClient.Do(req)
return resp
}
// 7th request is not throttled.
resp7 := doReqWithBasicAuth("ba27afb7-ad60-4077-956e-366e77358b92")
_ = resp7.Body.Close()
fmt.Printf("[7] PUT %s %d\n", tenantPath, resp7.StatusCode)
// 8th request is throttled (the same username as in the previous request, and it's rate-limited).
resp8 := doReqWithBasicAuth("ba27afb7-ad60-4077-956e-366e77358b92")
_ = resp8.Body.Close()
fmt.Printf("[8] PUT %s %d\n", tenantPath, resp8.StatusCode)
// 9th request is not throttled (the different username is used).
resp9 := doReqWithBasicAuth("97d8d1e6-948d-4c41-91d6-495dcc8c7b1a")
_ = resp9.Body.Close()
fmt.Printf("[9] PUT %s %d\n", tenantPath, resp9.StatusCode)
}
func makeExampleTestServer(cfg *throttle.Config, longWorkDelay time.Duration) (*httptest.Server, error) {
promMetrics := throttle.NewPrometheusMetrics()
promMetrics.MustRegister()
defer promMetrics.Unregister()
// Configure middleware that should do global throttling ("all_reqs" tag says about that).
globalThrottleMiddleware, err := throttle.MiddlewareWithOpts(cfg, apiErrDomain, promMetrics, throttle.MiddlewareOpts{
Tags: []string{"all_reqs"}})
if err != nil {
return nil, fmt.Errorf("create global throttling middleware: %w", err)
}
// Configure middleware that should do per-client throttling based on the username from basic auth ("authenticated_reqs" tag says about that).
clientThrottleMiddleware, err := throttle.MiddlewareWithOpts(cfg, apiErrDomain, promMetrics, throttle.MiddlewareOpts{
Tags: []string{"authenticated_reqs"},
GetKeyIdentity: func(r *http.Request) (key string, bypass bool, err error) {
username, _, ok := r.BasicAuth()
if !ok {
return "", true, fmt.Errorf("no basic auth")
}
return username, false, nil
},
})
if err != nil {
return nil, fmt.Errorf("create client throttling middleware: %w", err)
}
restoreTenantPathRegExp := regexp.MustCompile(`^/api/2/tenants/([\w-]{36})/?$`)
return httptest.NewServer(globalThrottleMiddleware(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/long-work":
if r.Method != http.MethodPost {
rw.WriteHeader(http.StatusMethodNotAllowed)
return
}
time.Sleep(longWorkDelay) // Emulate long work.
rw.WriteHeader(http.StatusOK)
return
case "/hello-world":
if r.Method != http.MethodGet {
rw.WriteHeader(http.StatusMethodNotAllowed)
return
}
rw.WriteHeader(http.StatusOK)
_, _ = rw.Write([]byte("Hello world!"))
return
case "/long-work-without-limits":
if r.Method != http.MethodPost {
rw.WriteHeader(http.StatusMethodNotAllowed)
return
}
time.Sleep(longWorkDelay) // Emulate long work.
rw.WriteHeader(http.StatusOK)
return
}
if restoreTenantPathRegExp.MatchString(r.URL.Path) {
if r.Method != http.MethodPut {
rw.WriteHeader(http.StatusMethodNotAllowed)
return
}
clientThrottleMiddleware(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.WriteHeader(http.StatusNoContent)
})).ServeHTTP(rw, r)
return
}
rw.WriteHeader(http.StatusNotFound)
}))), nil
}
Output: [1] GET /hello-world 200 [2] GET /hello-world 503 [3] POST /long-work 200 [4] POST /long-work 503 [5] POST /long-work-without-limits 200 [6] POST /long-work-without-limits 200 [7] PUT /api/2/tenants/446507ba-2f9b-4347-adbc-63581383ba25 204 [8] PUT /api/2/tenants/446507ba-2f9b-4347-adbc-63581383ba25 429 [9] PUT /api/2/tenants/446507ba-2f9b-4347-adbc-63581383ba25 204
Index ¶
- Constants
- func InFlightLimitMiddleware(cfg *InFlightLimitZoneConfig, errDomain string, ruleName string, ...) (func(next http.Handler) http.Handler, error)
- func InFlightLimitMiddlewareWithOpts(cfg *InFlightLimitZoneConfig, errDomain string, ruleName string, ...) (func(next http.Handler) http.Handler, error)
- func MapstructureDecodeHook() mapstructure.DecodeHookFunc
- func Middleware(cfg *Config, errDomain string, mc MetricsCollector) (func(next http.Handler) http.Handler, error)
- func MiddlewareWithOpts(cfg *Config, errDomain string, mc MetricsCollector, opts MiddlewareOpts) (func(next http.Handler) http.Handler, error)
- func RateLimitMiddleware(cfg *RateLimitZoneConfig, errDomain string, ruleName string, ...) (func(next http.Handler) http.Handler, error)
- func RateLimitMiddlewareWithOpts(cfg *RateLimitZoneConfig, errDomain string, ruleName string, ...) (func(next http.Handler) http.Handler, error)
- type Config
- type ConfigOption
- type InFlightLimitMiddlewareOpts
- type InFlightLimitZoneConfig
- type MetricsCollector
- type MiddlewareOpts
- type PrometheusMetrics
- func (pm *PrometheusMetrics) IncInFlightLimitRejects(ruleName string, dryRun bool, backlogged bool)
- func (pm *PrometheusMetrics) IncRateLimitRejects(ruleName string, dryRun bool)
- func (pm *PrometheusMetrics) MustCurryWith(labels prometheus.Labels) *PrometheusMetrics
- func (pm *PrometheusMetrics) MustRegister()
- func (pm *PrometheusMetrics) Unregister()
- type PrometheusMetricsOpts
- type RateLimitMiddlewareOpts
- type RateLimitRetryAfterValue
- type RateLimitValue
- type RateLimitZoneConfig
- type RuleConfig
- type RuleInFlightLimit
- type RuleRateLimit
- type TagsList
- type ZoneConfig
- type ZoneKeyConfig
- type ZoneKeyType
Examples ¶
Constants ¶
const ( RateLimitAlgLeakyBucket = "leaky_bucket" RateLimitAlgSlidingWindow = "sliding_window" )
Rate-limiting algorithms.
const RuleLogFieldName = "throttle_rule"
RuleLogFieldName is a logged field that contains the name of the throttling rule.
Variables ¶
This section is empty.
Functions ¶
func InFlightLimitMiddleware ¶ added in v1.16.0
func InFlightLimitMiddleware( cfg *InFlightLimitZoneConfig, errDomain string, ruleName string, mc MetricsCollector, ) (func(next http.Handler) http.Handler, error)
InFlightLimitMiddleware is a middleware that performs in-flight limiting based on the passed configuration.
func InFlightLimitMiddlewareWithOpts ¶ added in v1.16.0
func InFlightLimitMiddlewareWithOpts( cfg *InFlightLimitZoneConfig, errDomain string, ruleName string, mc MetricsCollector, opts InFlightLimitMiddlewareOpts, ) (func(next http.Handler) http.Handler, error)
InFlightLimitMiddlewareWithOpts is a more configurable version of InFlightLimitMiddleware.
func MapstructureDecodeHook ¶ added in v1.11.0
func MapstructureDecodeHook() mapstructure.DecodeHookFunc
MapstructureDecodeHook returns a DecodeHookFunc for mapstructure to handle custom types.
func Middleware ¶
func Middleware(cfg *Config, errDomain string, mc MetricsCollector) (func(next http.Handler) http.Handler, error)
Middleware is a middleware that throttles incoming HTTP requests based on the passed configuration.
func MiddlewareWithOpts ¶
func MiddlewareWithOpts( cfg *Config, errDomain string, mc MetricsCollector, opts MiddlewareOpts, ) (func(next http.Handler) http.Handler, error)
MiddlewareWithOpts is a more configurable version of Middleware.
func RateLimitMiddleware ¶ added in v1.16.0
func RateLimitMiddleware( cfg *RateLimitZoneConfig, errDomain string, ruleName string, mc MetricsCollector, ) (func(next http.Handler) http.Handler, error)
RateLimitMiddleware is a middleware that performs rate limiting based on the passed configuration.
func RateLimitMiddlewareWithOpts ¶ added in v1.16.0
func RateLimitMiddlewareWithOpts( cfg *RateLimitZoneConfig, errDomain string, ruleName string, mc MetricsCollector, opts RateLimitMiddlewareOpts, ) (func(next http.Handler) http.Handler, error)
RateLimitMiddlewareWithOpts is a more configurable version of RateLimitMiddleware.
Types ¶
type Config ¶
type Config struct {
// RateLimitZones contains rate limiting zones.
// Key is a zone's name, and value is a zone's configuration.
RateLimitZones map[string]RateLimitZoneConfig `mapstructure:"rateLimitZones" yaml:"rateLimitZones" json:"rateLimitZones"`
// InFlightLimitZones contains in-flight limiting zones.
// Key is a zone's name, and value is a zone's configuration.
InFlightLimitZones map[string]InFlightLimitZoneConfig `mapstructure:"inFlightLimitZones" yaml:"inFlightLimitZones" json:"inFlightLimitZones"` // nolint: lll
// Rules contains list of so-called throttling rules.
// Basically, throttling rule represents a route (or multiple routes),
// and rate/in-flight limiting zones based on which all matched HTTP requests will be throttled.
Rules []RuleConfig `mapstructure:"rules" yaml:"rules" json:"rules"`
// contains filtered or unexported fields
}
Config represents a configuration for throttling of HTTP requests on the server side. Configuration can be loaded in different formats (YAML, JSON) using config.Loader, viper, or with json.Unmarshal/yaml.Unmarshal functions directly.
func NewConfig ¶
func NewConfig(options ...ConfigOption) *Config
NewConfig creates a new instance of the Config.
func NewConfigWithKeyPrefix ¶
NewConfigWithKeyPrefix creates a new instance of the Config with a key prefix. This prefix will be used by config.Loader. Deprecated: use NewConfig with WithKeyPrefix instead.
func (*Config) KeyPrefix ¶
KeyPrefix returns a key prefix with which all configuration parameters should be presented. Implements config.KeyPrefixProvider interface.
func (*Config) Set ¶
func (c *Config) Set(dp config.DataProvider) error
Set sets throttling configuration values from config.DataProvider. Implements config.Config interface.
func (*Config) SetProviderDefaults ¶
func (c *Config) SetProviderDefaults(_ config.DataProvider)
SetProviderDefaults sets default configuration values for logger in config.DataProvider. Implements config.Config interface.
type ConfigOption ¶ added in v1.11.0
type ConfigOption func(*configOptions)
ConfigOption is a type for functional options for the Config.
func WithKeyPrefix ¶ added in v1.11.0
func WithKeyPrefix(keyPrefix string) ConfigOption
WithKeyPrefix returns a ConfigOption that sets a key prefix for parsing configuration parameters. This prefix will be used by config.Loader.
type InFlightLimitMiddlewareOpts ¶ added in v1.16.0
type InFlightLimitMiddlewareOpts struct {
// GetKeyIdentity is a function that returns identity string representation.
// The returned string is used as a key for zone when key.type is "identity".
GetKeyIdentity func(r *http.Request) (key string, bypass bool, err error)
// InFlightLimitOnReject is a callback that is called for rejecting HTTP request when the in-flight limit is exceeded.
InFlightLimitOnReject middleware.InFlightLimitOnRejectFunc
// RateLimitOnRejectInDryRun is a callback that is called for rejecting HTTP request in the dry-run mode
// when the in-flight limit is exceeded.
InFlightLimitOnRejectInDryRun middleware.InFlightLimitOnRejectFunc
// RateLimitOnError is a callback that is called in case of any error that may occur during the in-flight limiting.
InFlightLimitOnError middleware.InFlightLimitOnErrorFunc
}
type InFlightLimitZoneConfig ¶
type InFlightLimitZoneConfig struct {
ZoneConfig `mapstructure:",squash" yaml:",inline"`
InFlightLimit int `mapstructure:"inFlightLimit" yaml:"inFlightLimit" json:"inFlightLimit"`
BacklogLimit int `mapstructure:"backlogLimit" yaml:"backlogLimit" json:"backlogLimit"`
BacklogTimeout config.TimeDuration `mapstructure:"backlogTimeout" yaml:"backlogTimeout" json:"backlogTimeout"`
ResponseRetryAfter config.TimeDuration `mapstructure:"responseRetryAfter" yaml:"responseRetryAfter" json:"responseRetryAfter"`
}
InFlightLimitZoneConfig represents zone configuration for in-flight limiting.
func (*InFlightLimitZoneConfig) Validate ¶
func (c *InFlightLimitZoneConfig) Validate() error
Validate validates zone configuration for in-flight limiting.
type MetricsCollector ¶
type MetricsCollector interface {
// IncInFlightLimitRejects increments the counter of rejected requests due to in-flight limit exceeded.
IncInFlightLimitRejects(ruleName string, dryRun bool, backlogged bool)
// IncRateLimitRejects increments the counter of rejected requests due to rate limit exceeded.
IncRateLimitRejects(ruleName string, dryRun bool)
}
MetricsCollector represents a collector of metrics for rate/in-flight limiting rejects.
type MiddlewareOpts ¶
type MiddlewareOpts struct {
// GetKeyIdentity is a function that returns identity string representation.
// The returned string is used as a key for zone when key.type is "identity".
GetKeyIdentity func(r *http.Request) (key string, bypass bool, err error)
// RateLimitOnReject is a callback called for rejecting HTTP request when the rate limit is exceeded.
RateLimitOnReject middleware.RateLimitOnRejectFunc
// RateLimitOnRejectInDryRun is a callback called for rejecting HTTP request in the dry-run mode
// when the rate limit is exceeded.
RateLimitOnRejectInDryRun middleware.RateLimitOnRejectFunc
// RateLimitOnError is a callback called in case of any error that may occur during the rate limiting.
RateLimitOnError middleware.RateLimitOnErrorFunc
// InFlightLimitOnReject is a callback called for rejecting HTTP request when the in-flight limit is exceeded.
InFlightLimitOnReject middleware.InFlightLimitOnRejectFunc
// RateLimitOnRejectInDryRun is a callback called for rejecting HTTP request in the dry-run mode
// when the in-flight limit is exceeded.
InFlightLimitOnRejectInDryRun middleware.InFlightLimitOnRejectFunc
// RateLimitOnError is a callback called in case of any error that may occur during the in-flight limiting.
InFlightLimitOnError middleware.InFlightLimitOnErrorFunc
// Tags is a list of tags for filtering throttling rules from the config. If it's empty, all rules can be applied.
Tags []string
// BuildHandlerAtInit determines where the final handler will be constructed.
// If true, it will be done at the initialization step (i.e., in the constructor),
// false (default) - right in the ServeHTTP() method (gorilla/mux case).
BuildHandlerAtInit bool
}
MiddlewareOpts represents an options for Middleware.
func (MiddlewareOpts) InFlightLimitOpts ¶
func (opts MiddlewareOpts) InFlightLimitOpts() InFlightLimitMiddlewareOpts
InFlightLimitOpts returns options for constructing in-flight limiting middleware.
func (MiddlewareOpts) RateLimitOpts ¶
func (opts MiddlewareOpts) RateLimitOpts() RateLimitMiddlewareOpts
RateLimitOpts returns options for constructing rate limiting middleware.
type PrometheusMetrics ¶ added in v1.3.0
type PrometheusMetrics struct {
InFlightLimitRejects *prometheus.CounterVec
RateLimitRejects *prometheus.CounterVec
}
PrometheusMetrics represents a collector of Prometheus metrics for rate/in-flight limiting rejects.
func NewPrometheusMetrics ¶ added in v1.3.0
func NewPrometheusMetrics() *PrometheusMetrics
NewPrometheusMetrics creates a new instance of PrometheusMetrics.
func NewPrometheusMetricsWithOpts ¶ added in v1.3.0
func NewPrometheusMetricsWithOpts(opts PrometheusMetricsOpts) *PrometheusMetrics
NewPrometheusMetricsWithOpts creates a new instance of PrometheusMetrics with the provided options.
func (*PrometheusMetrics) IncInFlightLimitRejects ¶ added in v1.3.0
func (pm *PrometheusMetrics) IncInFlightLimitRejects(ruleName string, dryRun bool, backlogged bool)
IncInFlightLimitRejects increments the counter of rejected requests due to in-flight limit exceeded.
func (*PrometheusMetrics) IncRateLimitRejects ¶ added in v1.3.0
func (pm *PrometheusMetrics) IncRateLimitRejects(ruleName string, dryRun bool)
IncRateLimitRejects increments the counter of rejected requests due to rate limit exceeded.
func (*PrometheusMetrics) MustCurryWith ¶ added in v1.3.0
func (pm *PrometheusMetrics) MustCurryWith(labels prometheus.Labels) *PrometheusMetrics
MustCurryWith curries the metrics collector with the provided labels.
func (*PrometheusMetrics) MustRegister ¶ added in v1.3.0
func (pm *PrometheusMetrics) MustRegister()
MustRegister does registration of metrics collector in Prometheus and panics if any error occurs.
func (*PrometheusMetrics) Unregister ¶ added in v1.3.0
func (pm *PrometheusMetrics) Unregister()
Unregister cancels registration of metrics collector in Prometheus.
type PrometheusMetricsOpts ¶ added in v1.3.0
type PrometheusMetricsOpts struct {
// Namespace is a namespace for metrics. It will be prepended to all metric names.
Namespace string
// ConstLabels is a set of labels that will be applied to all metrics.
ConstLabels prometheus.Labels
// CurriedLabelNames is a list of label names that will be curried with the provided labels.
// See PrometheusMetrics.MustCurryWith method for more details.
// Keep in mind that if this list is not empty,
// PrometheusMetrics.MustCurryWith method must be called further with the same labels.
// Otherwise, the collector will panic.
CurriedLabelNames []string
}
PrometheusMetricsOpts represents options for PrometheusMetrics.
type RateLimitMiddlewareOpts ¶ added in v1.16.0
type RateLimitMiddlewareOpts struct {
// GetKeyIdentity is a function that returns identity string representation.
// The returned string is used as a key for zone when key.type is "identity".
GetKeyIdentity func(r *http.Request) (key string, bypass bool, err error)
// RateLimitOnReject is a callback that is called for rejecting HTTP request when the rate limit is exceeded.
RateLimitOnReject middleware.RateLimitOnRejectFunc
// RateLimitOnRejectInDryRun is a callback that is called for rejecting HTTP request in the dry-run mode
// when the rate limit is exceeded.
RateLimitOnRejectInDryRun middleware.RateLimitOnRejectFunc
// RateLimitOnError is a callback that is called in case of any error that may occur during the rate limiting.
RateLimitOnError middleware.RateLimitOnErrorFunc
}
RateLimitMiddlewareOpts represents an options for RateLimitMiddleware.
type RateLimitRetryAfterValue ¶
RateLimitRetryAfterValue represents structured retry-after value for rate limiting.
func (RateLimitRetryAfterValue) String ¶ added in v1.11.0
func (ra RateLimitRetryAfterValue) String() string
String returns a string representation of the retry-after value. Implements fmt.Stringer interface.
func (*RateLimitRetryAfterValue) UnmarshalJSON ¶ added in v1.11.0
func (ra *RateLimitRetryAfterValue) UnmarshalJSON(data []byte) error
UnmarshalJSON implements the json.Unmarshaler interface. Implements the json.Unmarshaler interface.
func (*RateLimitRetryAfterValue) UnmarshalText ¶
func (ra *RateLimitRetryAfterValue) UnmarshalText(text []byte) error
UnmarshalText implements the encoding.TextUnmarshaler interface. Implements the encoding.TextUnmarshaler interface which is used by mapstructure.TextUnmarshallerHookFunc.
func (*RateLimitRetryAfterValue) UnmarshalYAML ¶ added in v1.11.0
func (ra *RateLimitRetryAfterValue) UnmarshalYAML(value *yaml.Node) error
UnmarshalYAML implements the yaml.Unmarshaler interface. Implements the yaml.Unmarshaler interface.
type RateLimitValue ¶
RateLimitValue represents value for rate limiting.
func (RateLimitValue) String ¶ added in v1.11.0
func (rl RateLimitValue) String() string
String returns a string representation of the rate limit value. Implements fmt.Stringer interface.
func (*RateLimitValue) UnmarshalJSON ¶ added in v1.11.0
func (rl *RateLimitValue) UnmarshalJSON(data []byte) error
UnmarshalJSON implements the json.Unmarshaler interface. Implements the json.Unmarshaler interface.
func (*RateLimitValue) UnmarshalText ¶
func (rl *RateLimitValue) UnmarshalText(text []byte) error
UnmarshalText implements the encoding.TextUnmarshaler interface. Implements the encoding.TextUnmarshaler interface which is used by mapstructure.TextUnmarshallerHookFunc.
func (*RateLimitValue) UnmarshalYAML ¶ added in v1.11.0
func (rl *RateLimitValue) UnmarshalYAML(value *yaml.Node) error
UnmarshalYAML implements the yaml.Unmarshaler interface. Implements the yaml.Unmarshaler interface.
type RateLimitZoneConfig ¶
type RateLimitZoneConfig struct {
ZoneConfig `mapstructure:",squash" yaml:",inline"`
Alg string `mapstructure:"alg" yaml:"alg" json:"alg"`
RateLimit RateLimitValue `mapstructure:"rateLimit" yaml:"rateLimit" json:"rateLimit"`
BurstLimit int `mapstructure:"burstLimit" yaml:"burstLimit" json:"burstLimit"`
BacklogLimit int `mapstructure:"backlogLimit" yaml:"backlogLimit" json:"backlogLimit"`
BacklogTimeout config.TimeDuration `mapstructure:"backlogTimeout" yaml:"backlogTimeout" json:"backlogTimeout"`
ResponseRetryAfter RateLimitRetryAfterValue `mapstructure:"responseRetryAfter" yaml:"responseRetryAfter" json:"responseRetryAfter"`
}
RateLimitZoneConfig represents zone configuration for rate limiting.
func (*RateLimitZoneConfig) Validate ¶
func (c *RateLimitZoneConfig) Validate() error
Validate validates zone configuration for rate limiting.
type RuleConfig ¶
type RuleConfig struct {
// Alias is an alternative name for the rule. It will be used as a label in metrics.
Alias string `mapstructure:"alias" yaml:"alias" json:"alias"`
// Routes contains a list of routes (HTTP verb + URL path) for which the rule will be applied.
Routes []restapi.RouteConfig `mapstructure:"routes" yaml:"routes" json:"routes"`
// ExcludedRoutes contains list of routes (HTTP verb + URL path) to be excluded from throttling limitations.
// The following service endpoints fit should typically be added to this list:
// - healthcheck endpoint serving as readiness probe
// - status endpoint serving as liveness probe
ExcludedRoutes []restapi.RouteConfig `mapstructure:"excludedRoutes" yaml:"excludedRoutes" json:"excludedRoutes"`
// Tags is useful when the different rules of the same config should be used by different middlewares.
// As example let's suppose we would like to have 2 different throttling rules:
// 1) for absolutely all requests;
// 2) for all identity-aware (authorized) requests.
// In the code, we will have 2 middlewares that will be executed on the different steps of the HTTP request serving,
// and each one should do only its own throttling.
// We can achieve this using different tags for rules and passing needed tag in the MiddlewareOpts.
Tags TagsList `mapstructure:"tags" yaml:"tags" json:"tags"`
// RateLimits contains a list of the rate limiting zones that are used in the rule.
RateLimits []RuleRateLimit `mapstructure:"rateLimits" yaml:"rateLimits" json:"rateLimits"`
// InFlightLimits contains a list of the in-flight limiting zones that are used in the rule.
InFlightLimits []RuleInFlightLimit `mapstructure:"inFlightLimits" yaml:"inFlightLimits" json:"inFlightLimits"`
}
RuleConfig represents configuration for throttling rule.
func (*RuleConfig) Validate ¶
func (c *RuleConfig) Validate( rateLimitZones map[string]RateLimitZoneConfig, inFlightLimitZones map[string]InFlightLimitZoneConfig, ) error
Validate validates throttling rule configuration.
type RuleInFlightLimit ¶
type RuleInFlightLimit struct {
Zone string `mapstructure:"zone" yaml:"zone"`
}
RuleInFlightLimit represents rule's in-flight limiting parameters.
type RuleRateLimit ¶
type RuleRateLimit struct {
Zone string `mapstructure:"zone" yaml:"zone"`
}
RuleRateLimit represents rule's rate limiting parameters.
type TagsList ¶ added in v1.11.0
type TagsList []string
TagsList represents a list of tags.
func (*TagsList) UnmarshalJSON ¶ added in v1.11.0
UnmarshalJSON implements the json.Unmarshaler interface.
func (*TagsList) UnmarshalText ¶ added in v1.11.0
UnmarshalText implements the encoding.TextUnmarshaler interface.
type ZoneConfig ¶
type ZoneConfig struct {
Key ZoneKeyConfig `mapstructure:"key" yaml:"key" json:"key"`
MaxKeys int `mapstructure:"maxKeys" yaml:"maxKeys" json:"maxKeys"`
ResponseStatusCode int `mapstructure:"responseStatusCode" yaml:"responseStatusCode" json:"responseStatusCode"`
DryRun bool `mapstructure:"dryRun" yaml:"dryRun" json:"dryRun"`
IncludedKeys []string `mapstructure:"includedKeys" yaml:"includedKeys" json:"includedKeys"`
ExcludedKeys []string `mapstructure:"excludedKeys" yaml:"excludedKeys" json:"excludedKeys"`
}
ZoneConfig represents a basic zone configuration.
func (*ZoneConfig) Validate ¶
func (c *ZoneConfig) Validate() error
Validate validates zone configuration.
type ZoneKeyConfig ¶
type ZoneKeyConfig struct {
// Type determines type of key that will be used for throttling.
Type ZoneKeyType `mapstructure:"type" yaml:"type" json:"type"`
// HeaderName is a name of the HTTP request header which value will be used as a key.
// Matters only when Type is a "header".
HeaderName string `mapstructure:"headerName" yaml:"headerName" json:"headerName"`
// NoBypassEmpty specifies whether throttling will be used if the value obtained by the key is empty.
NoBypassEmpty bool `mapstructure:"noBypassEmpty" yaml:"noBypassEmpty" json:"noBypassEmpty"`
}
ZoneKeyConfig represents a configuration of zone's key.
func (*ZoneKeyConfig) Validate ¶
func (c *ZoneKeyConfig) Validate() error
Validate validates keys zone configuration.
type ZoneKeyType ¶
type ZoneKeyType string
ZoneKeyType is a type of keys zone.
const ( ZoneKeyTypeNoKey ZoneKeyType = "" ZoneKeyTypeIdentity ZoneKeyType = "identity" ZoneKeyTypeHTTPHeader ZoneKeyType = "header" ZoneKeyTypeRemoteAddr ZoneKeyType = "remote_addr" )
Zone key types.