From 59a601f64206a9784889dcefcb103580753f9d86 Mon Sep 17 00:00:00 2001 From: yvesf Date: Thu, 11 Mar 2010 16:27:59 +0100 Subject: blah blah --- proxy.py | 190 ++++++++++++++++----------------------------------------------- 1 file changed, 48 insertions(+), 142 deletions(-) (limited to 'proxy.py') diff --git a/proxy.py b/proxy.py index b583167..b721134 100644 --- a/proxy.py +++ b/proxy.py @@ -1,8 +1,24 @@ #!/usr/bin/python -t -import asynchat, asyncore, socket +import asynchat, asyncore, socket, httplib, urlparse import pwd, os, sys, logging, logging.handlers +import string +try: + import cStringIO as StringIO +except ImportError: + import StringIO +endpoints = { + {'host':'10.1.0.1', 'port':'8080', 'speed':220, 'name':'Yves Proxy'}, + {'host':'10.3.0.99', 'port':'8080', 'speed':340, 'name':'Thomas Proxy'}, +} + +class HTTPResponseProducer(object): + def __init__(self, resp, amt=512): + self.resp = resp + self.amt = amt + def more(self): + return self.resp.read(self.amt) class HTTPChannel(asynchat.async_chat): def __init__(self, server, sock, addr): @@ -16,7 +32,7 @@ class HTTPChannel(asynchat.async_chat): def collect_incoming_data(self, data): self.data.write(data) if self.data.tell() > 16384: - self.shutdown = 1 + self.close_when_done() def found_terminator(self): if not self.request: @@ -25,7 +41,7 @@ class HTTPChannel(asynchat.async_chat): self.request = string.split(self.data.readline(), None, 2) if len(self.request) != 3: # badly formed request; just shut down - self.shutdown = 1 + self.close_when_done() else: self.server.handle_request(self, self.request[0], self.request[1]) self.close_when_done() @@ -46,147 +62,37 @@ class HTTPProxyServer(asyncore.dispatcher): HTTPChannel(self, conn, addr) def handle_request(self, channel, method, path): - rss = self.es.to_rss() - channel.push("HTTP/1.0 200 OK\r\nContent-type: text/xml\r\n\r\n") - channel.push(rss) + url = urlparse.urlparse(path) + print method, path + if method != "GET": + return self._do_standard_proxy(channel, method, url) + + #check for content-length header with a HEAD request + conn = httplib.HTTPConnection(url.hostname, url.port or 80) + conn.request("HEAD", url.path) + resp = conn.getresponse() + content_length = filter(lambda it: it[0] == "content-length", resp.getheaders()) + if len( content_length ) == 0: + return self._do_standard_proxy(channel, method, url) + else: + content_length = content_length[0][1] + print "Content-Length: %s" % (content_length) + + return self._do_standard_proxy(channel, method, url) + #print "do some magic for " +str(url) + #channel.push("HTTP/1.0 200 OK\r\nX-Proxy: Magicproxy (request handled in boost mode)\r\n") + #channel.close_when_done() + + def _do_standard_proxy(self, channel, method, url): + conn = httplib.HTTPConnection(url.hostname, url.port or 80) + conn.request(method, url.path) + resp = conn.getresponse() + channel.push("HTTP/1.0 200 OK\r\nX-Proxy: Magicproxy (request handled in standard mode)\r\n") + channel.push( "\r\n".join(map(lambda k: "%s: %s" % (k[0],k[1]), resp.getheaders())) ) + channel.push("\r\n\r\n") + channel.push_with_producer( HTTPResponseProducer(resp) ) if __name__ == "__main__": proxy = HTTPProxyServer() asyncore.loop() - - - - -sys.exit(0) - -class SMTPChannel(asynchat.async_chat): - def __init__(self, server, sock, addr): - asynchat.async_chat.__init__(self, sock) - self.server = server - self.set_terminator("\n") - self.data = "" - self.read_data = False - self.push("220 Mailserver terrorist.at. Nutzung ohne vorige Erlaubnis verboten!\n") - - def collect_incoming_data(self, data): - if len(self.data) > 0: - self.data += "\n" - self.data += data - self.server.logger.debug("Read: " + data.strip()) - if self.data.__len__() > 16384: - self.server.logger.error("too much data, shutdown") - self.close_when_done() - - def push(self,data): - self.server.logger.debug("Write: " + data) - asynchat.async_chat.push(self,data) - - def handle_close(self): - asynchat.async_chat.handle_close(self) - if self.read_data and len(self.data) > 10: - #QUIT oder "." wurde nicht erkannt - mail = email.message_from_string(self.data) - key=self.server.maildir.add(mail) - self.server.logger.info("New Mail: %s" % key) - self.server.maildir.flush() - - - def found_terminator(self): - try: - if self.read_data: - if self.data.endswith("\n.") or self.data.endswith("\n.\r"): - self.read_data = False - self.push("250 Ok: queued as 12345\n") - mail = email.message_from_string(self.data) - key=self.server.maildir.add(mail) - self.server.logger.info("New Mail: %s" % key) - self.server.maildir.flush() - self.data = "" - else: - pass - - elif self.data.startswith("EHLO") \ - or self.data.startswith("HELO"): - self.push("250 Mailserver terrorist.at. Nutzung ohne vorige Erlaubnis verboten!\n") - self.data = "" - elif self.data.startswith("DATA"): - self.push("354 End data with .\n") - self.read_data = True - self.data="" - elif self.data.startswith("QUIT"): - self.data = "" - self.push("221 Bye\n") - self.close_when_done() - else: - self.push("250 OK\n") - self.data = "" - except Exception,e: - self.server.logger.error(str(e)) - - -class SMTPServer(asyncore.dispatcher): - def __init__(self): - asyncore.dispatcher.__init__(self) - self.port = 25 - self.create_socket(socket.AF_INET, socket.SOCK_STREAM) - self.set_reuse_addr() - self.bind(("", self.port)) - self.listen(5) - self.maildir = mailbox.Maildir("Maildir", create=True) - self.logger = logging.getLogger('MyLogger') - self.logger.setLevel(logging.DEBUG) - handler = logging.handlers.TimedRotatingFileHandler("log/smtp.log", "D", 1) - self.logger.addHandler(handler) - - def handle_accept(self): - conn, addr = self.accept() - self.logger.info("New Client %s:%s" % conn.getpeername()) - try: - SMTPChannel(self, conn, addr) - except Exception,e: - self.logger.error(str(e)) - - - -if __name__ == '__main__': - s = SMTPServer() - - #user change - pwinfo = pwd.getpwnam('nobody') - os.setregid(pwinfo[3],pwinfo[3]) - os.setreuid(pwinfo[2],pwinfo[2]) - - #"Robustly turn into a UNIX daemon, running in our_home_dir." - # First fork - try: - if os.fork() > 0: - sys.exit(0) # kill off parent - except OSError, e: - sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror)) - sys.exit(1) - os.setsid() - os.chdir('/') - os.umask(0) - - # Second fork - try: - pid = os.fork() - if pid > 0: - os._exit(0) - except OSError, e: - sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror)) - os._exit(1) - - si = open('/dev/null', 'r') - so = open('/dev/null', 'a+', 0) - se = open('/dev/null', 'a+', 0) - os.dup2(si.fileno(), sys.stdin.fileno()) - os.dup2(so.fileno(), sys.stdout.fileno()) - os.dup2(se.fileno(), sys.stderr.fileno()) - # Set custom file descriptors so that they get proper buffering. - sys.stdout, sys.stderr = so, se - #""" - - s.logger.info("Startup; pid=%s" % os.getpid()) - asyncore.loop() -- cgit v1.2.1