-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathmodel_urlspec.go
More file actions
206 lines (195 loc) · 7.15 KB
/
model_urlspec.go
File metadata and controls
206 lines (195 loc) · 7.15 KB
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
package gateway
import (
"github.com/TykTechnologies/tyk/apidef"
"github.com/TykTechnologies/tyk/apidef/oas"
"github.com/TykTechnologies/tyk/regexp"
)
// URLSpec represents a flattened specification for URLs, used to check if a proxy URL
// path is on any of the white, black or ignored lists. This is generated as part of the
// configuration init
type URLSpec struct {
spec *regexp.Regexp
Status URLStatus
MethodActions map[string]apidef.EndpointMethodMeta
Whitelist apidef.EndPointMeta
Blacklist apidef.EndPointMeta
Ignored apidef.EndPointMeta
MockResponse apidef.MockResponseMeta
CacheConfig EndPointCacheMeta
TransformAction TransformSpec
TransformResponseAction TransformSpec
TransformJQAction TransformJQSpec
TransformJQResponseAction TransformJQSpec
InjectHeaders apidef.HeaderInjectionMeta
InjectHeadersResponse apidef.HeaderInjectionMeta
HardTimeout apidef.HardTimeoutMeta
CircuitBreaker ExtendedCircuitBreakerMeta
URLRewrite *apidef.URLRewriteMeta
VirtualPathSpec apidef.VirtualMeta
RequestSize apidef.RequestSizeMeta
MethodTransform apidef.MethodTransformMeta
TrackEndpoint apidef.TrackEndpointMeta
DoNotTrackEndpoint apidef.TrackEndpointMeta
ValidatePathMeta apidef.ValidatePathMeta
Internal apidef.InternalMeta
GoPluginMeta GoPluginMiddleware
PersistGraphQL apidef.PersistGraphQLMeta
RateLimit apidef.RateLimitMeta
OASValidateRequestMeta *oas.ValidateRequest
OASMockResponseMeta *oas.MockResponse
// OASValidateRequestCandidates holds multiple OAS endpoints that compile to the
// same regex pattern. When non-empty, the validate request middleware must
// disambiguate by checking path parameter schemas against each candidate.
OASValidateRequestCandidates []ValidateRequestCandidate
// OASMockResponseCandidates holds multiple OAS endpoints that compile to the
// same regex pattern. When non-empty, the mock response middleware must
// disambiguate by checking path parameter schemas against each candidate.
OASMockResponseCandidates []MockResponseCandidate
IgnoreCase bool
// OASMethod stores the HTTP method for OAS-specific middleware
// This is needed because OAS operations are method-specific
OASMethod string
// OASPath stores the original OAS path pattern (e.g., "/users/{id}")
// This is used for matching against the OAS router when needed
OASPath string
}
// ValidateRequestCandidate represents one OAS endpoint that maps to the same
// compiled regex pattern. Used for disambiguation when multiple parameterized
// paths collapse to the same regex (e.g., /employees/{prct} and /employees/{zd}).
type ValidateRequestCandidate struct {
OASValidateRequestMeta *oas.ValidateRequest
OASMethod string
OASPath string
}
// MockResponseCandidate represents one OAS endpoint that maps to the same
// compiled regex pattern for mock response disambiguation.
type MockResponseCandidate struct {
OASMockResponseMeta *oas.MockResponse
OASMethod string
OASPath string
}
// modeSpecificSpec returns the respective field of URLSpec if it matches the given mode.
// Deprecated: Usage should not increase.
func (u *URLSpec) modeSpecificSpec(mode URLStatus) (interface{}, bool) {
switch mode {
case Ignored, BlackList, WhiteList:
return nil, true
case Cached:
return &u.CacheConfig, true
case Transformed:
return &u.TransformAction, true
case TransformedJQ:
return &u.TransformJQAction, true
case HeaderInjected:
return &u.InjectHeaders, true
case HeaderInjectedResponse:
return &u.InjectHeadersResponse, true
case TransformedResponse:
return &u.TransformResponseAction, true
case TransformedJQResponse:
return &u.TransformJQResponseAction, true
case HardTimeout:
return &u.HardTimeout.TimeOut, true
case CircuitBreaker:
return &u.CircuitBreaker, true
case URLRewrite:
return u.URLRewrite, true
case VirtualPath:
return &u.VirtualPathSpec, true
case RequestSizeLimit:
return &u.RequestSize, true
case MethodTransformed:
return &u.MethodTransform, true
case RequestTracked:
return &u.TrackEndpoint, true
case RequestNotTracked:
return &u.DoNotTrackEndpoint, true
case ValidateJSONRequest:
return &u.ValidatePathMeta, true
case Internal:
return &u.Internal, true
case GoPlugin:
return &u.GoPluginMeta, true
case PersistGraphQL:
return &u.PersistGraphQL, true
case OASValidateRequest:
return u.OASValidateRequestMeta, true
case OASMockResponse:
return u.OASMockResponseMeta, true
default:
return nil, false
}
}
// matchesMethod checks if the given method matches the method required by the URLSpec for the current status.
func (u *URLSpec) matchesMethod(method string) bool {
switch u.Status {
case Ignored, BlackList, WhiteList:
return true
case Cached:
return method == u.CacheConfig.Method || (u.CacheConfig.Method == SAFE_METHODS && isSafeMethod(method))
case Transformed:
return method == u.TransformAction.Method
case TransformedJQ:
return method == u.TransformJQAction.Method
case HeaderInjected:
return method == u.InjectHeaders.Method
case HeaderInjectedResponse:
return method == u.InjectHeadersResponse.Method
case TransformedResponse:
return method == u.TransformResponseAction.Method
case TransformedJQResponse:
return method == u.TransformJQResponseAction.Method
case HardTimeout:
return method == u.HardTimeout.Method
case CircuitBreaker:
return method == u.CircuitBreaker.Method
case URLRewrite:
return method == u.URLRewrite.Method
case VirtualPath:
return method == u.VirtualPathSpec.Method
case RequestSizeLimit:
return method == u.RequestSize.Method
case MethodTransformed:
return method == u.MethodTransform.Method
case RequestTracked:
return method == u.TrackEndpoint.Method
case RequestNotTracked:
return method == u.DoNotTrackEndpoint.Method
case ValidateJSONRequest:
return method == u.ValidatePathMeta.Method
case Internal:
return method == u.Internal.Method
case GoPlugin:
return method == u.GoPluginMeta.Meta.Method
case PersistGraphQL:
return method == u.PersistGraphQL.Method
case RateLimit:
return method == u.RateLimit.Method
case OASValidateRequest, OASMockResponse:
// OAS middleware is method-specific, check against stored method
return method == u.OASMethod
default:
return false
}
}
// matchesPath takes the input string and matches it against an internal regex.
// it will match the regex against the clean URL with stripped listen path first,
// then it will match against the full URL including the listen path as provided.
// APISpec to provide URL sanitization of the input is passed along.
func (a *URLSpec) matchesPath(reqPath string, api *APISpec) bool {
clean := api.StripListenPath(reqPath)
noVersion := api.StripVersionPath(clean)
// match /users
if noVersion != clean && a.spec.MatchString(noVersion) {
return true
}
// match /v3/users
if a.spec.MatchString(clean) {
return true
}
// match /listenpath/v3/users
if a.spec.MatchString(reqPath) {
return true
}
return false
}