##// END OF EJS Templates
tests: make tinyproxy.py not import sys.argv by name
Yuya Nishihara -
r28778:256d90bb default
parent child Browse files
Show More
@@ -1,157 +1,158 b''
1 1 #!/usr/bin/env python
2 2
3 3 from __future__ import absolute_import, print_function
4 4
5 5 __doc__ = """Tiny HTTP Proxy.
6 6
7 7 This module implements GET, HEAD, POST, PUT and DELETE methods
8 8 on BaseHTTPServer, and behaves as an HTTP proxy. The CONNECT
9 9 method is also implemented experimentally, but has not been
10 10 tested yet.
11 11
12 12 Any help will be greatly appreciated. SUZUKI Hisao
13 13 """
14 14
15 15 __version__ = "0.2.1"
16 16
17 17 import BaseHTTPServer
18 18 import SocketServer
19 19 import os
20 20 import select
21 21 import socket
22 import sys
22 23 import urlparse
23 24
24 25 class ProxyHandler (BaseHTTPServer.BaseHTTPRequestHandler):
25 26 __base = BaseHTTPServer.BaseHTTPRequestHandler
26 27 __base_handle = __base.handle
27 28
28 29 server_version = "TinyHTTPProxy/" + __version__
29 30 rbufsize = 0 # self.rfile Be unbuffered
30 31
31 32 def handle(self):
32 33 (ip, port) = self.client_address
33 34 allowed = getattr(self, 'allowed_clients', None)
34 35 if allowed is not None and ip not in allowed:
35 36 self.raw_requestline = self.rfile.readline()
36 37 if self.parse_request():
37 38 self.send_error(403)
38 39 else:
39 40 self.__base_handle()
40 41
41 42 def log_request(self, code='-', size='-'):
42 43 xheaders = [h for h in self.headers.items() if h[0].startswith('x-')]
43 44 self.log_message('"%s" %s %s%s',
44 45 self.requestline, str(code), str(size),
45 46 ''.join([' %s:%s' % h for h in sorted(xheaders)]))
46 47
47 48 def _connect_to(self, netloc, soc):
48 49 i = netloc.find(':')
49 50 if i >= 0:
50 51 host_port = netloc[:i], int(netloc[i + 1:])
51 52 else:
52 53 host_port = netloc, 80
53 54 print("\t" "connect to %s:%d" % host_port)
54 55 try: soc.connect(host_port)
55 56 except socket.error as arg:
56 57 try: msg = arg[1]
57 58 except (IndexError, TypeError): msg = arg
58 59 self.send_error(404, msg)
59 60 return 0
60 61 return 1
61 62
62 63 def do_CONNECT(self):
63 64 soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
64 65 try:
65 66 if self._connect_to(self.path, soc):
66 67 self.log_request(200)
67 68 self.wfile.write(self.protocol_version +
68 69 " 200 Connection established\r\n")
69 70 self.wfile.write("Proxy-agent: %s\r\n" % self.version_string())
70 71 self.wfile.write("\r\n")
71 72 self._read_write(soc, 300)
72 73 finally:
73 74 print("\t" "bye")
74 75 soc.close()
75 76 self.connection.close()
76 77
77 78 def do_GET(self):
78 79 (scm, netloc, path, params, query, fragment) = urlparse.urlparse(
79 80 self.path, 'http')
80 81 if scm != 'http' or fragment or not netloc:
81 82 self.send_error(400, "bad url %s" % self.path)
82 83 return
83 84 soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
84 85 try:
85 86 if self._connect_to(netloc, soc):
86 87 self.log_request()
87 88 soc.send("%s %s %s\r\n" % (
88 89 self.command,
89 90 urlparse.urlunparse(('', '', path, params, query, '')),
90 91 self.request_version))
91 92 self.headers['Connection'] = 'close'
92 93 del self.headers['Proxy-Connection']
93 94 for key_val in self.headers.items():
94 95 soc.send("%s: %s\r\n" % key_val)
95 96 soc.send("\r\n")
96 97 self._read_write(soc)
97 98 finally:
98 99 print("\t" "bye")
99 100 soc.close()
100 101 self.connection.close()
101 102
102 103 def _read_write(self, soc, max_idling=20):
103 104 iw = [self.connection, soc]
104 105 ow = []
105 106 count = 0
106 107 while True:
107 108 count += 1
108 109 (ins, _, exs) = select.select(iw, ow, iw, 3)
109 110 if exs:
110 111 break
111 112 if ins:
112 113 for i in ins:
113 114 if i is soc:
114 115 out = self.connection
115 116 else:
116 117 out = soc
117 118 try:
118 119 data = i.recv(8192)
119 120 except socket.error:
120 121 break
121 122 if data:
122 123 out.send(data)
123 124 count = 0
124 125 else:
125 126 print("\t" "idle", count)
126 127 if count == max_idling:
127 128 break
128 129
129 130 do_HEAD = do_GET
130 131 do_POST = do_GET
131 132 do_PUT = do_GET
132 133 do_DELETE = do_GET
133 134
134 135 class ThreadingHTTPServer (SocketServer.ThreadingMixIn,
135 136 BaseHTTPServer.HTTPServer):
136 137 def __init__(self, *args, **kwargs):
137 138 BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)
138 139 a = open("proxy.pid", "w")
139 140 a.write(str(os.getpid()) + "\n")
140 141 a.close()
141 142
142 143 if __name__ == '__main__':
143 from sys import argv
144 argv = sys.argv
144 145 if argv[1:] and argv[1] in ('-h', '--help'):
145 146 print(argv[0], "[port [allowed_client_name ...]]")
146 147 else:
147 148 if argv[2:]:
148 149 allowed = []
149 150 for name in argv[2:]:
150 151 client = socket.gethostbyname(name)
151 152 allowed.append(client)
152 153 print("Accept: %s (%s)" % (client, name))
153 154 ProxyHandler.allowed_clients = allowed
154 155 del argv[2:]
155 156 else:
156 157 print("Any clients will be served...")
157 158 BaseHTTPServer.test(ProxyHandler, ThreadingHTTPServer)
General Comments 0
You need to be logged in to leave comments. Login now