1
1
package config
2
2
3
3
import (
4
+ "encoding/json"
4
5
"fmt"
5
- "regexp"
6
6
"strconv"
7
7
"strings"
8
8
gotemplate "text/template"
@@ -39,30 +39,44 @@ var baseHeaders = []http.Header{
39
39
},
40
40
}
41
41
42
- func executeServers (conf dataplane.Configuration ) ([]http. Server , map [ string ][]http. RouteMatch ) {
42
+ func executeServers (conf dataplane.Configuration ) [] executeResult {
43
43
servers , httpMatchPairs := createServers (conf .HTTPServers , conf .SSLServers )
44
44
45
- return servers , httpMatchPairs
45
+ serverResult := executeResult {
46
+ dest : httpConfigFile ,
47
+ data : execute (serversTemplate , servers ),
48
+ }
49
+
50
+ // create httpMatchPair conf
51
+ httpMatchConf , err := json .Marshal (httpMatchPairs )
52
+ if err != nil {
53
+ // panic is safe here because we should never fail to marshal the match unless we constructed it incorrectly.
54
+ panic (fmt .Errorf ("could not marshal http match pairs: %w" , err ))
55
+ }
56
+
57
+ httpMatchResult := executeResult {
58
+ dest : httpMatchVarsFile ,
59
+ data : httpMatchConf ,
60
+ }
61
+
62
+ return []executeResult {serverResult , httpMatchResult }
46
63
}
47
64
48
- func createServers (httpServers , sslServers []dataplane.VirtualServer ) (
49
- []http.Server ,
50
- map [string ][]http.RouteMatch ,
51
- ) {
65
+ func createServers (httpServers , sslServers []dataplane.VirtualServer ) ([]http.Server , httpMatchPairs ) {
52
66
servers := make ([]http.Server , 0 , len (httpServers )+ len (sslServers ))
53
- finalMatchPairs := make (map [ string ][]http. RouteMatch )
67
+ finalMatchPairs := make (httpMatchPairs )
54
68
55
- for _ , s := range httpServers {
56
- httpServer , matchPair := createServer (s )
69
+ for serverID , s := range httpServers {
70
+ httpServer , matchPair := createServer (s , serverID )
57
71
servers = append (servers , httpServer )
58
72
59
73
for key , val := range matchPair {
60
74
finalMatchPairs [key ] = val
61
75
}
62
76
}
63
77
64
- for _ , s := range sslServers {
65
- sslServer , matchPair := createSSLServer (s )
78
+ for serverID , s := range sslServers {
79
+ sslServer , matchPair := createSSLServer (s , serverID )
66
80
servers = append (servers , sslServer )
67
81
68
82
for key , val := range matchPair {
@@ -73,18 +87,15 @@ func createServers(httpServers, sslServers []dataplane.VirtualServer) (
73
87
return servers , finalMatchPairs
74
88
}
75
89
76
- func createSSLServer (virtualServer dataplane.VirtualServer ) (
77
- http.Server ,
78
- map [string ][]http.RouteMatch ,
79
- ) {
90
+ func createSSLServer (virtualServer dataplane.VirtualServer , serverID int ) (http.Server , httpMatchPairs ) {
80
91
if virtualServer .IsDefault {
81
92
return http.Server {
82
93
IsDefaultSSL : true ,
83
94
Port : virtualServer .Port ,
84
95
}, nil
85
96
}
86
97
87
- locs , matchPairs := createLocations (virtualServer )
98
+ locs , matchPairs := createLocations (& virtualServer , serverID )
88
99
89
100
return http.Server {
90
101
ServerName : virtualServer .Hostname ,
@@ -97,18 +108,15 @@ func createSSLServer(virtualServer dataplane.VirtualServer) (
97
108
}, matchPairs
98
109
}
99
110
100
- func createServer (virtualServer dataplane.VirtualServer ) (
101
- http.Server ,
102
- map [string ][]http.RouteMatch ,
103
- ) {
111
+ func createServer (virtualServer dataplane.VirtualServer , serverID int ) (http.Server , httpMatchPairs ) {
104
112
if virtualServer .IsDefault {
105
113
return http.Server {
106
114
IsDefaultHTTP : true ,
107
115
Port : virtualServer .Port ,
108
116
}, nil
109
117
}
110
118
111
- locs , matchPairs := createLocations (virtualServer )
119
+ locs , matchPairs := createLocations (& virtualServer , serverID )
112
120
113
121
return http.Server {
114
122
ServerName : virtualServer .Hostname ,
@@ -124,19 +132,16 @@ type rewriteConfig struct {
124
132
Rewrite string
125
133
}
126
134
127
- type httpMatchPairs map [string ][]http. RouteMatch
135
+ type httpMatchPairs map [string ][]RouteMatch
128
136
129
- func createLocations (server dataplane.VirtualServer ) (
130
- []http.Location ,
131
- map [string ][]http.RouteMatch ,
132
- ) {
137
+ func createLocations (server * dataplane.VirtualServer , serverID int ) ([]http.Location , httpMatchPairs ) {
133
138
maxLocs , pathsAndTypes := getMaxLocationCountAndPathMap (server .PathRules )
134
139
locs := make ([]http.Location , 0 , maxLocs )
135
140
matchPairs := make (httpMatchPairs )
136
141
var rootPathExists bool
137
142
138
143
for pathRuleIdx , rule := range server .PathRules {
139
- matches := make ([]http. RouteMatch , 0 , len (rule .MatchRules ))
144
+ matches := make ([]RouteMatch , 0 , len (rule .MatchRules ))
140
145
141
146
if rule .Path == rootPath {
142
147
rootPathExists = true
@@ -157,9 +162,16 @@ func createLocations(server dataplane.VirtualServer) (
157
162
}
158
163
159
164
if len (matches ) > 0 {
160
- for i := range extLocations {
161
- key := server .Hostname + extLocations [i ].Path + strconv .Itoa (int (server .Port ))
162
- extLocations [i ].HTTPMatchKey = sanitizeKey (key )
165
+ for i , loc := range extLocations {
166
+ var key string
167
+ if server .SSL != nil {
168
+ key += "SSL"
169
+ }
170
+ key += strconv .Itoa (serverID ) + "_" + strconv .Itoa (pathRuleIdx )
171
+ if strings .Contains (loc .Path , "= /" ) {
172
+ key += "EXACT"
173
+ }
174
+ extLocations [i ].HTTPMatchKey = key
163
175
matchPairs [extLocations [i ].HTTPMatchKey ] = matches
164
176
}
165
177
locs = append (locs , extLocations ... )
@@ -173,13 +185,6 @@ func createLocations(server dataplane.VirtualServer) (
173
185
return locs , matchPairs
174
186
}
175
187
176
- // removeSpecialCharacters removes '/', '.' from key and replaces '= ' with 'EXACT',
177
- // to avoid compilation issues with NJS and NGINX Conf.
178
- func sanitizeKey (input string ) string {
179
- s := regexp .MustCompile ("[./]" ).ReplaceAllString (input , "" )
180
- return regexp .MustCompile ("= " ).ReplaceAllString (s , "EXACT" )
181
- }
182
-
183
188
// pathAndTypeMap contains a map of paths and any path types defined for that path
184
189
// for example, {/foo: {exact: {}, prefix: {}}}
185
190
type pathAndTypeMap map [string ]map [dataplane.PathType ]struct {}
@@ -256,7 +261,7 @@ func initializeInternalLocation(
256
261
pathruleIdx ,
257
262
matchRuleIdx int ,
258
263
match dataplane.Match ,
259
- ) (http.Location , http. RouteMatch ) {
264
+ ) (http.Location , RouteMatch ) {
260
265
path := fmt .Sprintf ("@rule%d-route%d" , pathruleIdx , matchRuleIdx )
261
266
return createMatchLocation (path ), createRouteMatch (match , path )
262
267
}
@@ -431,8 +436,26 @@ func createRewritesValForRewriteFilter(filter *dataplane.HTTPURLRewriteFilter, p
431
436
return rewrites
432
437
}
433
438
434
- func createRouteMatch (match dataplane.Match , redirectPath string ) http.RouteMatch {
435
- hm := http.RouteMatch {
439
+ // httpMatch is an internal representation of an HTTPRouteMatch.
440
+ // This struct is marshaled into a string and stored as a variable in the nginx location block for the route's path.
441
+ // The NJS httpmatches module will look up this variable on the request object and compare the request against the
442
+ // Method, Headers, and QueryParams contained in httpMatch.
443
+ // If the request satisfies the httpMatch, NGINX will redirect the request to the location RedirectPath.
444
+ type RouteMatch struct {
445
+ // Method is the HTTPMethod of the HTTPRouteMatch.
446
+ Method string `json:"method,omitempty"`
447
+ // RedirectPath is the path to redirect the request to if the request satisfies the match conditions.
448
+ RedirectPath string `json:"redirectPath,omitempty"`
449
+ // Headers is a list of HTTPHeaders name value pairs with the format "{name}:{value}".
450
+ Headers []string `json:"headers,omitempty"`
451
+ // QueryParams is a list of HTTPQueryParams name value pairs with the format "{name}={value}".
452
+ QueryParams []string `json:"params,omitempty"`
453
+ // Any represents a match with no match conditions.
454
+ Any bool `json:"any,omitempty"`
455
+ }
456
+
457
+ func createRouteMatch (match dataplane.Match , redirectPath string ) RouteMatch {
458
+ hm := RouteMatch {
436
459
RedirectPath : redirectPath ,
437
460
}
438
461
0 commit comments