-
Notifications
You must be signed in to change notification settings - Fork 7
/
ratelimit.go
168 lines (143 loc) · 4.87 KB
/
ratelimit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package repo
import "github.com/flomesh-io/fsm/pkg/apis/policy/v1alpha1"
// TCPRateLimit defines the rate limiting specification for
// the upstream host.
type TCPRateLimit struct {
// Local specified the local rate limiting specification
// for the upstream host.
// Local rate limiting is enforced directly by the upstream
// host without any involvement of a global rate limiting service.
// This is applied as a token bucket rate limiter.
// +optional
Local *TCPLocalRateLimit `json:"Local,omitempty"`
}
// HTTPRateLimit defines the rate limiting specification for
// the upstream host.
type HTTPRateLimit struct {
// Local specified the local rate limiting specification
// for the upstream host.
// Local rate limiting is enforced directly by the upstream
// host without any involvement of a global rate limiting service.
// This is applied as a token bucket rate limiter.
// +optional
Local *HTTPLocalRateLimit `json:"Local,omitempty"`
}
func newTCPRateLimit(spec *v1alpha1.LocalRateLimitSpec) *TCPRateLimit {
if spec == nil || spec.TCP == nil {
return nil
}
lrl := new(TCPRateLimit)
lrl.Local = newTCPLocalRateLimit(spec.TCP)
return lrl
}
func newHTTPRateLimit(spec *v1alpha1.LocalRateLimitSpec) *HTTPRateLimit {
if spec == nil || spec.HTTP == nil {
return nil
}
lrl := new(HTTPRateLimit)
lrl.Local = newHTTPLocalRateLimit(spec.HTTP)
return lrl
}
// TCPLocalRateLimit defines the local rate limiting specification
// for the upstream host at the TCP level.
type TCPLocalRateLimit struct {
// Connections defines the number of connections allowed
// per unit of time before rate limiting occurs.
Connections uint32 `json:"Connections"`
// StatTimeWindow specifies statistical time period of local rate limit
StatTimeWindow float64 `json:"StatTimeWindow"`
// Burst defines the number of connections above the baseline
// rate that are allowed in a short period of time.
// +optional
Burst uint32 `json:"Burst,omitempty"`
}
func newTCPLocalRateLimit(spec *v1alpha1.TCPLocalRateLimitSpec) *TCPLocalRateLimit {
if spec == nil {
return nil
}
lrl := new(TCPLocalRateLimit)
lrl.Connections = spec.Connections
lrl.Burst = spec.Burst
switch spec.Unit {
case `second`:
lrl.StatTimeWindow = 1
case `minute`:
lrl.StatTimeWindow = 60
case `hour`:
lrl.StatTimeWindow = 3600
}
return lrl
}
// HTTPLocalRateLimit defines the local rate limiting specification
// for the upstream host at the HTTP level.
type HTTPLocalRateLimit struct {
// Requests defines the number of requests allowed
// per unit of time before rate limiting occurs.
Requests uint32 `json:"Requests"`
// StatTimeWindow specifies statistical time period of local rate limit
StatTimeWindow float64 `json:"StatTimeWindow"`
// Burst defines the number of requests above the baseline
// rate that are allowed in a short period of time.
// +optional
Burst uint32 `json:"Burst,omitempty"`
// ResponseStatusCode defines the HTTP status code to use for responses
// to rate limited requests. Code must be in the 400-599 (inclusive)
// error range. If not specified, a default of 429 (Too Many Requests) is used.
// +optional
ResponseStatusCode uint32 `json:"ResponseStatusCode,omitempty"`
// ResponseHeadersToAdd defines the list of HTTP headers that should be
// added to each response for requests that have been rate limited.
// +optional
ResponseHeadersToAdd []HTTPHeaderValue `json:"ResponseHeadersToAdd,omitempty"`
}
func newHTTPLocalRateLimit(spec *v1alpha1.HTTPLocalRateLimitSpec) *HTTPLocalRateLimit {
if spec == nil {
return nil
}
lrl := new(HTTPLocalRateLimit)
lrl.Requests = spec.Requests
lrl.Burst = spec.Burst
lrl.ResponseStatusCode = spec.ResponseStatusCode
if len(spec.ResponseHeadersToAdd) > 0 {
for _, header := range spec.ResponseHeadersToAdd {
lrl.ResponseHeadersToAdd = append(lrl.ResponseHeadersToAdd, newHTTPHeaderValue(header))
}
}
switch spec.Unit {
case `second`:
lrl.StatTimeWindow = 1
case `minute`:
lrl.StatTimeWindow = 60
case `hour`:
lrl.StatTimeWindow = 3600
}
return lrl
}
// HTTPHeaderValue defines an HTTP header name/value pair
type HTTPHeaderValue struct {
// Name defines the name of the HTTP header.
Name string `json:"Name"`
// Value defines the value of the header corresponding to the name key.
Value string `json:"Value"`
}
func newHTTPHeaderValue(header v1alpha1.HTTPHeaderValue) HTTPHeaderValue {
return HTTPHeaderValue{
Name: header.Name,
Value: header.Value,
}
}
// HTTPPerRouteRateLimit defines the rate limiting specification
// per HTTP route.
type HTTPPerRouteRateLimit struct {
// Local defines the local rate limiting specification
// applied per HTTP route.
Local *HTTPLocalRateLimit `json:"Local,omitempty"`
}
func newHTTPPerRouteRateLimit(spec *v1alpha1.HTTPPerRouteRateLimitSpec) *HTTPPerRouteRateLimit {
if spec == nil {
return nil
}
rrl := new(HTTPPerRouteRateLimit)
rrl.Local = newHTTPLocalRateLimit(spec.Local)
return rrl
}