OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """This is a simple HTTP/FTP/SYNC/TCP/UDP/ server used for testing Chrome. | 6 """This is a simple HTTP/FTP/SYNC/TCP/UDP/ server used for testing Chrome. |
7 | 7 |
8 It supports several test URLs, as specified by the handlers in TestPageHandler. | 8 It supports several test URLs, as specified by the handlers in TestPageHandler. |
9 By default, it listens on an ephemeral port and sends the port number back to | 9 By default, it listens on an ephemeral port and sends the port number back to |
10 the originating process over a pipe. The originating process can specify an | 10 the originating process over a pipe. The originating process can specify an |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 import simplejson as json | 57 import simplejson as json |
58 | 58 |
59 if sys.platform == 'win32': | 59 if sys.platform == 'win32': |
60 import msvcrt | 60 import msvcrt |
61 | 61 |
62 SERVER_HTTP = 0 | 62 SERVER_HTTP = 0 |
63 SERVER_FTP = 1 | 63 SERVER_FTP = 1 |
64 SERVER_SYNC = 2 | 64 SERVER_SYNC = 2 |
65 SERVER_TCP_ECHO = 3 | 65 SERVER_TCP_ECHO = 3 |
66 SERVER_UDP_ECHO = 4 | 66 SERVER_UDP_ECHO = 4 |
| 67 SERVER_BASIC_AUTH_PROXY = 5 |
67 | 68 |
68 # Using debug() seems to cause hangs on XP: see http://crbug.com/64515 . | 69 # Using debug() seems to cause hangs on XP: see http://crbug.com/64515 . |
69 debug_output = sys.stderr | 70 debug_output = sys.stderr |
70 def debug(str): | 71 def debug(str): |
71 debug_output.write(str + "\n") | 72 debug_output.write(str + "\n") |
72 debug_output.flush() | 73 debug_output.flush() |
73 | 74 |
74 class RecordingSSLSessionCache(object): | 75 class RecordingSSLSessionCache(object): |
75 """RecordingSSLSessionCache acts as a TLS session cache and maintains a log of | 76 """RecordingSSLSessionCache acts as a TLS session cache and maintains a log of |
76 lookups and inserts in order to test session cache behaviours.""" | 77 lookups and inserts in order to test session cache behaviours.""" |
(...skipping 1935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2012 # "echo response" message if "echo request" message is valid. | 2013 # "echo response" message if "echo request" message is valid. |
2013 try: | 2014 try: |
2014 return_data = echo_message.GetEchoResponseData(data) | 2015 return_data = echo_message.GetEchoResponseData(data) |
2015 if not return_data: | 2016 if not return_data: |
2016 return | 2017 return |
2017 except ValueError: | 2018 except ValueError: |
2018 return | 2019 return |
2019 socket.sendto(return_data, self.client_address) | 2020 socket.sendto(return_data, self.client_address) |
2020 | 2021 |
2021 | 2022 |
| 2023 class BasicAuthProxyRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
| 2024 """A request handler that behaves as a proxy server which requires |
| 2025 basic authentication. Only CONNECT, GET and HEAD is supported for now. |
| 2026 """ |
| 2027 |
| 2028 _AUTH_CREDENTIAL = 'Basic Zm9vOmJhcg==' # foo:bar |
| 2029 |
| 2030 def parse_request(self): |
| 2031 """Overrides parse_request to check credential.""" |
| 2032 |
| 2033 if not BaseHTTPServer.BaseHTTPRequestHandler.parse_request(self): |
| 2034 return False |
| 2035 |
| 2036 auth = self.headers.getheader('Proxy-Authorization') |
| 2037 if auth != self._AUTH_CREDENTIAL: |
| 2038 self.send_response(407) |
| 2039 self.send_header('Proxy-Authenticate', 'Basic realm="MyRealm1"') |
| 2040 self.end_headers() |
| 2041 return False |
| 2042 |
| 2043 return True |
| 2044 |
| 2045 def _start_read_write(self, sock): |
| 2046 sock.setblocking(0) |
| 2047 self.request.setblocking(0) |
| 2048 rlist = [self.request, sock] |
| 2049 while True: |
| 2050 ready_sockets, unused, errors = select.select(rlist, [], []) |
| 2051 if errors: |
| 2052 self.send_response(500) |
| 2053 self.end_headers() |
| 2054 return |
| 2055 for s in ready_sockets: |
| 2056 received = s.recv(1024) |
| 2057 if len(received) == 0: |
| 2058 return |
| 2059 if s == self.request: |
| 2060 other = sock |
| 2061 else: |
| 2062 other = self.request |
| 2063 other.send(received) |
| 2064 |
| 2065 def _do_common_method(self): |
| 2066 url = urlparse.urlparse(self.path) |
| 2067 port = url.port |
| 2068 if not port: |
| 2069 if url.scheme == 'http': |
| 2070 port = 80 |
| 2071 elif url.scheme == 'https': |
| 2072 port = 443 |
| 2073 if not url.hostname or not port: |
| 2074 self.send_response(400) |
| 2075 self.end_headers() |
| 2076 return |
| 2077 |
| 2078 if len(url.path) == 0: |
| 2079 path = '/' |
| 2080 else: |
| 2081 path = url.path |
| 2082 if len(url.query) > 0: |
| 2083 path = '%s?%s' % (url.path, url.query) |
| 2084 |
| 2085 sock = None |
| 2086 try: |
| 2087 sock = socket.create_connection((url.hostname, port)) |
| 2088 sock.send('%s %s %s\r\n' % ( |
| 2089 self.command, path, self.protocol_version)) |
| 2090 for header in self.headers.headers: |
| 2091 header = header.strip() |
| 2092 if (header.lower().startswith('connection') or |
| 2093 header.lower().startswith('proxy')): |
| 2094 continue |
| 2095 sock.send('%s\r\n' % header) |
| 2096 sock.send('\r\n') |
| 2097 self._start_read_write(sock) |
| 2098 except: |
| 2099 self.send_response(500) |
| 2100 self.end_headers() |
| 2101 finally: |
| 2102 if sock is not None: |
| 2103 sock.close() |
| 2104 |
| 2105 def do_CONNECT(self): |
| 2106 try: |
| 2107 pos = self.path.rfind(':') |
| 2108 host = self.path[:pos] |
| 2109 port = int(self.path[pos+1:]) |
| 2110 except: |
| 2111 self.send_response(400) |
| 2112 self.end_headers() |
| 2113 |
| 2114 try: |
| 2115 sock = socket.create_connection((host, port)) |
| 2116 self.send_response(200, 'Connection established') |
| 2117 self.end_headers() |
| 2118 self._start_read_write(sock) |
| 2119 except: |
| 2120 self.send_response(500) |
| 2121 self.end_headers() |
| 2122 finally: |
| 2123 sock.close() |
| 2124 |
| 2125 def do_GET(self): |
| 2126 self._do_common_method() |
| 2127 |
| 2128 def do_HEAD(self): |
| 2129 self._do_common_method() |
| 2130 |
| 2131 |
2022 class FileMultiplexer: | 2132 class FileMultiplexer: |
2023 def __init__(self, fd1, fd2) : | 2133 def __init__(self, fd1, fd2) : |
2024 self.__fd1 = fd1 | 2134 self.__fd1 = fd1 |
2025 self.__fd2 = fd2 | 2135 self.__fd2 = fd2 |
2026 | 2136 |
2027 def __del__(self) : | 2137 def __del__(self) : |
2028 if self.__fd1 != sys.stdout and self.__fd1 != sys.stderr: | 2138 if self.__fd1 != sys.stdout and self.__fd1 != sys.stderr: |
2029 self.__fd1.close() | 2139 self.__fd1.close() |
2030 if self.__fd2 != sys.stdout and self.__fd2 != sys.stderr: | 2140 if self.__fd2 != sys.stdout and self.__fd2 != sys.stderr: |
2031 self.__fd2.close() | 2141 self.__fd2.close() |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2130 server = TCPEchoServer((host, port), TCPEchoHandler) | 2240 server = TCPEchoServer((host, port), TCPEchoHandler) |
2131 print 'Echo TCP server started on port %d...' % server.server_port | 2241 print 'Echo TCP server started on port %d...' % server.server_port |
2132 server_data['port'] = server.server_port | 2242 server_data['port'] = server.server_port |
2133 elif options.server_type == SERVER_UDP_ECHO: | 2243 elif options.server_type == SERVER_UDP_ECHO: |
2134 # Used for generating the key (randomly) that encodes the "echo request" | 2244 # Used for generating the key (randomly) that encodes the "echo request" |
2135 # message. | 2245 # message. |
2136 random.seed() | 2246 random.seed() |
2137 server = UDPEchoServer((host, port), UDPEchoHandler) | 2247 server = UDPEchoServer((host, port), UDPEchoHandler) |
2138 print 'Echo UDP server started on port %d...' % server.server_port | 2248 print 'Echo UDP server started on port %d...' % server.server_port |
2139 server_data['port'] = server.server_port | 2249 server_data['port'] = server.server_port |
| 2250 elif options.server_type == SERVER_BASIC_AUTH_PROXY: |
| 2251 server = HTTPServer((host, port), BasicAuthProxyRequestHandler) |
| 2252 print 'BasicAuthProxy server started on port %d...' % server.server_port |
| 2253 server_data['port'] = server.server_port |
2140 # means FTP Server | 2254 # means FTP Server |
2141 else: | 2255 else: |
2142 my_data_dir = MakeDataDir() | 2256 my_data_dir = MakeDataDir() |
2143 | 2257 |
2144 # Instantiate a dummy authorizer for managing 'virtual' users | 2258 # Instantiate a dummy authorizer for managing 'virtual' users |
2145 authorizer = pyftpdlib.ftpserver.DummyAuthorizer() | 2259 authorizer = pyftpdlib.ftpserver.DummyAuthorizer() |
2146 | 2260 |
2147 # Define a new user having full r/w permissions and a read-only | 2261 # Define a new user having full r/w permissions and a read-only |
2148 # anonymous user | 2262 # anonymous user |
2149 authorizer.add_user('chrome', 'chrome', my_data_dir, perm='elradfmw') | 2263 authorizer.add_user('chrome', 'chrome', my_data_dir, perm='elradfmw') |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2204 dest='server_type', | 2318 dest='server_type', |
2205 help='start up a sync server.') | 2319 help='start up a sync server.') |
2206 option_parser.add_option('', '--tcp-echo', action='store_const', | 2320 option_parser.add_option('', '--tcp-echo', action='store_const', |
2207 const=SERVER_TCP_ECHO, default=SERVER_HTTP, | 2321 const=SERVER_TCP_ECHO, default=SERVER_HTTP, |
2208 dest='server_type', | 2322 dest='server_type', |
2209 help='start up a tcp echo server.') | 2323 help='start up a tcp echo server.') |
2210 option_parser.add_option('', '--udp-echo', action='store_const', | 2324 option_parser.add_option('', '--udp-echo', action='store_const', |
2211 const=SERVER_UDP_ECHO, default=SERVER_HTTP, | 2325 const=SERVER_UDP_ECHO, default=SERVER_HTTP, |
2212 dest='server_type', | 2326 dest='server_type', |
2213 help='start up a udp echo server.') | 2327 help='start up a udp echo server.') |
| 2328 option_parser.add_option('', '--basic-auth-proxy', action='store_const', |
| 2329 const=SERVER_BASIC_AUTH_PROXY, default=SERVER_HTTP, |
| 2330 dest='server_type', |
| 2331 help='start up a proxy server which requires basic ' |
| 2332 'authentication.') |
2214 option_parser.add_option('', '--log-to-console', action='store_const', | 2333 option_parser.add_option('', '--log-to-console', action='store_const', |
2215 const=True, default=False, | 2334 const=True, default=False, |
2216 dest='log_to_console', | 2335 dest='log_to_console', |
2217 help='Enables or disables sys.stdout logging to ' | 2336 help='Enables or disables sys.stdout logging to ' |
2218 'the console.') | 2337 'the console.') |
2219 option_parser.add_option('', '--port', default='0', type='int', | 2338 option_parser.add_option('', '--port', default='0', type='int', |
2220 help='Port used by the server. If unspecified, the ' | 2339 help='Port used by the server. If unspecified, the ' |
2221 'server will listen on an ephemeral port.') | 2340 'server will listen on an ephemeral port.') |
2222 option_parser.add_option('', '--xmpp-port', default='0', type='int', | 2341 option_parser.add_option('', '--xmpp-port', default='0', type='int', |
2223 help='Port used by the XMPP server. If unspecified, ' | 2342 help='Port used by the XMPP server. If unspecified, ' |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2286 dest='host', | 2405 dest='host', |
2287 help='Hostname or IP upon which the server will ' | 2406 help='Hostname or IP upon which the server will ' |
2288 'listen. Client connections will also only be ' | 2407 'listen. Client connections will also only be ' |
2289 'allowed from this address.') | 2408 'allowed from this address.') |
2290 option_parser.add_option('', '--auth-token', dest='auth_token', | 2409 option_parser.add_option('', '--auth-token', dest='auth_token', |
2291 help='Specify the auth token which should be used' | 2410 help='Specify the auth token which should be used' |
2292 'in the authorization header for GData.') | 2411 'in the authorization header for GData.') |
2293 options, args = option_parser.parse_args() | 2412 options, args = option_parser.parse_args() |
2294 | 2413 |
2295 sys.exit(main(options, args)) | 2414 sys.exit(main(options, args)) |
OLD | NEW |