Merge remote-tracking branch 'origin/master'

This commit is contained in:
Henrik Nordstrom 2011-02-03 23:30:03 +01:00
commit 5bf6482bd0
8 changed files with 76 additions and 79 deletions

View File

@ -47,7 +47,7 @@ def format_keyvals(lst, key="key", val="text", space=5, indent=0):
def format_flow(f, focus, extended=False, padding=3):
if not f.request and not f.response:
txt = [
("title", " Connection from %s..."%(f.connection.address)),
("title", " Connection from %s..."%(f.client_conn.address[0])),
]
else:
if extended:
@ -1263,7 +1263,7 @@ class ConsoleMaster(controller.Master):
self.refresh_connection(f)
# Handlers
def handle_browserconnection(self, r):
def handle_clientconnection(self, r):
f = flow.Flow(r)
self.state.add_browserconnect(f)
r.ack()

View File

@ -13,10 +13,6 @@ class RunException(Exception):
self.errout = errout
class ReplayConnection:
pass
# begin nocover
class ReplayThread(threading.Thread):
def __init__(self, flow, masterq):
@ -29,14 +25,14 @@ class ReplayThread(threading.Thread):
response = server.read_response()
response.send(self.masterq)
except proxy.ProxyError, v:
err = proxy.Error(self.flow.connection, v.msg)
err = proxy.Error(self.flow.client_conn, v.msg)
err.send(self.masterq)
# end nocover
class Flow:
def __init__(self, connection):
self.connection = connection
def __init__(self, client_conn):
self.client_conn = client_conn
self.request, self.response, self.error = None, None, None
self.intercepting = False
self._backup = None
@ -110,6 +106,7 @@ class Flow:
self.response = proxy.Response.from_state(self.request, state["response"])
if state["error"]:
self.error = proxy.Error.from_state(state["error"])
self.client_conn = self.request.client_conn
@classmethod
def from_state(klass, state):
@ -131,7 +128,7 @@ class Flow:
def backup(self):
if not self._backup:
self._backup = [
self.connection.copy() if self.connection else None,
self.client_conn.copy(),
self.request.copy() if self.request else None,
self.response.copy() if self.response else None,
self.error.copy() if self.error else None,
@ -140,7 +137,7 @@ class Flow:
def revert(self):
if self._backup:
restore = [i.copy() if i else None for i in self._backup]
self.connection, self.request, self.response, self.error = restore
self.client_conn, self.request, self.response, self.error = restore
self._backup = None
def match(self, pattern):
@ -152,7 +149,7 @@ class Flow:
return False
def is_replay(self):
return isinstance(self.connection, ReplayConnection)
return self.client_conn.is_replay()
def kill(self):
if self.request and not self.request.acked:
@ -188,13 +185,13 @@ class State:
Start a browser connection.
"""
self.flow_list.insert(0, f)
self.flow_map[f.connection] = f
self.flow_map[f.client_conn] = f
def add_request(self, req):
"""
Add a request to the state. Returns the matching flow.
"""
f = self.flow_map.get(req.connection)
f = self.flow_map.get(req.client_conn)
if not f:
return False
f.request = req
@ -204,7 +201,7 @@ class State:
"""
Add a response to the state. Returns the matching flow.
"""
f = self.flow_map.get(resp.request.connection)
f = self.flow_map.get(resp.request.client_conn)
if not f:
return False
f.response = resp
@ -215,7 +212,7 @@ class State:
Add an error response to the state. Returns the matching flow, or
None if there isn't one.
"""
f = self.flow_map.get(err.connection)
f = self.flow_map.get(err.client_conn)
if not f:
return None
f.error = err
@ -231,6 +228,8 @@ class State:
data = bson.loads(js)
data = [Flow.from_state(i) for i in data["flows"]]
self.flow_list.extend(data)
for i in data:
self.flow_map[i.client_conn] = i
def set_limit(self, limit):
"""
@ -245,26 +244,26 @@ class State:
else:
return tuple(self.flow_list[:])
def get_connection(self, itm):
if isinstance(itm, (proxy.BrowserConnection, ReplayConnection)):
def get_client_conn(self, itm):
if isinstance(itm, proxy.ClientConnection):
return itm
elif hasattr(itm, "connection"):
return itm.connection
elif hasattr(itm, "client_conn"):
return itm.client_conn
elif hasattr(itm, "request"):
return itm.request.connection
return itm.request.client_conn
def lookup(self, itm):
"""
Checks for matching connection, using a Flow, Replay Connection,
BrowserConnection, Request, Response or Error object. Returns None
Checks for matching client_conn, using a Flow, Replay Connection,
ClientConnection, Request, Response or Error object. Returns None
if not found.
"""
connection = self.get_connection(itm)
return self.flow_map.get(connection)
client_conn = self.get_client_conn(itm)
return self.flow_map.get(client_conn)
def delete_flow(self, f):
if not f.intercepting:
c = self.get_connection(f)
c = self.get_client_conn(f)
if c in self.flow_map:
del self.flow_map[c]
self.flow_list.remove(f)
@ -284,19 +283,11 @@ class State:
self.delete_flow(f)
def revert(self, f):
"""
Replaces the matching connection object with a ReplayConnection object.
"""
conn = self.get_connection(f)
if conn in self.flow_map:
del self.flow_map[conn]
conn = self.get_client_conn(f)
f.revert()
self.flow_map[f.connection] = f
def replay(self, f, masterq):
"""
Replaces the matching connection object with a ReplayConnection object.
Returns None if successful, or error message if not.
"""
#begin nocover
@ -304,17 +295,12 @@ class State:
return "Can't replay while intercepting..."
if f.request:
f.backup()
conn = self.get_connection(f)
if conn in self.flow_map:
del self.flow_map[conn]
rp = ReplayConnection()
f.connection = rp
f.request.connection = rp
conn = self.get_client_conn(f)
f.client_conn.set_replay()
if f.request.content:
f.request.headers["content-length"] = [str(len(f.request.content))]
f.response = None
f.error = None
self.flow_map[rp] = f
rt = ReplayThread(f, masterq)
rt.start()
#end nocover

View File

@ -84,8 +84,8 @@ def parse_proxy_request(request):
class Request(controller.Msg):
FMT = '%s %s HTTP/1.0\r\n%s\r\n%s'
def __init__(self, connection, host, port, scheme, method, path, headers, content, timestamp=None):
self.connection = connection
def __init__(self, client_conn, host, port, scheme, method, path, headers, content, timestamp=None):
self.client_conn = client_conn
self.host, self.port, self.scheme = host, port, scheme
self.method, self.path, self.headers, self.content = method, path, headers, content
self.timestamp = timestamp or time.time()
@ -106,7 +106,7 @@ class Request(controller.Msg):
@classmethod
def from_state(klass, state):
return klass(
None,
ClientConnection(None),
state["host"],
state["port"],
state["scheme"],
@ -221,18 +221,31 @@ class Response(controller.Msg):
return self.FMT%data
class BrowserConnection(controller.Msg):
def __init__(self, address, port):
self.address, self.port = address, port
class ClientConnection(controller.Msg):
def __init__(self, address):
"""
address is an (address, port) tuple, or None if this connection has
been replayed from within mitmproxy.
"""
self.address = address
controller.Msg.__init__(self)
def set_replay(self):
self.address = None
def is_replay(self):
if self.address:
return False
else:
return True
def copy(self):
return copy.copy(self)
class Error(controller.Msg):
def __init__(self, connection, msg, timestamp=None):
self.connection, self.msg = connection, msg
def __init__(self, client_conn, msg, timestamp=None):
self.client_conn, self.msg = client_conn, msg
self.timestamp = timestamp or time.time()
controller.Msg.__init__(self)
@ -350,10 +363,10 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
def handle(self):
server = None
bc = BrowserConnection(*self.client_address)
bc.send(self.mqueue)
cc = ClientConnection(self.client_address)
cc.send(self.mqueue)
try:
request = self.read_request(bc)
request = self.read_request(cc)
request = request.send(self.mqueue)
if request is None:
self.finish()
@ -369,14 +382,14 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
except IOError:
pass
except ProxyError, e:
err = Error(bc, e.msg)
err = Error(cc, e.msg)
err.send(self.mqueue)
self.send_error(e.code, e.msg)
if server:
server.terminate()
self.finish()
def read_request(self, connection):
def read_request(self, client_conn):
request = self.rfile.readline()
method, scheme, host, port, path = parse_proxy_request(request)
if not host:
@ -412,7 +425,7 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
content = self.rfile.read(int(headers["content-length"][0]))
else:
content = ""
return Request(connection, host, port, scheme, method, path, headers, content)
return Request(client_conn, host, port, scheme, method, path, headers, content)
def send_response(self, response):
self.wfile.write(response.assemble())

View File

@ -10,7 +10,7 @@ class uState(libpry.AutoTree):
connect -> request -> response
"""
bc = proxy.BrowserConnection("address", 22)
bc = proxy.ClientConnection(("address", 22))
c = console.ConsoleState()
f = flow.Flow(bc)
c.add_browserconnect(f)
@ -25,7 +25,7 @@ class uState(libpry.AutoTree):
"""
c = console.ConsoleState()
bc = proxy.BrowserConnection("address", 22)
bc = proxy.ClientConnection(("address", 22))
f = flow.Flow(bc)
c.add_browserconnect(f)
assert c.get_focus() == (f, 0)
@ -33,7 +33,7 @@ class uState(libpry.AutoTree):
assert c.get_from_pos(1) == (None, None)
assert c.get_next(0) == (None, None)
bc2 = proxy.BrowserConnection("address", 22)
bc2 = proxy.ClientConnection(("address", 22))
f2 = flow.Flow(bc2)
c.add_browserconnect(f2)
assert c.get_focus() == (f, 1)
@ -54,7 +54,7 @@ class uState(libpry.AutoTree):
def _add_request(self, state):
f = utils.tflow()
state.add_browserconnect(f)
q = utils.treq(f.connection)
q = utils.treq(f.client_conn)
state.add_request(q)
return f
@ -67,7 +67,7 @@ class uState(libpry.AutoTree):
c = console.ConsoleState()
f = utils.tflow()
c.add_browserconnect(f)
q = utils.treq(f.connection)
q = utils.treq(f.client_conn)
c.focus = None
assert c.add_request(q)
@ -117,7 +117,7 @@ class uformat_flow(libpry.AutoTree):
assert ('method', '[edited] ') in console.format_flow(f, True)
assert ('method', '[edited] ') in console.format_flow(f, True, True)
f.connection = flow.ReplayConnection()
f.client_conn = proxy.ClientConnection(None)
assert ('method', '[replay] ') in console.format_flow(f, True)
assert ('method', '[replay] ') in console.format_flow(f, True, True)

View File

@ -72,7 +72,7 @@ class uParsing(libpry.AutoTree):
class uMatching(libpry.AutoTree):
def req(self):
conn = proxy.BrowserConnection("one", 2222)
conn = proxy.ClientConnection(("one", 2222))
headers = utils.Headers()
headers["header"] = ["qvalue"]
return proxy.Request(

View File

@ -39,8 +39,6 @@ class uFlow(libpry.AutoTree):
def test_getset_state(self):
f = utils.tflow()
state = f.get_state()
assert f == flow.Flow.from_state(state)
f.response = utils.tresp()
f.request = f.response.request
state = f.get_state()
@ -66,7 +64,7 @@ class uFlow(libpry.AutoTree):
assert console.format_flow(f, True)
assert console.format_flow(f, False)
f.connection = flow.ReplayConnection()
f.client_conn.set_replay()
assert console.format_flow(f, True)
assert console.format_flow(f, False)
@ -115,7 +113,7 @@ class uFlow(libpry.AutoTree):
class uState(libpry.AutoTree):
def test_backup(self):
bc = proxy.BrowserConnection("address", 22)
bc = proxy.ClientConnection(("address", 22))
c = flow.State()
f = flow.Flow(bc)
c.add_browserconnect(f)
@ -129,7 +127,7 @@ class uState(libpry.AutoTree):
connect -> request -> response
"""
bc = proxy.BrowserConnection("address", 22)
bc = proxy.ClientConnection(("address", 22))
c = flow.State()
f = flow.Flow(bc)
c.add_browserconnect(f)
@ -154,14 +152,14 @@ class uState(libpry.AutoTree):
assert not c.lookup(newresp)
def test_err(self):
bc = proxy.BrowserConnection("address", 22)
bc = proxy.ClientConnection(("address", 22))
c = flow.State()
f = flow.Flow(bc)
c.add_browserconnect(f)
e = proxy.Error(bc, "message")
assert c.add_error(e)
e = proxy.Error(proxy.BrowserConnection("address", 22), "message")
e = proxy.Error(proxy.ClientConnection(("address", 22)), "message")
assert not c.add_error(e)
def test_view(self):
@ -176,7 +174,7 @@ class uState(libpry.AutoTree):
f = utils.tflow()
req = utils.treq(f.connection)
req = utils.treq(f.client_conn)
c.add_browserconnect(f)
c.add_request(req)
assert len(c.view) == 2
@ -188,7 +186,7 @@ class uState(libpry.AutoTree):
def _add_request(self, state):
f = utils.tflow()
state.add_browserconnect(f)
q = utils.treq(f.connection)
q = utils.treq(f.client_conn)
state.add_request(q)
return f
@ -201,7 +199,7 @@ class uState(libpry.AutoTree):
f = utils.tflow()
f.error = proxy.Error(None, "msg")
state.add_browserconnect(f)
q = utils.treq(f.connection)
q = utils.treq(f.client_conn)
state.add_request(q)
def test_kill_flow(self):

View File

@ -221,7 +221,7 @@ class uRequest(libpry.AutoTree):
def test_simple(self):
h = utils.Headers()
h["test"] = ["test"]
c = proxy.BrowserConnection("addr", 2222)
c = proxy.ClientConnection(("addr", 2222))
r = proxy.Request(c, "host", 22, "https", "GET", "/", h, "content")
u = r.url()
assert r.set_url(u)
@ -233,7 +233,7 @@ class uRequest(libpry.AutoTree):
def test_getset_state(self):
h = utils.Headers()
h["test"] = ["test"]
c = proxy.BrowserConnection("addr", 2222)
c = proxy.ClientConnection(("addr", 2222))
r = proxy.Request(c, "host", 22, "https", "GET", "/", h, "content")
state = r.get_state()
assert proxy.Request.from_state(state) == r
@ -243,7 +243,7 @@ class uResponse(libpry.AutoTree):
def test_simple(self):
h = utils.Headers()
h["test"] = ["test"]
c = proxy.BrowserConnection("addr", 2222)
c = proxy.ClientConnection(("addr", 2222))
req = proxy.Request(c, "host", 22, "https", "GET", "/", h, "content")
resp = proxy.Response(req, 200, "HTTP", "msg", h.copy(), "content")
assert resp.short()
@ -252,7 +252,7 @@ class uResponse(libpry.AutoTree):
def test_getset_state(self):
h = utils.Headers()
h["test"] = ["test"]
c = proxy.BrowserConnection("addr", 2222)
c = proxy.ClientConnection(("addr", 2222))
r = proxy.Request(c, "host", 22, "https", "GET", "/", h, "content")
req = proxy.Request(c, "host", 22, "https", "GET", "/", h, "content")
resp = proxy.Response(req, 200, "HTTP", "msg", h.copy(), "content")

View File

@ -2,7 +2,7 @@ from libmproxy import proxy, utils, filt, flow
def treq(conn=None):
if not conn:
conn = proxy.BrowserConnection("address", 22)
conn = proxy.ClientConnection(("address", 22))
headers = utils.Headers()
headers["header"] = ["qvalue"]
return proxy.Request(conn, "host", 80, "http", "GET", "/path", headers, "content")
@ -17,6 +17,6 @@ def tresp(req=None):
def tflow():
bc = proxy.BrowserConnection("address", 22)
bc = proxy.ClientConnection(("address", 22))
return flow.Flow(bc)