summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--proxy.py190
1 files changed, 48 insertions, 142 deletions
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 <CR><LF>.<CR><LF>\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()