@@ -154,7 +154,8 @@ function headersMatch(requestHeaders, headers) {
154154 const h = headers [ i ] ;
155155 const kv = h . split ( ':' ) ;
156156
157- if ( kv . length !== 2 ) {
157+ // header should be of the format "key:MatchType:value"
158+ if ( kv . length !== 3 ) {
158159 throw Error ( `invalid header match: ${ h } ` ) ;
159160 }
160161 // 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) {
168169
169170 // split on comma because nginx uses commas to delimit multiple header values
170171 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+ }
173188 }
174189 }
175190
@@ -179,20 +194,38 @@ function headersMatch(requestHeaders, headers) {
179194function paramsMatch ( requestParams , params ) {
180195 for ( let i = 0 ; i < params . length ; i ++ ) {
181196 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
183198 // 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 ) {
191206 throw Error ( `invalid query parameter: ${ p } ` ) ;
192207 }
193208
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+
194227 // 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 ) ] ;
196229
197230 // val can either be a string or an array of strings.
198231 // Also, the NGINX request's args object lookup is case-sensitive.
@@ -207,8 +240,15 @@ function paramsMatch(requestParams, params) {
207240 val = val [ 0 ] ;
208241 }
209242
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+ }
212252 }
213253 }
214254
0 commit comments