From 72ca111da681086dc39151d88e46cac3f64e4e7c Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Fri, 2 Mar 2012 11:18:26 +0000 Subject: [PATCH] -add proxy --- src/gns/proxy/proxy.py | 142 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/gns/proxy/proxy.py diff --git a/src/gns/proxy/proxy.py b/src/gns/proxy/proxy.py new file mode 100644 index 000000000..8fdec115e --- /dev/null +++ b/src/gns/proxy/proxy.py @@ -0,0 +1,142 @@ +#!/usr/bin/python + +__doc__ = """Tiny HTTP Proxy. + +This module implements GET, HEAD, POST, PUT and DELETE methods +on BaseHTTPServer, and behaves as an HTTP proxy. The CONNECT +method is also implemented experimentally, but has not been +tested yet. + +Any help will be greatly appreciated. SUZUKI Hisao +""" + +__version__ = "0.2.1" + +import BaseHTTPServer, select, socket, SocketServer, urlparse, re + +class ProxyHandler (BaseHTTPServer.BaseHTTPRequestHandler): + __base = BaseHTTPServer.BaseHTTPRequestHandler + __base_handle = __base.handle + + server_version = "TinyHTTPProxy/" + __version__ + rbufsize = 0 # self.rfile Be unbuffered + host_port = () + + def handle(self): + (ip, port) = self.client_address + if hasattr(self, 'allowed_clients') and ip not in self.allowed_clients: + self.raw_requestline = self.rfile.readline() + if self.parse_request(): self.send_error(403) + else: + self.__base_handle() + + def _connect_to(self, netloc, soc): + i = netloc.find(':') + if i >= 0: + self.host_port = netloc[:i], int(netloc[i+1:]) + else: + self.host_port = netloc, 80 + print "\t" "connect to %s:%d" % self.host_port + try: soc.connect(self.host_port) + except socket.error, arg: + try: msg = arg[1] + except: msg = arg + self.send_error(404, msg) + return 0 + return 1 + + def do_CONNECT(self): + soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + if self._connect_to(self.path, soc): + self.log_request(200) + self.wfile.write(self.protocol_version + + " 200 Connection established\r\n") + self.wfile.write("Proxy-agent: %s\r\n" % self.version_string()) + self.wfile.write("\r\n") + self._read_write(soc, 300) + finally: + print "\t" "bye" + soc.close() + self.connection.close() + + def do_GET(self): + (scm, netloc, path, params, query, fragment) = urlparse.urlparse( + self.path, 'http') + if scm != 'http' or fragment or not netloc: + self.send_error(400, "bad url %s" % self.path) + return + soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + if self._connect_to(netloc, soc): + self.log_request() + soc.send("%s %s %s\r\n" % ( + self.command, + urlparse.urlunparse(('', '', path, params, query, '')), + self.request_version)) + self.headers['Connection'] = 'close' + del self.headers['Proxy-Connection'] + for key_val in self.headers.items(): + soc.send("%s: %s\r\n" % key_val) + soc.send("\r\n") + self._read_write(soc) + finally: + print "\t" "bye" + soc.close() + self.connection.close() + + def _read_write(self, soc, max_idling=20): + iw = [self.connection, soc] + ow = [] + count = 0 + msg = '' + while 1: + count += 1 + (ins, _, exs) = select.select(iw, ow, iw, 3) + if exs: + break + if ins: + for i in ins: + if i is soc: + out = self.connection + else: + out = soc + data = i.recv(8192) + if data: + if (re.match("(\w+\.)*gnunet", self.host_port[0])): + arr = self.host_port[0].split(' ') + arr.pop(0) + data = re.sub(r'(a href="http://(\w+\.)*)(\+)', r'\1'+self.host_port[0], data) + print data + out.send(data) + count = 0 + else: + print "\t" "idle", count + print msg + if count == max_idling: break + + do_HEAD = do_GET + do_POST = do_GET + do_PUT = do_GET + do_DELETE=do_GET + +class ThreadingHTTPServer (SocketServer.ThreadingMixIn, + BaseHTTPServer.HTTPServer): pass + +if __name__ == '__main__': + from sys import argv + if argv[1:] and argv[1] in ('-h', '--help'): + print argv[0], "[port [allowed_client_name ...]]" + else: + if argv[2:]: + allowed = [] + for name in argv[2:]: + client = socket.gethostbyname(name) + allowed.append(client) + print "Accept: %s (%s)" % (client, name) + ProxyHandler.allowed_clients = allowed + del argv[2:] + else: + print "Any clients will be served..." + BaseHTTPServer.test(ProxyHandler, ThreadingHTTPServer) + -- 2.25.1