@@ -290,21 +290,23 @@ const $requestEntity = {
290290} ;
291291
292292const $httpHeaders = {
293- init ( headers ) {
294- this . headers = headers ;
293+ init ( ... headers ) {
294+ this . headers = headers . flat ( ) ;
295295 this . parsed . clear ( ) ;
296296 } ,
297297 reset ( ) {
298298 this . headers = [ ] ;
299299 this . parsed . clear ( ) ;
300300 } ,
301301 lookup ( name ) {
302- if ( this . parsed . size === 0 ) {
303- for ( const { name, value } of this . headers ) {
304- this . parsed . set ( name . toLowerCase ( ) , value ) ;
305- }
306- }
307- return this . parsed . get ( name ) ;
302+ let value = this . parsed . get ( name ) ;
303+ if ( value === undefined ) {
304+ const headers = this . headers ;
305+ const i = headers . findIndex ( a => name === a . name . toLowerCase ( ) ) ;
306+ value = i !== - 1 ? headers [ i ] . value : null ;
307+ this . parsed . set ( name , value ) ;
308+ }
309+ return value ?? undefined ;
308310 } ,
309311 headers : [ ] ,
310312 parsed : new Map ( ) ,
@@ -2943,13 +2945,14 @@ class FilterOnHeaders {
29432945 return re . test ( headerValue ) !== not ;
29442946 }
29452947
2946- static compile ( details ) {
2947- const parsed = sfp . parseHeaderValue ( details . optionValues . get ( 'header' ) ) ;
2948+ static compile ( fid , details ) {
2949+ const fc = filterClasses [ fid ] ;
2950+ const parsed = sfp . parseHeaderValue ( details . optionValues . get ( `${ fc . headerRealm } header` ) ) ;
29482951 let normalized = parsed . name ;
29492952 if ( parsed . value !== '' ) {
29502953 normalized += `:${ parsed . value } ` ;
29512954 }
2952- return [ FilterOnHeaders . fid , normalized ] ;
2955+ return [ fid , normalized ] ;
29532956 }
29542957
29552958 static fromCompiled ( args ) {
@@ -2962,7 +2965,8 @@ class FilterOnHeaders {
29622965 ) ;
29632966 }
29642967
2965- static dnrFromCompiled ( args , rule ) {
2968+ static dnrFromCompiled ( fid , args , rule ) {
2969+ const fc = filterClasses [ fid ] ;
29662970 rule . condition ||= { } ;
29672971 const parsed = sfp . parseHeaderValue ( args [ 1 ] ) ;
29682972 if ( parsed . bad !== true ) {
@@ -2971,8 +2975,8 @@ class FilterOnHeaders {
29712975 : parsed . value ;
29722976 if ( value !== undefined ) {
29732977 const prop = parsed . not
2974- ? 'excludedResponseHeaders'
2975- : 'responseHeaders' ;
2978+ ? `excludedR ${ fc . headerRealm . slice ( 1 ) } Headers`
2979+ : ` ${ fc . headerRealm } Headers` ;
29762980 rule . condition [ prop ] ||= [ ] ;
29772981 const details = {
29782982 header : parsed . name ,
@@ -2984,21 +2988,52 @@ class FilterOnHeaders {
29842988 return ;
29852989 }
29862990 }
2987- dnrAddRuleError ( rule , `header="${ args [ 1 ] } " not supported` ) ;
2991+ dnrAddRuleError ( rule , `${ fc . headerRealm } header="${ args [ 1 ] } " not supported` ) ;
29882992 }
29892993
2990- static logData ( idata , details ) {
2994+ static logData ( fid , idata , details ) {
2995+ const fc = filterClasses [ fid ] ;
29912996 const irefs = filterData [ idata + 1 ] ;
29922997 const headerOpt = filterRefs [ irefs ] . headerOpt ;
2993- let opt = ' header' ;
2998+ let opt = ` ${ fc . headerRealm } header` ;
29942999 if ( headerOpt !== '' ) {
29953000 opt += `=${ LogData . requote ( headerOpt ) } ` ;
29963001 }
29973002 details . options . push ( opt ) ;
29983003 }
29993004}
30003005
3001- registerFilterClass ( FilterOnHeaders ) ;
3006+ class FilterOnResponseHeaders extends FilterOnHeaders {
3007+ static headerRealm = 'response' ;
3008+ static compile ( details ) {
3009+ return super . compile ( FilterOnResponseHeaders . fid , details ) ;
3010+ }
3011+
3012+ static dnrFromCompiled ( args , rule ) {
3013+ super . dnrFromCompiled ( FilterOnResponseHeaders . fid , args , rule ) ;
3014+ }
3015+
3016+ static logData ( idata , details ) {
3017+ super . logData ( FilterOnResponseHeaders . fid , idata , details ) ;
3018+ }
3019+ }
3020+ registerFilterClass ( FilterOnResponseHeaders ) ;
3021+
3022+ class FilterOnRequestHeaders extends FilterOnHeaders {
3023+ static headerRealm = 'request' ;
3024+ static compile ( details ) {
3025+ return super . compile ( FilterOnRequestHeaders . fid , details ) ;
3026+ }
3027+
3028+ static dnrFromCompiled ( args , rule ) {
3029+ super . dnrFromCompiled ( FilterOnRequestHeaders . fid , args , rule ) ;
3030+ }
3031+
3032+ static logData ( idata , details ) {
3033+ super . logData ( FilterOnRequestHeaders . fid , idata , details ) ;
3034+ }
3035+ }
3036+ registerFilterClass ( FilterOnRequestHeaders ) ;
30023037
30033038/******************************************************************************/
30043039
@@ -3604,11 +3639,6 @@ class FilterCompiler {
36043639 this . optionUnitBits |= FROM_BIT ;
36053640 break ;
36063641 }
3607- case sfp . NODE_TYPE_NET_OPTION_NAME_HEADER : {
3608- this . optionValues . set ( 'header' , parser . getNetOptionValue ( id ) || '' ) ;
3609- this . optionUnitBits |= HEADER_BIT ;
3610- break ;
3611- }
36123642 case sfp . NODE_TYPE_NET_OPTION_NAME_IPADDRESS :
36133643 this . optionValues . set ( 'ipaddress' , parser . getNetOptionValue ( id ) || '' ) ;
36143644 this . optionUnitBits |= IPADDRESS_BIT ;
@@ -3642,6 +3672,16 @@ class FilterCompiler {
36423672 this . optionUnitBits |= MODIFY_BIT ;
36433673 break ;
36443674 }
3675+ case sfp . NODE_TYPE_NET_OPTION_NAME_REQUESTHEADER : {
3676+ this . optionValues . set ( 'requestheader' , parser . getNetOptionValue ( id ) || '' ) ;
3677+ this . optionUnitBits |= HEADER_BIT ;
3678+ break ;
3679+ }
3680+ case sfp . NODE_TYPE_NET_OPTION_NAME_RESPONSEHEADER : {
3681+ this . optionValues . set ( 'responseheader' , parser . getNetOptionValue ( id ) || '' ) ;
3682+ this . optionUnitBits |= HEADER_BIT ;
3683+ break ;
3684+ }
36453685 case sfp . NODE_TYPE_NET_OPTION_NAME_TO : {
36463686 const iter = parser . getNetFilterToOptionIterator ( ) ;
36473687 const list = [ ] ;
@@ -3736,7 +3776,6 @@ class FilterCompiler {
37363776 case sfp . NODE_TYPE_NET_OPTION_NAME_CSP :
37373777 case sfp . NODE_TYPE_NET_OPTION_NAME_DENYALLOW :
37383778 case sfp . NODE_TYPE_NET_OPTION_NAME_FROM :
3739- case sfp . NODE_TYPE_NET_OPTION_NAME_HEADER :
37403779 case sfp . NODE_TYPE_NET_OPTION_NAME_IPADDRESS :
37413780 case sfp . NODE_TYPE_NET_OPTION_NAME_METHOD :
37423781 case sfp . NODE_TYPE_NET_OPTION_NAME_PERMISSIONS :
@@ -3745,6 +3784,8 @@ class FilterCompiler {
37453784 case sfp . NODE_TYPE_NET_OPTION_NAME_REDIRECTRULE :
37463785 case sfp . NODE_TYPE_NET_OPTION_NAME_REMOVEPARAM :
37473786 case sfp . NODE_TYPE_NET_OPTION_NAME_REPLACE :
3787+ case sfp . NODE_TYPE_NET_OPTION_NAME_REQUESTHEADER :
3788+ case sfp . NODE_TYPE_NET_OPTION_NAME_RESPONSEHEADER :
37483789 case sfp . NODE_TYPE_NET_OPTION_NAME_TO :
37493790 case sfp . NODE_TYPE_NET_OPTION_NAME_URLSKIP :
37503791 case sfp . NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM :
@@ -4117,7 +4158,12 @@ class FilterCompiler {
41174158
41184159 // Header
41194160 if ( ( this . optionUnitBits & HEADER_BIT ) !== 0 ) {
4120- units . push ( FilterOnHeaders . compile ( this ) ) ;
4161+ if ( this . optionValues . has ( 'requestheader' ) ) {
4162+ units . push ( FilterOnRequestHeaders . compile ( this ) ) ;
4163+ }
4164+ if ( this . optionValues . has ( 'responseheader' ) ) {
4165+ units . push ( FilterOnResponseHeaders . compile ( this ) ) ;
4166+ }
41214167 this . action |= HEADERS_REALM ;
41224168 }
41234169
@@ -5432,7 +5478,7 @@ StaticNetFilteringEngine.prototype.matchRequest = function(fctxt, modifiers = 0)
54325478
54335479/******************************************************************************/
54345480
5435- StaticNetFilteringEngine . prototype . matchHeaders = function ( fctxt , headers ) {
5481+ StaticNetFilteringEngine . prototype . matchHeaders = function ( fctxt , ... headers ) {
54365482 const typeBits = typeNameToTypeValue [ fctxt . type ] || otherTypeBitValue ;
54375483 const partyBits = fctxt . is3rdPartyToDoc ( ) ? THIRDPARTY_REALM : FIRSTPARTY_REALM ;
54385484
@@ -5449,7 +5495,7 @@ StaticNetFilteringEngine.prototype.matchHeaders = function(fctxt, headers) {
54495495 $requestTypeValue = ( typeBits & TYPE_REALM ) >>> TYPE_REALM_OFFSET ;
54505496 $requestAddress = fctxt . getIPAddress ( ) ;
54515497 $isBlockImportant = false ;
5452- $httpHeaders . init ( headers ) ;
5498+ $httpHeaders . init ( ... headers ) ;
54535499
54545500 let r = 0 ;
54555501 if ( this . realmMatchString ( HEADERS_REALM | BLOCK_REALM , typeBits , partyBits ) ) {
0 commit comments