Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: net/tools/testserver/testserver.py

Issue 9369029: Add '--host' option to testserver.py and expose it via a new TestServer constructor. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Integrate the definition of kLocalhost to facilitate follow-up CLs. Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« net/test/test_server.h ('K') | « net/test/test_server.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 def __init__(self): 75 def __init__(self):
76 self.log = [] 76 self.log = []
77 77
78 def __getitem__(self, sessionID): 78 def __getitem__(self, sessionID):
79 self.log.append(('lookup', sessionID)) 79 self.log.append(('lookup', sessionID))
80 raise KeyError() 80 raise KeyError()
81 81
82 def __setitem__(self, sessionID, session): 82 def __setitem__(self, sessionID, session):
83 self.log.append(('insert', sessionID)) 83 self.log.append(('insert', sessionID))
84 84
85
86 class ClientRestrictingServerMixIn:
87 """Implements verify_request to limit connections to our configured IP
88 address."""
89
90 def verify_request(self, request, client_address):
91 return client_address[0] == self.server_address[0]
92
93
85 class StoppableHTTPServer(BaseHTTPServer.HTTPServer): 94 class StoppableHTTPServer(BaseHTTPServer.HTTPServer):
86 """This is a specialization of of BaseHTTPServer to allow it 95 """This is a specialization of BaseHTTPServer to allow it
87 to be exited cleanly (by setting its "stop" member to True).""" 96 to be exited cleanly (by setting its "stop" member to True)."""
88 97
89 def serve_forever(self): 98 def serve_forever(self):
90 self.stop = False 99 self.stop = False
91 self.nonce_time = None 100 self.nonce_time = None
92 while not self.stop: 101 while not self.stop:
93 self.handle_request() 102 self.handle_request()
94 self.socket.close() 103 self.socket.close()
95 104
96 class HTTPSServer(tlslite.api.TLSSocketServerMixIn, StoppableHTTPServer): 105
97 """This is a specialization of StoppableHTTPerver that add https support.""" 106 class HTTPServer(ClientRestrictingServerMixIn, StoppableHTTPServer):
107 """This is a specialization of StoppableHTTPerver that adds client
108 verification."""
109
110 pass
111
112
113 class HTTPSServer(tlslite.api.TLSSocketServerMixIn,
114 ClientRestrictingServerMixIn,
115 StoppableHTTPServer):
116 """This is a specialization of StoppableHTTPerver that add https support and
117 client verification."""
98 118
99 def __init__(self, server_address, request_hander_class, cert_path, 119 def __init__(self, server_address, request_hander_class, cert_path,
100 ssl_client_auth, ssl_client_cas, ssl_bulk_ciphers, 120 ssl_client_auth, ssl_client_cas, ssl_bulk_ciphers,
101 record_resume_info): 121 record_resume_info):
102 s = open(cert_path).read() 122 s = open(cert_path).read()
103 x509 = tlslite.api.X509() 123 x509 = tlslite.api.X509()
104 x509.parse(s) 124 x509.parse(s)
105 self.cert_chain = tlslite.api.X509CertChain([x509]) 125 self.cert_chain = tlslite.api.X509CertChain([x509])
106 s = open(cert_path).read() 126 s = open(cert_path).read()
107 self.private_key = tlslite.api.parsePEMKey(s, private=True) 127 self.private_key = tlslite.api.parsePEMKey(s, private=True)
(...skipping 28 matching lines...) Expand all
136 tlsConnection.ignoreAbruptClose = True 156 tlsConnection.ignoreAbruptClose = True
137 return True 157 return True
138 except tlslite.api.TLSAbruptCloseError: 158 except tlslite.api.TLSAbruptCloseError:
139 # Ignore abrupt close. 159 # Ignore abrupt close.
140 return True 160 return True
141 except tlslite.api.TLSError, error: 161 except tlslite.api.TLSError, error:
142 print "Handshake failure:", str(error) 162 print "Handshake failure:", str(error)
143 return False 163 return False
144 164
145 165
146 class SyncHTTPServer(StoppableHTTPServer): 166 class SyncHTTPServer(ClientRestrictingServerMixIn, StoppableHTTPServer):
147 """An HTTP server that handles sync commands.""" 167 """An HTTP server that handles sync commands."""
148 168
149 def __init__(self, server_address, request_handler_class): 169 def __init__(self, server_address, request_handler_class):
150 # We import here to avoid pulling in chromiumsync's dependencies 170 # We import here to avoid pulling in chromiumsync's dependencies
151 # unless strictly necessary. 171 # unless strictly necessary.
152 import chromiumsync 172 import chromiumsync
153 import xmppserver 173 import xmppserver
154 StoppableHTTPServer.__init__(self, server_address, request_handler_class) 174 StoppableHTTPServer.__init__(self, server_address, request_handler_class)
155 self._sync_handler = chromiumsync.TestServer() 175 self._sync_handler = chromiumsync.TestServer()
156 self._xmpp_socket_map = {} 176 self._xmpp_socket_map = {}
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 261
242 for fd in write_fds: 262 for fd in write_fds:
243 HandleXmppSocket(fd, self._xmpp_socket_map, 263 HandleXmppSocket(fd, self._xmpp_socket_map,
244 asyncore.dispatcher.handle_write_event) 264 asyncore.dispatcher.handle_write_event)
245 265
246 for fd in exceptional_fds: 266 for fd in exceptional_fds:
247 HandleXmppSocket(fd, self._xmpp_socket_map, 267 HandleXmppSocket(fd, self._xmpp_socket_map,
248 asyncore.dispatcher.handle_expt_event) 268 asyncore.dispatcher.handle_expt_event)
249 269
250 270
251 class TCPEchoServer(SocketServer.TCPServer): 271 class FTPServer(ClientRestrictingServerMixIn, pyftpdlib.ftpserver.FTPServer):
272 """This is a specialization of FTPServer that adds client verification."""
273
274 pass
275
276
277 class TCPEchoServer(ClientRestrictingServerMixIn, SocketServer.TCPServer):
252 """A TCP echo server that echoes back what it has received.""" 278 """A TCP echo server that echoes back what it has received."""
253 279
254 def server_bind(self): 280 def server_bind(self):
255 """Override server_bind to store the server name.""" 281 """Override server_bind to store the server name."""
256 SocketServer.TCPServer.server_bind(self) 282 SocketServer.TCPServer.server_bind(self)
257 host, port = self.socket.getsockname()[:2] 283 host, port = self.socket.getsockname()[:2]
258 self.server_name = socket.getfqdn(host) 284 self.server_name = socket.getfqdn(host)
259 self.server_port = port 285 self.server_port = port
260 286
261 def serve_forever(self): 287 def serve_forever(self):
262 self.stop = False 288 self.stop = False
263 self.nonce_time = None 289 self.nonce_time = None
264 while not self.stop: 290 while not self.stop:
265 self.handle_request() 291 self.handle_request()
266 self.socket.close() 292 self.socket.close()
267 293
268 294
269 class UDPEchoServer(SocketServer.UDPServer): 295 class UDPEchoServer(ClientRestrictingServerMixIn, SocketServer.UDPServer):
270 """A UDP echo server that echoes back what it has received.""" 296 """A UDP echo server that echoes back what it has received."""
271 297
272 def server_bind(self): 298 def server_bind(self):
273 """Override server_bind to store the server name.""" 299 """Override server_bind to store the server name."""
274 SocketServer.UDPServer.server_bind(self) 300 SocketServer.UDPServer.server_bind(self)
275 host, port = self.socket.getsockname()[:2] 301 host, port = self.socket.getsockname()[:2]
276 self.server_name = socket.getfqdn(host) 302 self.server_name = socket.getfqdn(host)
277 self.server_port = port 303 self.server_port = port
278 304
279 def serve_forever(self): 305 def serve_forever(self):
(...skipping 1335 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 test_name = "/chromiumsync/command" 1641 test_name = "/chromiumsync/command"
1616 if not self._ShouldHandleRequest(test_name): 1642 if not self._ShouldHandleRequest(test_name):
1617 return False 1643 return False
1618 1644
1619 length = int(self.headers.getheader('content-length')) 1645 length = int(self.headers.getheader('content-length'))
1620 raw_request = self.rfile.read(length) 1646 raw_request = self.rfile.read(length)
1621 http_response = 200 1647 http_response = 200
1622 raw_reply = None 1648 raw_reply = None
1623 if not self.server.GetAuthenticated(): 1649 if not self.server.GetAuthenticated():
1624 http_response = 401 1650 http_response = 401
1625 challenge = 'GoogleLogin realm="http://127.0.0.1", service="chromiumsync"' 1651 challenge = 'GoogleLogin realm="http://%s", service="chromiumsync"' % (
1652 self.server.server_address[0])
1626 else: 1653 else:
1627 http_response, raw_reply = self.server.HandleCommand( 1654 http_response, raw_reply = self.server.HandleCommand(
1628 self.path, raw_request) 1655 self.path, raw_request)
1629 1656
1630 ### Now send the response to the client. ### 1657 ### Now send the response to the client. ###
1631 self.send_response(http_response) 1658 self.send_response(http_response)
1632 if http_response == 401: 1659 if http_response == 401:
1633 self.send_header('www-Authenticate', challenge) 1660 self.send_header('www-Authenticate', challenge)
1634 self.end_headers() 1661 self.end_headers()
1635 self.wfile.write(raw_reply) 1662 self.wfile.write(raw_reply)
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1862 1889
1863 def main(options, args): 1890 def main(options, args):
1864 logfile = open('testserver.log', 'w') 1891 logfile = open('testserver.log', 'w')
1865 sys.stderr = FileMultiplexer(sys.stderr, logfile) 1892 sys.stderr = FileMultiplexer(sys.stderr, logfile)
1866 if options.log_to_console: 1893 if options.log_to_console:
1867 sys.stdout = FileMultiplexer(sys.stdout, logfile) 1894 sys.stdout = FileMultiplexer(sys.stdout, logfile)
1868 else: 1895 else:
1869 sys.stdout = logfile 1896 sys.stdout = logfile
1870 1897
1871 port = options.port 1898 port = options.port
1899 host = options.host
1872 1900
1873 server_data = {} 1901 server_data = {}
1902 server_data['host'] = host
1874 1903
1875 if options.server_type == SERVER_HTTP: 1904 if options.server_type == SERVER_HTTP:
1876 if options.cert: 1905 if options.cert:
1877 # let's make sure the cert file exists. 1906 # let's make sure the cert file exists.
1878 if not os.path.isfile(options.cert): 1907 if not os.path.isfile(options.cert):
1879 print 'specified server cert file not found: ' + options.cert + \ 1908 print 'specified server cert file not found: ' + options.cert + \
1880 ' exiting...' 1909 ' exiting...'
1881 return 1910 return
1882 for ca_cert in options.ssl_client_ca: 1911 for ca_cert in options.ssl_client_ca:
1883 if not os.path.isfile(ca_cert): 1912 if not os.path.isfile(ca_cert):
1884 print 'specified trusted client CA file not found: ' + ca_cert + \ 1913 print 'specified trusted client CA file not found: ' + ca_cert + \
1885 ' exiting...' 1914 ' exiting...'
1886 return 1915 return
1887 server = HTTPSServer(('127.0.0.1', port), TestPageHandler, options.cert, 1916 server = HTTPSServer((host, port), TestPageHandler, options.cert,
1888 options.ssl_client_auth, options.ssl_client_ca, 1917 options.ssl_client_auth, options.ssl_client_ca,
1889 options.ssl_bulk_cipher, options.record_resume) 1918 options.ssl_bulk_cipher, options.record_resume)
1890 print 'HTTPS server started on port %d...' % server.server_port 1919 print 'HTTPS server started on %s:%d...' % (host, server.server_port)
eroman 2012/02/23 20:51:44 note that if host is an IPv6 literal, this host:po
1891 else: 1920 else:
1892 server = StoppableHTTPServer(('127.0.0.1', port), TestPageHandler) 1921 server = HTTPServer((host, port), TestPageHandler)
1893 print 'HTTP server started on port %d...' % server.server_port 1922 print 'HTTP server started on %s:%d...' % (host, server.server_port)
1894 1923
1895 server.data_dir = MakeDataDir() 1924 server.data_dir = MakeDataDir()
1896 server.file_root_url = options.file_root_url 1925 server.file_root_url = options.file_root_url
1897 server_data['port'] = server.server_port 1926 server_data['port'] = server.server_port
1898 server._device_management_handler = None 1927 server._device_management_handler = None
1899 server.policy_keys = options.policy_keys 1928 server.policy_keys = options.policy_keys
1900 server.policy_user = options.policy_user 1929 server.policy_user = options.policy_user
1901 elif options.server_type == SERVER_SYNC: 1930 elif options.server_type == SERVER_SYNC:
1902 server = SyncHTTPServer(('127.0.0.1', port), SyncPageHandler) 1931 server = SyncHTTPServer((host, port), SyncPageHandler)
1903 print 'Sync HTTP server started on port %d...' % server.server_port 1932 print 'Sync HTTP server started on port %d...' % server.server_port
1904 print 'Sync XMPP server started on port %d...' % server.xmpp_port 1933 print 'Sync XMPP server started on port %d...' % server.xmpp_port
1905 server_data['port'] = server.server_port 1934 server_data['port'] = server.server_port
1906 server_data['xmpp_port'] = server.xmpp_port 1935 server_data['xmpp_port'] = server.xmpp_port
1907 elif options.server_type == SERVER_TCP_ECHO: 1936 elif options.server_type == SERVER_TCP_ECHO:
1908 # Used for generating the key (randomly) that encodes the "echo request" 1937 # Used for generating the key (randomly) that encodes the "echo request"
1909 # message. 1938 # message.
1910 random.seed() 1939 random.seed()
1911 server = TCPEchoServer(('127.0.0.1', port), TCPEchoHandler) 1940 server = TCPEchoServer((host, port), TCPEchoHandler)
1912 print 'Echo TCP server started on port %d...' % server.server_port 1941 print 'Echo TCP server started on port %d...' % server.server_port
1913 server_data['port'] = server.server_port 1942 server_data['port'] = server.server_port
1914 elif options.server_type == SERVER_UDP_ECHO: 1943 elif options.server_type == SERVER_UDP_ECHO:
1915 # Used for generating the key (randomly) that encodes the "echo request" 1944 # Used for generating the key (randomly) that encodes the "echo request"
1916 # message. 1945 # message.
1917 random.seed() 1946 random.seed()
1918 server = UDPEchoServer(('127.0.0.1', port), UDPEchoHandler) 1947 server = UDPEchoServer((host, port), UDPEchoHandler)
1919 print 'Echo UDP server started on port %d...' % server.server_port 1948 print 'Echo UDP server started on port %d...' % server.server_port
1920 server_data['port'] = server.server_port 1949 server_data['port'] = server.server_port
1921 # means FTP Server 1950 # means FTP Server
1922 else: 1951 else:
1923 my_data_dir = MakeDataDir() 1952 my_data_dir = MakeDataDir()
1924 1953
1925 # Instantiate a dummy authorizer for managing 'virtual' users 1954 # Instantiate a dummy authorizer for managing 'virtual' users
1926 authorizer = pyftpdlib.ftpserver.DummyAuthorizer() 1955 authorizer = pyftpdlib.ftpserver.DummyAuthorizer()
1927 1956
1928 # Define a new user having full r/w permissions and a read-only 1957 # Define a new user having full r/w permissions and a read-only
1929 # anonymous user 1958 # anonymous user
1930 authorizer.add_user('chrome', 'chrome', my_data_dir, perm='elradfmw') 1959 authorizer.add_user('chrome', 'chrome', my_data_dir, perm='elradfmw')
1931 1960
1932 authorizer.add_anonymous(my_data_dir) 1961 authorizer.add_anonymous(my_data_dir)
1933 1962
1934 # Instantiate FTP handler class 1963 # Instantiate FTP handler class
1935 ftp_handler = pyftpdlib.ftpserver.FTPHandler 1964 ftp_handler = pyftpdlib.ftpserver.FTPHandler
1936 ftp_handler.authorizer = authorizer 1965 ftp_handler.authorizer = authorizer
1937 1966
1938 # Define a customized banner (string returned when client connects) 1967 # Define a customized banner (string returned when client connects)
1939 ftp_handler.banner = ("pyftpdlib %s based ftpd ready." % 1968 ftp_handler.banner = ("pyftpdlib %s based ftpd ready." %
1940 pyftpdlib.ftpserver.__ver__) 1969 pyftpdlib.ftpserver.__ver__)
1941 1970
1942 # Instantiate FTP server class and listen to 127.0.0.1:port 1971 # Instantiate FTP server class and listen to address:port
1943 address = ('127.0.0.1', port) 1972 server = pyftpdlib.ftpserver.FTPServer((host, port), ftp_handler)
1944 server = pyftpdlib.ftpserver.FTPServer(address, ftp_handler)
1945 server_data['port'] = server.socket.getsockname()[1] 1973 server_data['port'] = server.socket.getsockname()[1]
1946 print 'FTP server started on port %d...' % server_data['port'] 1974 print 'FTP server started on port %d...' % server_data['port']
1947 1975
1948 # Notify the parent that we've started. (BaseServer subclasses 1976 # Notify the parent that we've started. (BaseServer subclasses
1949 # bind their sockets on construction.) 1977 # bind their sockets on construction.)
1950 if options.startup_pipe is not None: 1978 if options.startup_pipe is not None:
1951 server_data_json = json.dumps(server_data) 1979 server_data_json = json.dumps(server_data)
1952 server_data_len = len(server_data_json) 1980 server_data_len = len(server_data_json)
1953 print 'sending server_data: %s (%d bytes)' % ( 1981 print 'sending server_data: %s (%d bytes)' % (
1954 server_data_json, server_data_len) 1982 server_data_json, server_data_len)
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2036 'the server. If ther server has multiple keys, it ' 2064 'the server. If ther server has multiple keys, it '
2037 'will rotate through them in at each request a ' 2065 'will rotate through them in at each request a '
2038 'round-robin fashion. The server will generate a ' 2066 'round-robin fashion. The server will generate a '
2039 'random key if none is specified on the command ' 2067 'random key if none is specified on the command '
2040 'line.') 2068 'line.')
2041 option_parser.add_option('', '--policy-user', default='user@example.com', 2069 option_parser.add_option('', '--policy-user', default='user@example.com',
2042 dest='policy_user', 2070 dest='policy_user',
2043 help='Specify the user name the server should ' 2071 help='Specify the user name the server should '
2044 'report back to the client as the user owning the ' 2072 'report back to the client as the user owning the '
2045 'token used for making the policy request.') 2073 'token used for making the policy request.')
2074 option_parser.add_option('', '--host', default='127.0.0.1',
2075 dest='host',
2076 help='Hostname or IP upon which the server will '
2077 'listen. Client connections will also only be '
2078 'allowed from this address.')
2046 options, args = option_parser.parse_args() 2079 options, args = option_parser.parse_args()
2047 2080
2048 sys.exit(main(options, args)) 2081 sys.exit(main(options, args))
OLDNEW
« net/test/test_server.h ('K') | « net/test/test_server.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698