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