Replace http decorator with one that handles different flowtypes

This commit is contained in:
Shadab Zafar 2016-07-15 11:48:11 +05:30
parent a7bb0f5d02
commit 5f7d61f864

View File

@ -38,16 +38,21 @@ import sys
import functools import functools
from mitmproxy.models.http import HTTPFlow from mitmproxy.models.http import HTTPFlow
from mitmproxy.models.tcp import TCPFlow
from netlib import strutils from netlib import strutils
import pyparsing as pp import pyparsing as pp
def http(fn): def only(*types):
def decorator(fn):
@functools.wraps(fn) @functools.wraps(fn)
def filter_http_only(self, flow): def filter_types(self, flow):
return isinstance(flow, HTTPFlow) and fn(self, flow) if isinstance(flow, types):
return filter_http_only return fn(self, flow)
return False
return filter_types
return decorator
class _Token(object): class _Token(object):
@ -71,6 +76,7 @@ class FErr(_Action):
code = "e" code = "e"
help = "Match error" help = "Match error"
@only(HTTPFlow, TCPFlow)
def __call__(self, f): def __call__(self, f):
return True if f.error else False return True if f.error else False
@ -79,7 +85,7 @@ class FReq(_Action):
code = "q" code = "q"
help = "Match request with no response" help = "Match request with no response"
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
if not f.response: if not f.response:
return True return True
@ -89,7 +95,7 @@ class FResp(_Action):
code = "s" code = "s"
help = "Match response" help = "Match response"
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
return bool(f.response) return bool(f.response)
@ -129,7 +135,7 @@ class FAsset(_Action):
] ]
ASSET_TYPES = [re.compile(x) for x in ASSET_TYPES] ASSET_TYPES = [re.compile(x) for x in ASSET_TYPES]
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
if f.response: if f.response:
for i in self.ASSET_TYPES: for i in self.ASSET_TYPES:
@ -142,7 +148,7 @@ class FContentType(_Rex):
code = "t" code = "t"
help = "Content-type header" help = "Content-type header"
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
if _check_content_type(self.re, f.request): if _check_content_type(self.re, f.request):
return True return True
@ -155,7 +161,7 @@ class FRequestContentType(_Rex):
code = "tq" code = "tq"
help = "Request Content-Type header" help = "Request Content-Type header"
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
return _check_content_type(self.re, f.request) return _check_content_type(self.re, f.request)
@ -164,7 +170,7 @@ class FResponseContentType(_Rex):
code = "ts" code = "ts"
help = "Response Content-Type header" help = "Response Content-Type header"
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
if f.response: if f.response:
return _check_content_type(self.re, f.response) return _check_content_type(self.re, f.response)
@ -176,7 +182,7 @@ class FHead(_Rex):
help = "Header" help = "Header"
flags = re.MULTILINE flags = re.MULTILINE
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
if f.request and self.re.search(bytes(f.request.headers)): if f.request and self.re.search(bytes(f.request.headers)):
return True return True
@ -190,7 +196,7 @@ class FHeadRequest(_Rex):
help = "Request header" help = "Request header"
flags = re.MULTILINE flags = re.MULTILINE
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
if f.request and self.re.search(bytes(f.request.headers)): if f.request and self.re.search(bytes(f.request.headers)):
return True return True
@ -201,7 +207,7 @@ class FHeadResponse(_Rex):
help = "Response header" help = "Response header"
flags = re.MULTILINE flags = re.MULTILINE
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
if f.response and self.re.search(bytes(f.response.headers)): if f.response and self.re.search(bytes(f.response.headers)):
return True return True
@ -211,6 +217,7 @@ class FBod(_Rex):
code = "b" code = "b"
help = "Body" help = "Body"
@only(HTTPFlow, TCPFlow)
def __call__(self, f): def __call__(self, f):
# HTTPFlow # HTTPFlow
@ -235,7 +242,7 @@ class FBodRequest(_Rex):
code = "bq" code = "bq"
help = "Request body" help = "Request body"
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
if f.request and f.request.content: if f.request and f.request.content:
if self.re.search(f.request.get_decoded_content()): if self.re.search(f.request.get_decoded_content()):
@ -246,7 +253,7 @@ class FBodResponse(_Rex):
code = "bs" code = "bs"
help = "Response body" help = "Response body"
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
if f.response and f.response.content: if f.response and f.response.content:
if self.re.search(f.response.get_decoded_content()): if self.re.search(f.response.get_decoded_content()):
@ -258,7 +265,7 @@ class FMethod(_Rex):
help = "Method" help = "Method"
flags = re.IGNORECASE flags = re.IGNORECASE
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
return bool(self.re.search(f.request.data.method)) return bool(self.re.search(f.request.data.method))
@ -268,7 +275,7 @@ class FDomain(_Rex):
help = "Domain" help = "Domain"
flags = re.IGNORECASE flags = re.IGNORECASE
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
return bool(self.re.search(f.request.data.host)) return bool(self.re.search(f.request.data.host))
@ -285,7 +292,7 @@ class FUrl(_Rex):
toks = toks[1:] toks = toks[1:]
return klass(*toks) return klass(*toks)
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
return self.re.search(f.request.url) return self.re.search(f.request.url)
@ -295,6 +302,7 @@ class FSrc(_Rex):
help = "Match source address" help = "Match source address"
is_binary = False is_binary = False
@only(HTTPFlow, TCPFlow)
def __call__(self, f): def __call__(self, f):
return f.client_conn.address and self.re.search(repr(f.client_conn.address)) return f.client_conn.address and self.re.search(repr(f.client_conn.address))
@ -304,6 +312,7 @@ class FDst(_Rex):
help = "Match destination address" help = "Match destination address"
is_binary = False is_binary = False
@only(HTTPFlow, TCPFlow)
def __call__(self, f): def __call__(self, f):
return f.server_conn.address and self.re.search(repr(f.server_conn.address)) return f.server_conn.address and self.re.search(repr(f.server_conn.address))
@ -318,7 +327,7 @@ class FCode(_Int):
code = "c" code = "c"
help = "HTTP response code" help = "HTTP response code"
@http @only(HTTPFlow)
def __call__(self, f): def __call__(self, f):
if f.response and f.response.status_code == self.num: if f.response and f.response.status_code == self.num:
return True return True