Advertisement
Guest User

Untitled

a guest
Feb 3rd, 2009
766
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.11 KB | None | 0 0
  1. #!/bin/sh -
  2. "exec" "python" "-O" "$0" "$@"
  3.  
  4. __doc__ = """Tiny HTTP Proxy.
  5.  
  6. This module implements GET, HEAD, POST, PUT and DELETE methods
  7. on BaseHTTPServer, and behaves as an HTTP proxy.  The CONNECT
  8. method is also implemented experimentally, but has not been
  9. tested yet.
  10.  
  11. Any help will be greatly appreciated.       SUZUKI Hisao
  12. """
  13.  
  14. __version__ = "0.2.1"
  15.  
  16. import BaseHTTPServer, select, socket, SocketServer, urlparse
  17. import re, time
  18.  
  19. class ProxyHandler (BaseHTTPServer.BaseHTTPRequestHandler):
  20.     __base = BaseHTTPServer.BaseHTTPRequestHandler
  21.     __base_handle = __base.handle
  22.  
  23.     server_version = "TinyHTTPProxy/" + __version__
  24.     rbufsize = 0                        # self.rfile Be unbuffered
  25.  
  26.     def handle(self):
  27.         (ip, port) =  self.client_address
  28.         if hasattr(self, 'allowed_clients') and ip not in self.allowed_clients:
  29.             self.raw_requestline = self.rfile.readline()
  30.             if self.parse_request(): self.send_error(403)
  31.         else:
  32.             self.__base_handle()
  33.  
  34.     def _connect_to(self, netloc, soc):
  35.         #print "_connect_to: %s" % (netloc)
  36.        
  37.         i = netloc.find(':')
  38.         if i >= 0:
  39.             host_port = netloc[:i], int(netloc[i+1:])
  40.         else:
  41.             host_port = netloc, 80
  42.         #print "\t" "connect to %s:%d" % host_port
  43.         try: soc.connect(host_port)
  44.         except socket.error, arg:
  45.             try: msg = arg[1]
  46.             except: msg = arg
  47.             self.send_error(404, msg)
  48.             return 0
  49.         return 1
  50.  
  51.     def do_CONNECT(self):
  52.         #print('CONNECT')
  53.         soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  54.         try:
  55.             if self._connect_to(self.path, soc):
  56.                 self.log_request(200)
  57.                 self.wfile.write(self.protocol_version +
  58.                                  " 200 Connection established\r\n")
  59.                 self.wfile.write("Proxy-agent: %s\r\n" % self.version_string())
  60.                 self.wfile.write("\r\n")
  61.                 self._read_write(soc, 300)
  62.         finally:
  63.             #print "\t" "bye"
  64.             soc.close()
  65.             self.connection.close()
  66.  
  67.     def do_GET(self):
  68.         #print('GET')
  69.         (scm, netloc, path, params, query, fragment) = urlparse.urlparse(
  70.             self.path, 'http')
  71.         if scm != 'http' or fragment or not netloc:
  72.             self.send_error(400, "bad url %s" % self.path)
  73.             return
  74.         soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  75.        
  76.         pp = path.lower()
  77.         dbg = False
  78.         #dbg = pp.endswith("/") or pp.endswith(".html") or pp.endswith(".htm") or pp.endswith(".xml") or pp.endswith(".php")
  79.         if re.compile("(/|html|htm|bml|xml|php|txt)$", re.IGNORECASE).search(pp):
  80.             dbg = True
  81.             #print "pp:", pp
  82.  
  83.         dbg_hosts = "(habrahabr|zencd|www.livejournal|7bloggers.ru|lib.ru)"
  84.         if not re.compile(dbg_hosts, re.IGNORECASE).search(netloc):
  85.             dbg = False
  86.            
  87.         # Myth Busters patch
  88.         #if re.compile("Myth_busters", re.IGNORECASE).search(pp):
  89.         #    dbg = True
  90.         #else:
  91.         #    dbg = False
  92.  
  93.         if dbg: print "debugging", self.path
  94.        
  95.         try:
  96.             if self._connect_to(netloc, soc):
  97.                 if dbg: self.log_request()
  98.                 soc.send("%s %s %s\r\n" % (
  99.                     self.command,
  100.                     urlparse.urlunparse(('', '', path, params, query, '')),
  101.                     self.request_version))
  102.                    
  103.                 #for key_val in self.headers.items():
  104.                 #    print " header: %s" % (str(key_val))
  105.                    
  106.                 self.headers['Connection'] = 'close'
  107.                 del self.headers['Proxy-Connection']
  108.                 for key_val in self.headers.items():
  109.                     soc.send("%s: %s\r\n" % key_val)
  110.                 soc.send("\r\n")
  111.                 self._read_write(soc, 20, dbg, self.path)
  112.         finally:
  113.             #print "\t" "bye"
  114.             soc.close()
  115.             self.connection.close()
  116.  
  117.     def _read_write(self, soc, max_idling, dbg = False, path = ""):
  118.         time1 = time.time()
  119.         #print "_read_write(%d)\n" % (max_idling)
  120.         iw = [self.connection, soc]
  121.         ow = []
  122.         count = 0
  123.         while 1:
  124.             count += 1
  125.             (ins, _, exs) = select.select(iw, ow, iw, 3)
  126.             if exs: break
  127.             if ins:
  128.                 for i in ins:
  129.                     if i is soc:
  130.                         out = self.connection
  131.                     else:
  132.                         out = soc
  133.                     try:
  134.                         data = i.recv(8192)
  135.                         if data:
  136.                             #if dbg and data.lower().find("</html") >= 0:
  137.                             #    print "\a</HTML> FOUND"
  138.                             out.send(data)
  139.                             count = 0
  140.                     except:
  141.                         print 'EXCEPTION FOR %s' % (path)
  142.             #else:
  143.             #    print "idle", count
  144.             if count == max_idling: break
  145.  
  146.         if dbg:
  147.             #print " finished", path
  148.             time2 = time.time()
  149.             s = "%5.2f" % (time2-time1)
  150.             print "%9s %s\a" % (s, path)
  151.  
  152.     do_HEAD = do_GET
  153.     do_POST = do_GET
  154.     do_PUT  = do_GET
  155.     do_DELETE=do_GET
  156.  
  157. class ThreadingHTTPServer (SocketServer.ThreadingMixIn,
  158.                            BaseHTTPServer.HTTPServer): pass
  159.  
  160. if __name__ == '__main__':
  161.     from sys import argv
  162.    
  163.     #print time.time()
  164.     #exit(1)
  165.    
  166.     if argv[1:] and argv[1] in ('-h', '--help'):
  167.         print argv[0], "[port [allowed_client_name ...]]"
  168.     else:
  169.         if argv[2:]:
  170.             allowed = []
  171.             for name in argv[2:]:
  172.                 client = socket.gethostbyname(name)
  173.                 allowed.append(client)
  174.                 print "Accept: %s (%s)" % (client, name)
  175.             ProxyHandler.allowed_clients = allowed
  176.             del argv[2:]
  177.         else:
  178.             print "Any clients will be served..."
  179.         BaseHTTPServer.test(ProxyHandler, ThreadingHTTPServer)
  180.  
  181.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement