mirror of https://github.com/gorhill/uBlock.git
Better align syntax of `header=` option to that of `queryprune=`
The header value is no longer implicitly a regex-based literal, but a plain string against which the header name is compared. The value can be set to a regex literal by bracing the header value with the usual forward slashes, `/.../`. Examples: *$1p,strict3p,script,header=via:1.1 google *$1p,strict3p,script,header=via:/1\.1\s+google/ The first form will cause a strict comparison with the value of the header named `via` against the string `1.1 google`. The second form will cause a regex-based test with the value of the header named `via` against the regex `/1\.1\s+google/`. The header value can be prepended with `~` to reverse the comparison: *$1p,strict3p,script,header=via:~1.1 google The header value is optional and may be ommitted to test only for the presence of a specific header: *$1p,strict3p,script,header=via
This commit is contained in:
parent
ed64039912
commit
5db8d05975
|
@ -1161,8 +1161,9 @@ const Parser = class {
|
||||||
BITFlavorError | BITFlavorUnsupported | BITFlavorIgnore
|
BITFlavorError | BITFlavorUnsupported | BITFlavorIgnore
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static parseQueryPruneValue(arg) {
|
static parseQueryPruneValue(arg) {
|
||||||
let s = arg;
|
let s = arg.trim();
|
||||||
if ( s === '*' ) { return { all: true }; }
|
if ( s === '*' ) { return { all: true }; }
|
||||||
const out = { };
|
const out = { };
|
||||||
out.not = s.charCodeAt(0) === 0x7E /* '~' */;
|
out.not = s.charCodeAt(0) === 0x7E /* '~' */;
|
||||||
|
@ -1196,6 +1197,29 @@ const Parser = class {
|
||||||
out.name = s;
|
out.name = s;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static parseHeaderValue(arg) {
|
||||||
|
let s = arg.trim();
|
||||||
|
const out = { };
|
||||||
|
let pos = s.indexOf(':');
|
||||||
|
if ( pos === -1 ) { pos = s.length; }
|
||||||
|
out.name = s.slice(0, pos);
|
||||||
|
out.bad = out.name === '';
|
||||||
|
s = s.slice(pos + 1);
|
||||||
|
out.not = s.charCodeAt(0) === 0x7E /* '~' */;
|
||||||
|
if ( out.not ) { s = s.slice(1); }
|
||||||
|
out.value = s;
|
||||||
|
const match = /^\/(.+)\/(i)?$/.exec(s);
|
||||||
|
if ( match !== null ) {
|
||||||
|
try {
|
||||||
|
out.re = new RegExp(match[1], match[2] || '');
|
||||||
|
}
|
||||||
|
catch(ex) {
|
||||||
|
out.bad = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -2520,10 +2544,27 @@ const NetOptionsIterator = class {
|
||||||
// `header`: can't be used with any modifier type
|
// `header`: can't be used with any modifier type
|
||||||
{
|
{
|
||||||
const i = this.tokenPos[OPTTokenHeader];
|
const i = this.tokenPos[OPTTokenHeader];
|
||||||
if ( i !== -1 && hasBits(allBits, OPTModifierType) ) {
|
if ( i !== -1 ) {
|
||||||
optSlices[i] = OPTTokenInvalid;
|
if ( hasBits(allBits, OPTModifierType) ) {
|
||||||
if ( this.interactive ) {
|
optSlices[i] = OPTTokenInvalid;
|
||||||
this.parser.errorSlices(optSlices[i+1], optSlices[i+5]);
|
if ( this.interactive ) {
|
||||||
|
this.parser.errorSlices(optSlices[i+1], optSlices[i+5]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const val = this.parser.strFromSlices(
|
||||||
|
optSlices[i+4],
|
||||||
|
optSlices[i+5] - 3
|
||||||
|
);
|
||||||
|
const r = Parser.parseHeaderValue(val);
|
||||||
|
if ( r.bad ) {
|
||||||
|
optSlices[i] = OPTTokenInvalid;
|
||||||
|
if ( this.interactive ) {
|
||||||
|
this.parser.errorSlices(
|
||||||
|
optSlices[i+4],
|
||||||
|
optSlices[i+5]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
Home: https://github.com/gorhill/uBlock
|
Home: https://github.com/gorhill/uBlock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* jshint bitwise: false */
|
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -2389,32 +2387,22 @@ registerFilterClass(FilterStrictParty);
|
||||||
const FilterOnHeaders = class {
|
const FilterOnHeaders = class {
|
||||||
constructor(headerOpt) {
|
constructor(headerOpt) {
|
||||||
this.headerOpt = headerOpt;
|
this.headerOpt = headerOpt;
|
||||||
if ( headerOpt !== '' ) {
|
this.parsed = undefined;
|
||||||
let pos = headerOpt.indexOf(':');
|
|
||||||
if ( pos === -1 ) { pos = headerOpt.length; }
|
|
||||||
this.name = headerOpt.slice(0, pos);
|
|
||||||
this.value = headerOpt.slice(pos + 1);
|
|
||||||
this.not = this.value.charCodeAt(0) === 0x21 /* '!' */;
|
|
||||||
if ( this.not ) { this.value.slice(1); }
|
|
||||||
} else {
|
|
||||||
this.name = this.value = '';
|
|
||||||
this.not = false;
|
|
||||||
}
|
|
||||||
this.reValue = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match() {
|
match() {
|
||||||
if ( this.name === '' ) { return true; }
|
if ( this.parsed === undefined ) {
|
||||||
const value = $httpHeaders.lookup(this.name);
|
this.parsed =
|
||||||
if ( value === undefined ) { return false; }
|
vAPI.StaticFilteringParser.parseHeaderValue(this.headerOpt);
|
||||||
if ( this.value === '' ) { return true; }
|
|
||||||
if ( this.reValue === null ) {
|
|
||||||
let reText = this.value;
|
|
||||||
if ( reText.startsWith('|') ) { reText = '^' + reText.slice(1); }
|
|
||||||
if ( reText.endsWith('|') ) { reText = reText.slice(0, -1) + '$'; }
|
|
||||||
this.reValue = new RegExp(reText, 'i');
|
|
||||||
}
|
}
|
||||||
return this.reValue.test(value) !== this.not;
|
const { bad, name, not, re, value } = this.parsed;
|
||||||
|
if ( bad ) { return false; }
|
||||||
|
const headerValue = $httpHeaders.lookup(name);
|
||||||
|
if ( headerValue === undefined ) { return false; }
|
||||||
|
if ( value === '' ) { return true; }
|
||||||
|
return re === undefined
|
||||||
|
? (headerValue === value) !== not
|
||||||
|
: re.test(headerValue) !== not;
|
||||||
}
|
}
|
||||||
|
|
||||||
logData(details) {
|
logData(details) {
|
||||||
|
@ -4231,12 +4219,10 @@ FilterContainer.prototype.matchHeaders = function(fctxt, headers) {
|
||||||
let r = 0;
|
let r = 0;
|
||||||
if ( this.realmMatchString(Headers | BlockImportant, typeValue, partyBits) ) {
|
if ( this.realmMatchString(Headers | BlockImportant, typeValue, partyBits) ) {
|
||||||
r = 1;
|
r = 1;
|
||||||
}
|
} else if ( this.realmMatchString(Headers | BlockAction, typeValue, partyBits) ) {
|
||||||
if ( r !== 1 && this.realmMatchString(Headers | BlockAction, typeValue, partyBits) ) {
|
r = this.realmMatchString(Headers | AllowAction, typeValue, partyBits)
|
||||||
r = 1;
|
? 2
|
||||||
if ( r === 1 && this.realmMatchString(Headers | AllowAction, typeValue, partyBits) ) {
|
: 1;
|
||||||
r = 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$httpHeaders.reset();
|
$httpHeaders.reset();
|
||||||
|
|
Loading…
Reference in New Issue