mirror of
https://github.com/zero-peak/ZeroOmega.git
synced 2025-01-22 15:08:12 -05:00
Add str and fromStr for every condition type.
This commit is contained in:
parent
6e7b5150c1
commit
56457519ab
@ -34,6 +34,54 @@ module.exports = exports =
|
|||||||
return cache.compiled if cache.compiled
|
return cache.compiled if cache.compiled
|
||||||
handler = exports._handler(condition.conditionType)
|
handler = exports._handler(condition.conditionType)
|
||||||
cache.compiled = handler.compile.call(exports, condition, cache)
|
cache.compiled = handler.compile.call(exports, condition, cache)
|
||||||
|
str: (condition, {abbr} = {abbr: -1}) ->
|
||||||
|
handler = exports._handler(condition.conditionType)
|
||||||
|
if handler.abbrs[0].length == 0
|
||||||
|
endCode = condition.pattern.charCodeAt(condition.pattern.length - 1)
|
||||||
|
if endCode != exports.colonCharCode and condition.pattern.indexOf(' ') < 0
|
||||||
|
return condition.pattern
|
||||||
|
str = handler.str
|
||||||
|
typeStr =
|
||||||
|
if typeof abbr == 'number'
|
||||||
|
handler.abbrs[(handler.abbrs.length + abbr) % handler.abbrs.length]
|
||||||
|
else
|
||||||
|
condition.conditionType
|
||||||
|
result = typeStr + ':'
|
||||||
|
part = if str then str.call(exports, condition) else condition.pattern
|
||||||
|
result += ' ' + part if part
|
||||||
|
return result
|
||||||
|
|
||||||
|
colonCharCode: ':'.charCodeAt(0)
|
||||||
|
fromStr: (str) ->
|
||||||
|
str = str.trim()
|
||||||
|
i = str.indexOf(' ')
|
||||||
|
i = str.length if i < 0
|
||||||
|
if str.charCodeAt(i - 1) == exports.colonCharCode
|
||||||
|
conditionType = str.substr(0, i - 1)
|
||||||
|
str = str.substr(i + 1).trim()
|
||||||
|
else
|
||||||
|
conditionType = ''
|
||||||
|
|
||||||
|
conditionType = exports.typeFromAbbr(conditionType)
|
||||||
|
return null unless conditionType
|
||||||
|
condition = {conditionType: conditionType}
|
||||||
|
fromStr = exports._handler(condition.conditionType).fromStr
|
||||||
|
if fromStr
|
||||||
|
return fromStr.call(exports, str, condition)
|
||||||
|
else
|
||||||
|
condition.pattern = str
|
||||||
|
return condition
|
||||||
|
|
||||||
|
_abbrs: null
|
||||||
|
typeFromAbbr: (abbr) ->
|
||||||
|
if not exports._abbrs
|
||||||
|
exports._abbrs = {}
|
||||||
|
for own type, {abbrs} of exports._conditionTypes
|
||||||
|
exports._abbrs[type.toUpperCase()] = type
|
||||||
|
for ab in abbrs
|
||||||
|
exports._abbrs[ab.toUpperCase()] = type
|
||||||
|
|
||||||
|
return exports._abbrs[abbr.toUpperCase()]
|
||||||
|
|
||||||
comment: (comment, node) ->
|
comment: (comment, node) ->
|
||||||
return unless comment
|
return unless comment
|
||||||
@ -148,8 +196,11 @@ module.exports = exports =
|
|||||||
localHosts: ["127.0.0.1", "[::1]", "localhost"]
|
localHosts: ["127.0.0.1", "[::1]", "localhost"]
|
||||||
|
|
||||||
_condCache: new AttachedCache (condition) ->
|
_condCache: new AttachedCache (condition) ->
|
||||||
condition.conditionType + '$' +
|
tag = exports._handler(condition.conditionType).tag
|
||||||
exports._handler(condition.conditionType).tag.apply(exports, arguments)
|
result =
|
||||||
|
if tag then tag.apply(exports, arguments) else exports.str(condition)
|
||||||
|
|
||||||
|
condition.conditionType + '$' + result
|
||||||
|
|
||||||
_setProp: (obj, prop, value) ->
|
_setProp: (obj, prop, value) ->
|
||||||
if not Object::hasOwnProperty.call obj, prop
|
if not Object::hasOwnProperty.call obj, prop
|
||||||
@ -169,17 +220,25 @@ module.exports = exports =
|
|||||||
# These functions are .call()-ed with `this` set to module.exports.
|
# These functions are .call()-ed with `this` set to module.exports.
|
||||||
# coffeelint: disable=missing_fat_arrows
|
# coffeelint: disable=missing_fat_arrows
|
||||||
'TrueCondition':
|
'TrueCondition':
|
||||||
tag: (condition) -> ''
|
abbrs: ['True']
|
||||||
analyze: (condition) -> null
|
analyze: (condition) -> null
|
||||||
match: -> true
|
match: -> true
|
||||||
compile: (condition) -> new U2.AST_True
|
compile: (condition) -> new U2.AST_True
|
||||||
|
str: (condition) -> ''
|
||||||
|
fromStr: (str, condition) -> condition
|
||||||
|
|
||||||
'FalseCondition':
|
'FalseCondition':
|
||||||
tag: (condition) -> ''
|
abbrs: ['False', 'Disabled']
|
||||||
analyze: (condition) -> null
|
analyze: (condition) -> null
|
||||||
match: -> false
|
match: -> false
|
||||||
compile: (condition) -> new U2.AST_False
|
compile: (condition) -> new U2.AST_False
|
||||||
|
fromStr: (str, condition) ->
|
||||||
|
if str.length > 0
|
||||||
|
condition.pattern = str
|
||||||
|
condition
|
||||||
|
|
||||||
'UrlRegexCondition':
|
'UrlRegexCondition':
|
||||||
tag: (condition) -> condition.pattern
|
abbrs: ['UR', 'URegex', 'UrlR', 'UrlRegex']
|
||||||
analyze: (condition) -> @safeRegex escapeSlash condition.pattern
|
analyze: (condition) -> @safeRegex escapeSlash condition.pattern
|
||||||
match: (condition, request, cache) ->
|
match: (condition, request, cache) ->
|
||||||
return cache.analyzed.test(request.url)
|
return cache.analyzed.test(request.url)
|
||||||
@ -187,7 +246,8 @@ module.exports = exports =
|
|||||||
@regTest 'url', cache.analyzed
|
@regTest 'url', cache.analyzed
|
||||||
|
|
||||||
'UrlWildcardCondition':
|
'UrlWildcardCondition':
|
||||||
tag: (condition) -> condition.pattern
|
abbrs: ['U', 'UW', 'Url', 'UrlW', 'UWild', 'UWildcard', 'UrlWild',
|
||||||
|
'UrlWildcard']
|
||||||
analyze: (condition) ->
|
analyze: (condition) ->
|
||||||
parts = for pattern in condition.pattern.split('|') when pattern
|
parts = for pattern in condition.pattern.split('|') when pattern
|
||||||
shExp2RegExp pattern, trimAsterisk: true
|
shExp2RegExp pattern, trimAsterisk: true
|
||||||
@ -198,7 +258,7 @@ module.exports = exports =
|
|||||||
@regTest 'url', cache.analyzed
|
@regTest 'url', cache.analyzed
|
||||||
|
|
||||||
'HostRegexCondition':
|
'HostRegexCondition':
|
||||||
tag: (condition) -> condition.pattern
|
abbrs: ['R', 'HR', 'Regex', 'HostR', 'HRegex', 'HostRegex']
|
||||||
analyze: (condition) -> @safeRegex escapeSlash condition.pattern
|
analyze: (condition) -> @safeRegex escapeSlash condition.pattern
|
||||||
match: (condition, request, cache) ->
|
match: (condition, request, cache) ->
|
||||||
return cache.analyzed.test(request.host)
|
return cache.analyzed.test(request.host)
|
||||||
@ -206,7 +266,8 @@ module.exports = exports =
|
|||||||
@regTest 'host', cache.analyzed
|
@regTest 'host', cache.analyzed
|
||||||
|
|
||||||
'HostWildcardCondition':
|
'HostWildcardCondition':
|
||||||
tag: (condition) -> condition.pattern
|
abbrs: ['', 'H', 'W', 'HW', 'Wild', 'Wildcard', 'Host', 'HostW', 'HWild',
|
||||||
|
'HWildcard', 'HostWild', 'HostWildcard']
|
||||||
analyze: (condition) ->
|
analyze: (condition) ->
|
||||||
parts = for pattern in condition.pattern.split('|') when pattern
|
parts = for pattern in condition.pattern.split('|') when pattern
|
||||||
# Get the magical regex of this pattern. See
|
# Get the magical regex of this pattern. See
|
||||||
@ -229,7 +290,7 @@ module.exports = exports =
|
|||||||
@regTest 'host', cache.analyzed
|
@regTest 'host', cache.analyzed
|
||||||
|
|
||||||
'BypassCondition':
|
'BypassCondition':
|
||||||
tag: (condition) -> condition.pattern
|
abbrs: ['B', 'Bypass']
|
||||||
analyze: (condition) ->
|
analyze: (condition) ->
|
||||||
# See https://developer.chrome.com/extensions/proxy#bypass_list
|
# See https://developer.chrome.com/extensions/proxy#bypass_list
|
||||||
cache =
|
cache =
|
||||||
@ -335,7 +396,7 @@ module.exports = exports =
|
|||||||
right: conditions[1]
|
right: conditions[1]
|
||||||
)
|
)
|
||||||
'KeywordCondition':
|
'KeywordCondition':
|
||||||
tag: (condition) -> condition.pattern
|
abbrs: ['K', 'KW', 'Keyword']
|
||||||
analyze: (condition) -> null
|
analyze: (condition) -> null
|
||||||
match: (condition, request) ->
|
match: (condition, request) ->
|
||||||
request.scheme == 'http' and request.url.indexOf(condition.pattern) >= 0
|
request.scheme == 'http' and request.url.indexOf(condition.pattern) >= 0
|
||||||
@ -361,7 +422,7 @@ module.exports = exports =
|
|||||||
)
|
)
|
||||||
|
|
||||||
'IpCondition':
|
'IpCondition':
|
||||||
tag: (condition) -> condition.ip + '/' + condition.prefixLength
|
abbrs: ['Ip']
|
||||||
analyze: (condition) ->
|
analyze: (condition) ->
|
||||||
cache =
|
cache =
|
||||||
addr: null
|
addr: null
|
||||||
@ -429,8 +490,16 @@ module.exports = exports =
|
|||||||
consequent: isInNetExCall
|
consequent: isInNetExCall
|
||||||
alternative: alternative
|
alternative: alternative
|
||||||
)
|
)
|
||||||
|
str: (condition) -> condition.ip + '/' + condition.prefixLength
|
||||||
|
fromStr: (str, condition) ->
|
||||||
|
[ip, prefixLength] = str.split('/')
|
||||||
|
condition.ip = ip
|
||||||
|
condition.prefixLength = parseInt(prefixLength)
|
||||||
|
condition
|
||||||
|
|
||||||
'HostLevelsCondition':
|
'HostLevelsCondition':
|
||||||
tag: (condition) -> condition.minValue + '~' + condition.maxValue
|
abbrs: ['Lv', 'Level', 'Levels', 'HL', 'HLv', 'HLevel', 'HLevels',
|
||||||
|
'HostL', 'HostLv', 'HostLevel', 'HostLevels']
|
||||||
analyze: (condition) -> '.'.charCodeAt 0
|
analyze: (condition) -> '.'.charCodeAt 0
|
||||||
match: (condition, request, cache) ->
|
match: (condition, request, cache) ->
|
||||||
dotCharCode = cache.analyzed
|
dotCharCode = cache.analyzed
|
||||||
@ -453,8 +522,15 @@ module.exports = exports =
|
|||||||
)
|
)
|
||||||
@between(val, condition.minValue + 1, condition.maxValue + 1,
|
@between(val, condition.minValue + 1, condition.maxValue + 1,
|
||||||
"#{condition.minValue} <= hostLevels <= #{condition.maxValue}")
|
"#{condition.minValue} <= hostLevels <= #{condition.maxValue}")
|
||||||
|
str: (condition) -> condition.minValue + '~' + condition.maxValue
|
||||||
|
fromStr: (str, condition) ->
|
||||||
|
[minValue, maxValue] = str.split('~')
|
||||||
|
condition.minValue = minValue
|
||||||
|
condition.maxValue = maxValue
|
||||||
|
condition
|
||||||
|
|
||||||
'WeekdayCondition':
|
'WeekdayCondition':
|
||||||
tag: (condition) -> condition.startDay + '~' + condition.endDay
|
abbrs: ['WD', 'Week', 'Day', 'Weekday']
|
||||||
analyze: (condition) -> null
|
analyze: (condition) -> null
|
||||||
match: (condition, request) ->
|
match: (condition, request) ->
|
||||||
day = new Date().getDay()
|
day = new Date().getDay()
|
||||||
@ -471,8 +547,14 @@ module.exports = exports =
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
@between val, condition.startDay, condition.endDay
|
@between val, condition.startDay, condition.endDay
|
||||||
|
str: (condition) -> condition.startDay + '~' + condition.endDay
|
||||||
|
fromStr: (str, condition) ->
|
||||||
|
[startDay, endDay] = str.split('~')
|
||||||
|
condition.startDay = startDay
|
||||||
|
condition.endDay = endDay
|
||||||
|
condition
|
||||||
'TimeCondition':
|
'TimeCondition':
|
||||||
tag: (condition) -> condition.startHour + '~' + condition.endHour
|
abbrs: ['T', 'Time', 'Hour']
|
||||||
analyze: (condition) -> null
|
analyze: (condition) -> null
|
||||||
match: (condition, request) ->
|
match: (condition, request) ->
|
||||||
hour = new Date().getHours()
|
hour = new Date().getHours()
|
||||||
@ -489,4 +571,10 @@ module.exports = exports =
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
@between val, condition.startHour, condition.endHour
|
@between val, condition.startHour, condition.endHour
|
||||||
|
str: (condition) -> condition.startHour + '~' + condition.endHour
|
||||||
|
fromStr: (str, condition) ->
|
||||||
|
[startHour, endHour] = str.split('~')
|
||||||
|
condition.startHour = startHour
|
||||||
|
condition.endHour = endHour
|
||||||
|
condition
|
||||||
# coffeelint: enable=missing_fat_arrows
|
# coffeelint: enable=missing_fat_arrows
|
||||||
|
@ -274,3 +274,80 @@ describe 'Conditions', ->
|
|||||||
it 'should not match HTTPS requests', ->
|
it 'should not match HTTPS requests', ->
|
||||||
testCond(cond, 'https://example.com/', not 'match')
|
testCond(cond, 'https://example.com/', not 'match')
|
||||||
testCond(cond, 'https://example.net/', not 'match')
|
testCond(cond, 'https://example.net/', not 'match')
|
||||||
|
|
||||||
|
describe '#typeFromAbbr', ->
|
||||||
|
it 'should get condition types by abbrs', ->
|
||||||
|
Conditions.typeFromAbbr('True').should.equal('TrueCondition')
|
||||||
|
Conditions.typeFromAbbr('HR').should.equal('HostRegexCondition')
|
||||||
|
|
||||||
|
describe '#str and #fromStr', ->
|
||||||
|
it 'should encode & decode TrueCondition correctly', ->
|
||||||
|
condition =
|
||||||
|
conditionType: 'TrueCondition'
|
||||||
|
result = Conditions.str(condition)
|
||||||
|
result.should.equal('True:')
|
||||||
|
cond = Conditions.fromStr(result)
|
||||||
|
cond.should.eql(condition)
|
||||||
|
it 'should encode & decode conditions with pattern correctly', ->
|
||||||
|
condition =
|
||||||
|
conditionType: 'UrlWildcardCondition'
|
||||||
|
pattern: '*://*.example.com/*'
|
||||||
|
result = Conditions.str(condition)
|
||||||
|
result.should.equal('UrlWildcard: ' + condition.pattern)
|
||||||
|
cond = Conditions.fromStr(result)
|
||||||
|
cond.should.eql(condition)
|
||||||
|
it 'should encode & decode False while preserving pattern', ->
|
||||||
|
condition =
|
||||||
|
conditionType: 'FalseCondition'
|
||||||
|
pattern: 'a b c'
|
||||||
|
result = Conditions.str(condition)
|
||||||
|
result.should.equal('Disabled: a b c')
|
||||||
|
cond = Conditions.fromStr(result)
|
||||||
|
cond.should.eql(condition)
|
||||||
|
it 'should encode & decode FalseCondition without any pattern', ->
|
||||||
|
condition =
|
||||||
|
conditionType: 'FalseCondition'
|
||||||
|
result = Conditions.str(condition)
|
||||||
|
result.should.equal('Disabled:')
|
||||||
|
cond = Conditions.fromStr(result)
|
||||||
|
cond.should.eql(condition)
|
||||||
|
it 'should encode & decode HostWildcardCondition using shorthand syntax', ->
|
||||||
|
condition =
|
||||||
|
conditionType: 'HostWildcardCondition'
|
||||||
|
pattern: '*.example.com'
|
||||||
|
result = Conditions.str(condition)
|
||||||
|
result.should.equal(condition.pattern)
|
||||||
|
cond = Conditions.fromStr(result)
|
||||||
|
cond.should.eql(condition)
|
||||||
|
it 'should encode & decode HostWildcardCondition ending with colon', ->
|
||||||
|
condition =
|
||||||
|
conditionType: 'HostWildcardCondition'
|
||||||
|
pattern: 'bogus:'
|
||||||
|
result = Conditions.str(condition)
|
||||||
|
result.should.equal('HostWildcard: ' + condition.pattern)
|
||||||
|
cond = Conditions.fromStr(result)
|
||||||
|
cond.should.eql(condition)
|
||||||
|
it 'should encode & decode IpCondition correctly', ->
|
||||||
|
condition =
|
||||||
|
conditionType: 'IpCondition'
|
||||||
|
ip: '127.0.0.1'
|
||||||
|
prefixLength: 16
|
||||||
|
result = Conditions.str(condition)
|
||||||
|
result.should.equal('Ip: 127.0.0.1/16')
|
||||||
|
cond = Conditions.fromStr(result)
|
||||||
|
cond.should.eql(condition)
|
||||||
|
it 'should parse conditions with extra spaces correctly', ->
|
||||||
|
Conditions.fromStr('url: *abcde* ').should.eql({
|
||||||
|
conditionType: 'UrlWildcardCondition'
|
||||||
|
pattern: '*abcde*'
|
||||||
|
})
|
||||||
|
it 'should parse abbreviated condition types correctly', ->
|
||||||
|
Conditions.fromStr('url: *://*.example.com/*').should.eql({
|
||||||
|
conditionType: 'UrlWildcardCondition'
|
||||||
|
pattern: '*://*.example.com/*'
|
||||||
|
})
|
||||||
|
it 'should parse escaped HostWildcardCondition starting with colon', ->
|
||||||
|
Conditions.fromStr(': :bogus:').should.eql({
|
||||||
|
conditionType: 'HostWildcardCondition'
|
||||||
|
pattern: ':bogus:'
|
||||||
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user