diff options
author | Aldo Cortesi <aldo@nullcube.com> | 2010-02-16 17:09:07 +1300 |
---|---|---|
committer | Aldo Cortesi <aldo@nullcube.com> | 2010-02-16 17:09:07 +1300 |
commit | cb0e3287090786fad566feb67ac07b8ef361b2c3 (patch) | |
tree | 0cce85760f1811bc3bbd00245764142621fa9d16 /libmproxy/controller.py | |
download | mitmproxy-cb0e3287090786fad566feb67ac07b8ef361b2c3.tar.gz mitmproxy-cb0e3287090786fad566feb67ac07b8ef361b2c3.tar.bz2 mitmproxy-cb0e3287090786fad566feb67ac07b8ef361b2c3.zip |
Initial checkin.
Diffstat (limited to 'libmproxy/controller.py')
-rw-r--r-- | libmproxy/controller.py | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/libmproxy/controller.py b/libmproxy/controller.py new file mode 100644 index 00000000..4955aae3 --- /dev/null +++ b/libmproxy/controller.py @@ -0,0 +1,119 @@ + +# Copyright (C) 2010 Aldo Cortesi +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import sys +import Queue, threading + +#begin nocover + +class Msg: + def __init__(self): + self.q = Queue.Queue() + self.acked = False + + def ack(self, data=None): + self.acked = True + self.q.put(data or self) + + def send(self, masterq): + self.acked = False + masterq.put(self) + return self.q.get() + + +class Slave(threading.Thread): + def __init__(self, masterq, server): + self.masterq, self.server = masterq, server + self.server.set_mqueue(masterq) + threading.Thread.__init__(self) + + def run(self): + self.server.serve_forever() + + +class Master: + def __init__(self, server): + self.server = server + self._shutdown = False + self.masterq = None + + def tick(self, q): + try: + # Small timeout to prevent pegging the CPU + msg = q.get(timeout=0.01) + self.handle(msg) + except Queue.Empty: + pass + + def run(self): + q = Queue.Queue() + self.masterq = q + slave = Slave(q, self.server) + slave.start() + while not self._shutdown: + self.tick(q) + self.shutdown() + + def handle(self, msg): + c = "handle_" + msg.__class__.__name__.lower() + m = getattr(self, c, None) + if m: + m(msg) + else: + msg.ack() + + def shutdown(self): + if not self._shutdown: + self._shutdown = True + self.server.shutdown() + + +class DumpMaster(Master): + """ + A simple master that just dumps to screen. + """ + def __init__(self, server, verbosity): + self.verbosity = verbosity + Master.__init__(self, server) + + def run(self): + try: + return Master.run(self) + except KeyboardInterrupt: + self.shutdown() + + def handle_response(self, msg): + if 0 < self.verbosity < 3: + print >> sys.stderr, ">>", + print >> sys.stderr, msg.request.short() + if self.verbosity == 1: + print >> sys.stderr, "<<", + print >> sys.stderr, msg.short() + elif self.verbosity == 2: + print >> sys.stderr, "<<" + for i in msg.assemble().splitlines(): + print >> sys.stderr, "\t", i + print >> sys.stderr, "<<" + elif self.verbosity == 3: + print >> sys.stderr, ">>" + for i in msg.request.assemble().splitlines(): + print >> sys.stderr, "\t", i + print >> sys.stderr, ">>" + print >> sys.stderr, "<<" + for i in msg.assemble().splitlines(): + print >> sys.stderr, "\t", i + print >> sys.stderr, "<<" + msg.ack() |