web flow filter support scope

addon-dailer
lqqyt2423 2 years ago
parent cca253238e
commit 043f32ccb8

@ -262,13 +262,26 @@ export class Flow {
}
}
const FLOW_FILTER_SCOPES = ['url', 'method', 'code', 'header', 'reqheader', 'resheader', 'body', 'reqbody', 'resbody', 'all'] as const
type FlowFilterScope = typeof FLOW_FILTER_SCOPES[number]
class FlowFilter {
private keyword: string | RegExp | undefined
private scope: FlowFilterScope = 'url'
constructor(text: string) {
text = text.trim()
if (!text) return
for (const scope of FLOW_FILTER_SCOPES) {
if (text.startsWith(`${scope}:`)) {
this.scope = scope
text = text.replace(`${scope}:`, '').trim()
break
}
}
if (!text) return
// regexp
if (text.startsWith('/') && (text.endsWith('/') || text.endsWith('/i'))) {
let flags: string | undefined
@ -286,10 +299,90 @@ class FlowFilter {
}
}
match(flow: Flow): boolean {
public match(flow: Flow): boolean {
switch (this.scope) {
case 'url':
return this.matchUrl(flow)
case 'method':
return this.matchMethod(flow)
case 'code':
return this.matchCode(flow)
case 'reqheader':
return this.matchReqHeader(flow)
case 'resheader':
return this.matchResHeader(flow)
case 'header':
return this.matchHeader(flow)
case 'reqbody':
return this.matchReqBody(flow)
case 'resbody':
return this.matchResBody(flow)
case 'body':
return this.matchBody(flow)
case 'all':
return this.matchAll(flow)
default:
throw new Error(`invalid scope ${this.scope}`)
}
}
private matchUrl(flow: Flow): boolean {
return this.matchKeyword(flow.request.url)
}
private matchMethod(flow: Flow): boolean {
return this.matchKeyword(flow.request.method) || this.matchKeyword(flow.request.method.toLowerCase())
}
private matchCode(flow: Flow): boolean {
if (!flow.response) return false
return this.matchKeyword(flow.response.statusCode.toString())
}
private _matchHeader(header: Header): boolean {
return Object.entries(header).some(([key, vals]) => {
return [key].concat(vals).some(text => this.matchKeyword(text))
})
}
private matchReqHeader(flow: Flow): boolean {
return this._matchHeader(flow.request.header)
}
private matchResHeader(flow: Flow): boolean {
if (!flow.response) return false
return this._matchHeader(flow.response.header)
}
private matchHeader(flow: Flow): boolean {
return this.matchReqHeader(flow) || this.matchResHeader(flow)
}
private matchReqBody(flow: Flow): boolean {
const body = flow.requestBody()
if (!body) return false
return this.matchKeyword(body)
}
private matchResBody(flow: Flow): boolean {
const body = flow.responseBody()
if (!body) return false
return this.matchKeyword(body)
}
private matchBody(flow: Flow): boolean {
return this.matchReqBody(flow) || this.matchResBody(flow)
}
private matchAll(flow: Flow): boolean {
return this.matchUrl(flow) || this.matchMethod(flow) || this.matchHeader(flow) || this.matchBody(flow)
}
private matchKeyword(text: string): boolean {
if (!this.keyword) return true
if (this.keyword instanceof RegExp) return this.keyword.test(flow.request.url)
return flow.request.url.includes(this.keyword)
if (!text) return false
if (this.keyword instanceof RegExp) return this.keyword.test(text)
return text.includes(this.keyword)
}
}
@ -330,10 +423,6 @@ export class FlowManager {
return this._map.get(id)
}
changeFilter(text: string) {
this.flowFilter = new FlowFilter(text)
}
changeFilterLazy(text: string, callback: (err: any) => void) {
if (this.filterTimer) {
clearTimeout(this.filterTimer)
@ -342,10 +431,10 @@ export class FlowManager {
this.filterTimer = setTimeout(() => {
try {
this.changeFilter(text)
this.flowFilter = new FlowFilter(text)
callback(null)
} catch (err) {
this.changeFilter('')
this.flowFilter = undefined
callback(err)
}
}, 300) as any

Loading…
Cancel
Save