@@ -154,7 +154,8 @@ function headersMatch(requestHeaders, headers) {
154
154
const h = headers [ i ] ;
155
155
const kv = h . split ( ':' ) ;
156
156
157
- if ( kv . length !== 2 ) {
157
+ // header should be of the format "key:MatchType:value"
158
+ if ( kv . length !== 3 ) {
158
159
throw Error ( `invalid header match: ${ h } ` ) ;
159
160
}
160
161
// Header names are compared in a case-insensitive manner, meaning header name "FOO" is equivalent to "foo".
@@ -168,8 +169,22 @@ function headersMatch(requestHeaders, headers) {
168
169
169
170
// split on comma because nginx uses commas to delimit multiple header values
170
171
const values = val . split ( ',' ) ;
171
- if ( ! values . includes ( kv [ 1 ] ) ) {
172
- return false ;
172
+
173
+ let type = kv [ 1 ] ;
174
+ // verify the type of header match
175
+ if ( ! ( type == 'Exact' || type == 'RegularExpression' ) ) {
176
+ throw Error ( `invalid header match type: ${ type } ` ) ;
177
+ }
178
+
179
+ // match the value based on the type
180
+ if ( type === 'Exact' ) {
181
+ if ( ! values . includes ( kv [ 2 ] ) ) {
182
+ return false ;
183
+ }
184
+ } else if ( type === 'RegularExpression' ) {
185
+ if ( ! values . some ( ( v ) => new RegExp ( kv [ 2 ] ) . test ( v ) ) ) {
186
+ return false ;
187
+ }
173
188
}
174
189
}
175
190
@@ -179,20 +194,38 @@ function headersMatch(requestHeaders, headers) {
179
194
function paramsMatch ( requestParams , params ) {
180
195
for ( let i = 0 ; i < params . length ; i ++ ) {
181
196
let p = params [ i ] ;
182
- // We store query parameter matches as strings with the format "key=value"; however, there may be more than one
197
+ // We store query parameter matches as strings with the format "key=MatchType= value"; however, there may be more than one
183
198
// instance of "=" in the string.
184
- // To recover the key and value, we need to find the first occurrence of "=" in the string.
185
- const idx = params [ i ] . indexOf ( '=' ) ;
186
- // Check for an improperly constructed query parameter match. There are three possible error cases:
187
- // (1) if the index is -1, then there are no "=" in the string (e.g. "keyvalue")
188
- // (2 ) if the index is 0 , then there is no value in the string (e.g. "key=").
189
- // (3 ) if the index is equal to length -1 , then there is no key in the string (e.g. "=value").
190
- if ( idx === - 1 || ( idx === 0 ) | ( idx === p . length - 1 ) ) {
199
+ // To recover the key, type and and value, we need to find the first occurrence of "=" in the string.
200
+ const firstIdx = p . indexOf ( '=' ) ;
201
+
202
+ // Check for an improperly constructed query parameter match. There are two possible error cases:
203
+ // (1 ) if the index is -1 , then there are no "=" in the string (e.g. "keyExactvalue")
204
+ // (2 ) if the index is 0 , then there is no key in the string (e.g. "=Exact =value").
205
+ if ( firstIdx === - 1 || firstIdx === 0 ) {
191
206
throw Error ( `invalid query parameter: ${ p } ` ) ;
192
207
}
193
208
209
+ // find the next occurence of "=" in the string
210
+ const idx = p . indexOf ( '=' , firstIdx + 1 ) ;
211
+
212
+ // Three possible error cases for improperly constructed query parameter match:
213
+ // (1) if the index is -1, then there are no second occurence of "=" in the string (e.g. "Exactvalue")
214
+ // (2) if the index is 0, then there is no value in the string and has only one "=" (e.g. "key=Exact").
215
+ // (3) if the index is equal to length -1, then there is no key and type in the string (e.g. "=Exact=value").
216
+ if ( idx === - 1 || idx === 0 || idx === p . length - 1 ) {
217
+ throw Error ( `invalid query parameter: ${ p } ` ) ;
218
+ }
219
+
220
+ // extract the type match from the string
221
+ const type = p . slice ( firstIdx + 1 , idx ) ;
222
+
223
+ if ( ! ( type == 'Exact' || type == 'RegularExpression' ) ) {
224
+ throw Error ( `invalid header match type: ${ type } ` ) ;
225
+ }
226
+
194
227
// Divide string into key value using the index.
195
- let kv = [ p . slice ( 0 , idx ) , p . slice ( idx + 1 ) ] ;
228
+ let kv = [ p . slice ( 0 , firstIdx ) , p . slice ( idx + 1 ) ] ;
196
229
197
230
// val can either be a string or an array of strings.
198
231
// Also, the NGINX request's args object lookup is case-sensitive.
@@ -207,8 +240,15 @@ function paramsMatch(requestParams, params) {
207
240
val = val [ 0 ] ;
208
241
}
209
242
210
- if ( val !== kv [ 1 ] ) {
211
- return false ;
243
+ // match the value based on the type
244
+ if ( type === 'Exact' ) {
245
+ if ( val !== kv [ 1 ] ) {
246
+ return false ;
247
+ }
248
+ } else if ( type === 'RegularExpression' ) {
249
+ if ( ! new RegExp ( kv [ 1 ] ) . test ( val ) ) {
250
+ return false ;
251
+ }
212
252
}
213
253
}
214
254
0 commit comments