aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2012-06-19 13:23:07 +1200
committerAldo Cortesi <aldo@nullcube.com>2012-06-19 13:23:07 +1200
commita700721891e028aacc867001a715a8f7d9cbf223 (patch)
tree1ed752611078a36f202f2c1defdd96ccf302a335
parentbd99a13f3965bfdd09a58020424c3b36d97f6877 (diff)
downloadmitmproxy-a700721891e028aacc867001a715a8f7d9cbf223.tar.gz
mitmproxy-a700721891e028aacc867001a715a8f7d9cbf223.tar.bz2
mitmproxy-a700721891e028aacc867001a715a8f7d9cbf223.zip
Porting to netlib proceeds apace.
-rw-r--r--.gitignore1
-rw-r--r--libpathod/app.py97
-rw-r--r--libpathod/netlib.py182
-rw-r--r--libpathod/pathod.py23
-rw-r--r--libpathod/test.py12
-rw-r--r--test/test_test.py1
6 files changed, 122 insertions, 194 deletions
diff --git a/.gitignore b/.gitignore
index 64280a20..ac1655a1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ MANIFEST
*.swp
/doc
.coverage
+netlib
diff --git a/libpathod/app.py b/libpathod/app.py
new file mode 100644
index 00000000..8ea19f4c
--- /dev/null
+++ b/libpathod/app.py
@@ -0,0 +1,97 @@
+
+class APILog(tornado.web.RequestHandler):
+ def get(self):
+ self.write(
+ dict(
+ d = self.application.get_log()
+ )
+ )
+
+
+class APILogClear(tornado.web.RequestHandler):
+ def post(self):
+ self.application.clear_log()
+ self.write("OK")
+
+
+class APIShutdown(tornado.web.RequestHandler):
+ def post(self):
+ tornado.ioloop.IOLoop.instance().stop()
+ self.write("OK")
+
+
+class APIInfo(tornado.web.RequestHandler):
+ def get(self):
+ self.write(
+ dict(
+ version = version.IVERSION
+ )
+ )
+
+
+class _Page(tornado.web.RequestHandler):
+ def render(self, name, **kwargs):
+ tornado.web.RequestHandler.render(self, name + ".html", **kwargs)
+
+
+class Index(_Page):
+ name = "index"
+ section = "main"
+ def get(self):
+ self.render(self.name, section=self.section, spec="")
+
+
+class Preview(_Page):
+ name = "preview"
+ section = "main"
+ SANITY = 1024*1024
+ def get(self):
+ spec = self.get_argument("spec", None)
+ args = dict(
+ spec = spec,
+ section = self.section,
+ syntaxerror = None,
+ error = None
+ )
+ try:
+ r = rparse.parse(self.application.settings, spec)
+ except rparse.ParseException, v:
+ args["syntaxerror"] = str(v)
+ args["marked"] = v.marked()
+ return self.render(self.name, **args)
+ if r.length() > self.SANITY:
+ error = "Refusing to preview a response of %s bytes. This is for your own good."%r.length()
+ args["error"] = error
+ else:
+ d = utils.DummyRequest()
+ r.serve(d)
+ args["output"] = d.getvalue()
+ self.render(self.name, **args)
+
+
+class Help(_Page):
+ name = "help"
+ section = "help"
+ def get(self):
+ self.render(self.name, section=self.section)
+
+
+class Log(_Page):
+ name = "log"
+ section = "log"
+ def get(self):
+ self.render(self.name, section=self.section, log=self.application.log)
+
+
+class OneLog(_Page):
+ name = "onelog"
+ section = "log"
+ def get(self, lid):
+ l = pprint.pformat(self.application.log_by_id(int(lid)))
+ self.render(self.name, section=self.section, alog=l, lid=lid)
+
+
+class ClearLog(_Page):
+ def post(self):
+ self.application.clear_logs()
+ self.redirect("/log")
diff --git a/libpathod/netlib.py b/libpathod/netlib.py
deleted file mode 100644
index 08ccba09..00000000
--- a/libpathod/netlib.py
+++ /dev/null
@@ -1,182 +0,0 @@
-import select, socket, threading, traceback, sys
-from OpenSSL import SSL
-
-
-class NetLibError(Exception): pass
-
-
-class FileLike:
- def __init__(self, o):
- self.o = o
-
- def __getattr__(self, attr):
- return getattr(self.o, attr)
-
- def flush(self):
- pass
-
- def read(self, length):
- result = ''
- while len(result) < length:
- try:
- data = self.o.read(length)
- except SSL.ZeroReturnError:
- break
- if not data:
- break
- result += data
- return result
-
- def write(self, v):
- self.o.sendall(v)
-
- def readline(self, size = None):
- result = ''
- bytes_read = 0
- while True:
- if size is not None and bytes_read >= size:
- break
- ch = self.read(1)
- bytes_read += 1
- if not ch:
- break
- else:
- result += ch
- if ch == '\n':
- break
- return result
-
-
-class TCPClient:
- def __init__(self, ssl, host, port, clientcert):
- self.ssl, self.host, self.port, self.clientcert = ssl, host, port, clientcert
- self.connection, self.rfile, self.wfile = None, None, None
- self.cert = None
- self.connect()
-
- def connect(self):
- try:
- addr = socket.gethostbyname(self.host)
- server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- if self.ssl:
- context = SSL.Context(SSL.SSLv23_METHOD)
- if self.clientcert:
- context.use_certificate_file(self.clientcert)
- server = SSL.Connection(context, server)
- server.connect((addr, self.port))
- if self.ssl:
- self.cert = server.get_peer_certificate()
- self.rfile, self.wfile = FileLike(server), FileLike(server)
- else:
- self.rfile, self.wfile = server.makefile('rb'), server.makefile('wb')
- except socket.error, err:
- raise NetLibError('Error connecting to "%s": %s' % (self.host, err))
- self.connection = server
-
-
-class BaseHandler:
- rbufsize = -1
- wbufsize = 0
- def __init__(self, connection, client_address, server):
- self.connection = connection
- self.rfile = self.connection.makefile('rb', self.rbufsize)
- self.wfile = self.connection.makefile('wb', self.wbufsize)
-
- self.client_address = client_address
- self.server = server
- self.handle()
- self.finish()
-
- def convert_to_ssl(self, cert, key):
- ctx = SSL.Context(SSL.SSLv23_METHOD)
- ctx.use_privatekey_file(key)
- ctx.use_certificate_file(cert)
- self.connection = SSL.Connection(ctx, self.connection)
- self.connection.set_accept_state()
- self.rfile = FileLike(self.connection)
- self.wfile = FileLike(self.connection)
-
- def finish(self):
- try:
- if not getattr(self.wfile, "closed", False):
- self.wfile.flush()
- self.connection.close()
- self.wfile.close()
- self.rfile.close()
- except IOError: # pragma: no cover
- pass
-
- def handle(self): # pragma: no cover
- raise NotImplementedError
-
-
-class TCPServer:
- request_queue_size = 20
- def __init__(self, server_address):
- self.server_address = server_address
- self.__is_shut_down = threading.Event()
- self.__shutdown_request = False
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- self.socket.bind(self.server_address)
- self.server_address = self.socket.getsockname()
- self.socket.listen(self.request_queue_size)
- self.port = self.socket.getsockname()[1]
-
- def request_thread(self, request, client_address):
- try:
- self.handle_connection(request, client_address)
- request.close()
- except:
- self.handle_error(request, client_address)
- request.close()
-
- def serve_forever(self, poll_interval=0.5):
- self.__is_shut_down.clear()
- try:
- while not self.__shutdown_request:
- r, w, e = select.select([self.socket], [], [], poll_interval)
- if self.socket in r:
- try:
- request, client_address = self.socket.accept()
- except socket.error:
- return
- try:
- t = threading.Thread(
- target = self.request_thread,
- args = (request, client_address)
- )
- t.setDaemon(1)
- t.start()
- except:
- self.handle_error(request, client_address)
- request.close()
- finally:
- self.__shutdown_request = False
- self.__is_shut_down.set()
-
- def shutdown(self):
- self.__shutdown_request = True
- self.__is_shut_down.wait()
- self.handle_shutdown()
-
- def handle_error(self, request, client_address, fp=sys.stderr):
- """
- Called when handle_connection raises an exception.
- """
- print >> fp, '-'*40
- print >> fp, "Error processing of request from %s:%s"%client_address
- print >> fp, traceback.format_exc()
- print >> fp, '-'*40
-
- def handle_connection(self, request, client_address): # pragma: no cover
- """
- Called after client connection.
- """
- raise NotImplementedError
-
- def handle_shutdown(self):
- """
- Called after server shutdown.
- """
- pass
diff --git a/libpathod/pathod.py b/libpathod/pathod.py
index f712582e..c700b550 100644
--- a/libpathod/pathod.py
+++ b/libpathod/pathod.py
@@ -1,14 +1,25 @@
-import netlib
+from netlib import tcp, protocol, odict
-class PathodHandler(netlib.BaseHandler):
+class PathodHandler(tcp.BaseHandler):
def handle(self):
- print "Here"
+ line = self.rfile.readline()
+ if line == "\r\n" or line == "\n": # Possible leftover from previous message
+ line = self.rfile.readline()
+ if line == "":
+ return None
+ method, path, httpversion = protocol.parse_init_http(line)
+ headers = odict.ODictCaseless(protocol.read_headers(self.rfile))
+ content = protocol.read_http_body_request(
+ self.rfile, self.wfile, headers, httpversion, None
+ )
+ print method, path, httpversion
+ #return flow.Request(client_conn, httpversion, host, port, "http", method, path, headers, content)
-class PathodServer(netlib.TCPServer):
+
+class Pathod(tcp.TCPServer):
def __init__(self, addr):
- netlib.TCPServer.__init__(self, addr)
+ tcp.TCPServer.__init__(self, addr)
def handle_connection(self, request, client_address):
PathodHandler(request, client_address, self)
-
diff --git a/libpathod/test.py b/libpathod/test.py
index a66124a3..28fcd664 100644
--- a/libpathod/test.py
+++ b/libpathod/test.py
@@ -7,7 +7,8 @@ IFACE = "127.0.0.1"
class Daemon:
def __init__(self, staticdir=None, anchors=(), ssl=None):
- self.app = pathod.make_app(staticdir=staticdir, anchors=anchors)
+ #self.app = pathod.make_app(staticdir=staticdir, anchors=anchors)
+ self.app = None
self.q = Queue.Queue()
self.thread = PaThread(self.q, self.app, ssl)
self.thread.start()
@@ -19,7 +20,7 @@ class Daemon:
return resp.json
def shutdown(self):
- requests.post("%s/api/shutdown"%self.urlbase, verify=False)
+ self.thread.server.shutdown()
self.thread.join()
@@ -37,6 +38,7 @@ class PaThread(threading.Thread):
)
else:
ssloptions = self.ssl
- self.server, self.port = pathod.make_server(self.app, 0, IFACE, ssloptions)
- self.q.put(self.port)
- pathod.run(self.server)
+ self.server = pathod.Pathod((IFACE, 0))
+ #self.server, self.port = pathod.make_server(self.app, 0, IFACE, ssloptions)
+ self.q.put(self.server.port)
+ self.server.serve_forever()
diff --git a/test/test_test.py b/test/test_test.py
index 53decd1c..c3743a42 100644
--- a/test/test_test.py
+++ b/test/test_test.py
@@ -46,4 +46,3 @@ class TestDaemon:
def test_info(self):
assert tuple(self.d.info()["version"]) == version.IVERSION
-