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

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

Issue 10905087: Revert 154861 - Run safebrowsing_service_test through the net testserver code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « net/tools/testserver/run_testserver.cc ('k') | net/tools/testserver/testserver_base.py » ('j') | 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
11 explicit port if necessary. 11 explicit port if necessary.
12 It can use https if you specify the flag --https=CERT where CERT is the path 12 It can use https if you specify the flag --https=CERT where CERT is the path
13 to a pem file containing the certificate and private key that should be used. 13 to a pem file containing the certificate and private key that should be used.
14 """ 14 """
15 15
16 import asyncore 16 import asyncore
17 import base64 17 import base64
18 import BaseHTTPServer 18 import BaseHTTPServer
19 import cgi 19 import cgi
20 import errno 20 import errno
21 import hashlib
22 import httplib 21 import httplib
23 import minica 22 import minica
23 import optparse
24 import os 24 import os
25 import random 25 import random
26 import re 26 import re
27 import select 27 import select
28 import socket 28 import socket
29 import SocketServer 29 import SocketServer
30 import struct
30 import sys 31 import sys
31 import threading 32 import threading
32 import time 33 import time
33 import urllib 34 import urllib
34 import urlparse 35 import urlparse
36 import warnings
35 import zlib 37 import zlib
36 38
39 # Ignore deprecation warnings, they make our output more cluttered.
40 warnings.filterwarnings("ignore", category=DeprecationWarning)
41
37 import echo_message 42 import echo_message
38 import pyftpdlib.ftpserver 43 import pyftpdlib.ftpserver
39 import testserver_base
40 import tlslite 44 import tlslite
41 import tlslite.api 45 import tlslite.api
42 46
47 try:
48 import hashlib
49 _new_md5 = hashlib.md5
50 except ImportError:
51 import md5
52 _new_md5 = md5.new
43 53
44 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 54 try:
55 import json
56 except ImportError:
57 import simplejson as json
58
59 if sys.platform == 'win32':
60 import msvcrt
45 61
46 SERVER_HTTP = 0 62 SERVER_HTTP = 0
47 SERVER_FTP = 1 63 SERVER_FTP = 1
48 SERVER_SYNC = 2 64 SERVER_SYNC = 2
49 SERVER_TCP_ECHO = 3 65 SERVER_TCP_ECHO = 3
50 SERVER_UDP_ECHO = 4 66 SERVER_UDP_ECHO = 4
51 67
52
53 # Using debug() seems to cause hangs on XP: see http://crbug.com/64515 . 68 # Using debug() seems to cause hangs on XP: see http://crbug.com/64515 .
54 debug_output = sys.stderr 69 debug_output = sys.stderr
55 def debug(str): 70 def debug(str):
56 debug_output.write(str + "\n") 71 debug_output.write(str + "\n")
57 debug_output.flush() 72 debug_output.flush()
58 73
59
60 class RecordingSSLSessionCache(object): 74 class RecordingSSLSessionCache(object):
61 """RecordingSSLSessionCache acts as a TLS session cache and maintains a log of 75 """RecordingSSLSessionCache acts as a TLS session cache and maintains a log of
62 lookups and inserts in order to test session cache behaviours.""" 76 lookups and inserts in order to test session cache behaviours."""
63 77
64 def __init__(self): 78 def __init__(self):
65 self.log = [] 79 self.log = []
66 80
67 def __getitem__(self, sessionID): 81 def __getitem__(self, sessionID):
68 self.log.append(('lookup', sessionID)) 82 self.log.append(('lookup', sessionID))
69 raise KeyError() 83 raise KeyError()
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 118
105 def serve_forever_on_thread(self): 119 def serve_forever_on_thread(self):
106 self.thread = threading.Thread(target = self.serve_forever, 120 self.thread = threading.Thread(target = self.serve_forever,
107 name = "OCSPServerThread") 121 name = "OCSPServerThread")
108 self.thread.start() 122 self.thread.start()
109 123
110 def stop_serving(self): 124 def stop_serving(self):
111 self.shutdown() 125 self.shutdown()
112 self.thread.join() 126 self.thread.join()
113 127
114
115 class HTTPSServer(tlslite.api.TLSSocketServerMixIn, 128 class HTTPSServer(tlslite.api.TLSSocketServerMixIn,
116 ClientRestrictingServerMixIn, 129 ClientRestrictingServerMixIn,
117 StoppableHTTPServer): 130 StoppableHTTPServer):
118 """This is a specialization of StoppableHTTPServer that add https support and 131 """This is a specialization of StoppableHTTPServer that add https support and
119 client verification.""" 132 client verification."""
120 133
121 def __init__(self, server_address, request_hander_class, pem_cert_and_key, 134 def __init__(self, server_address, request_hander_class, pem_cert_and_key,
122 ssl_client_auth, ssl_client_cas, ssl_bulk_ciphers, 135 ssl_client_auth, ssl_client_cas, ssl_bulk_ciphers,
123 record_resume_info, tls_intolerant): 136 record_resume_info, tls_intolerant):
124 self.cert_chain = tlslite.api.X509CertChain().parseChain(pem_cert_and_key) 137 self.cert_chain = tlslite.api.X509CertChain().parseChain(pem_cert_and_key)
(...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 This is a fake implementation. A real implementation would only use a given 1310 This is a fake implementation. A real implementation would only use a given
1298 nonce a single time (hence the name n-once). However, for the purposes of 1311 nonce a single time (hence the name n-once). However, for the purposes of
1299 unittesting, we don't care about the security of the nonce. 1312 unittesting, we don't care about the security of the nonce.
1300 1313
1301 Args: 1314 Args:
1302 force_reset: Iff set, the nonce will be changed. Useful for testing the 1315 force_reset: Iff set, the nonce will be changed. Useful for testing the
1303 "stale" response. 1316 "stale" response.
1304 """ 1317 """
1305 if force_reset or not self.server.nonce_time: 1318 if force_reset or not self.server.nonce_time:
1306 self.server.nonce_time = time.time() 1319 self.server.nonce_time = time.time()
1307 return hashlib.md5('privatekey%s%d' % 1320 return _new_md5('privatekey%s%d' %
1308 (self.path, self.server.nonce_time)).hexdigest() 1321 (self.path, self.server.nonce_time)).hexdigest()
1309 1322
1310 def AuthDigestHandler(self): 1323 def AuthDigestHandler(self):
1311 """This handler tests 'Digest' authentication. 1324 """This handler tests 'Digest' authentication.
1312 1325
1313 It just sends a page with title 'user/pass' if you succeed. 1326 It just sends a page with title 'user/pass' if you succeed.
1314 1327
1315 A stale response is sent iff "stale" is present in the request path. 1328 A stale response is sent iff "stale" is present in the request path.
1316 """ 1329 """
1317 if not self._ShouldHandleRequest("/auth-digest"): 1330 if not self._ShouldHandleRequest("/auth-digest"):
1318 return False 1331 return False
1319 1332
1320 stale = 'stale' in self.path 1333 stale = 'stale' in self.path
1321 nonce = self.GetNonce(force_reset=stale) 1334 nonce = self.GetNonce(force_reset=stale)
1322 opaque = hashlib.md5('opaque').hexdigest() 1335 opaque = _new_md5('opaque').hexdigest()
1323 password = 'secret' 1336 password = 'secret'
1324 realm = 'testrealm' 1337 realm = 'testrealm'
1325 1338
1326 auth = self.headers.getheader('authorization') 1339 auth = self.headers.getheader('authorization')
1327 pairs = {} 1340 pairs = {}
1328 try: 1341 try:
1329 if not auth: 1342 if not auth:
1330 raise Exception('no auth') 1343 raise Exception('no auth')
1331 if not auth.startswith('Digest'): 1344 if not auth.startswith('Digest'):
1332 raise Exception('not digest') 1345 raise Exception('not digest')
1333 # Pull out all the name="value" pairs as a dictionary. 1346 # Pull out all the name="value" pairs as a dictionary.
1334 pairs = dict(re.findall(r'(\b[^ ,=]+)="?([^",]+)"?', auth)) 1347 pairs = dict(re.findall(r'(\b[^ ,=]+)="?([^",]+)"?', auth))
1335 1348
1336 # Make sure it's all valid. 1349 # Make sure it's all valid.
1337 if pairs['nonce'] != nonce: 1350 if pairs['nonce'] != nonce:
1338 raise Exception('wrong nonce') 1351 raise Exception('wrong nonce')
1339 if pairs['opaque'] != opaque: 1352 if pairs['opaque'] != opaque:
1340 raise Exception('wrong opaque') 1353 raise Exception('wrong opaque')
1341 1354
1342 # Check the 'response' value and make sure it matches our magic hash. 1355 # Check the 'response' value and make sure it matches our magic hash.
1343 # See http://www.ietf.org/rfc/rfc2617.txt 1356 # See http://www.ietf.org/rfc/rfc2617.txt
1344 hash_a1 = hashlib.md5( 1357 hash_a1 = _new_md5(
1345 ':'.join([pairs['username'], realm, password])).hexdigest() 1358 ':'.join([pairs['username'], realm, password])).hexdigest()
1346 hash_a2 = hashlib.md5(':'.join([self.command, pairs['uri']])).hexdigest() 1359 hash_a2 = _new_md5(':'.join([self.command, pairs['uri']])).hexdigest()
1347 if 'qop' in pairs and 'nc' in pairs and 'cnonce' in pairs: 1360 if 'qop' in pairs and 'nc' in pairs and 'cnonce' in pairs:
1348 response = hashlib.md5(':'.join([hash_a1, nonce, pairs['nc'], 1361 response = _new_md5(':'.join([hash_a1, nonce, pairs['nc'],
1349 pairs['cnonce'], pairs['qop'], hash_a2])).hexdigest() 1362 pairs['cnonce'], pairs['qop'], hash_a2])).hexdigest()
1350 else: 1363 else:
1351 response = hashlib.md5(':'.join([hash_a1, nonce, hash_a2])).hexdigest() 1364 response = _new_md5(':'.join([hash_a1, nonce, hash_a2])).hexdigest()
1352 1365
1353 if pairs['response'] != response: 1366 if pairs['response'] != response:
1354 raise Exception('wrong password') 1367 raise Exception('wrong password')
1355 except Exception, e: 1368 except Exception, e:
1356 # Authentication failed. 1369 # Authentication failed.
1357 self.send_response(401) 1370 self.send_response(401)
1358 hdr = ('Digest ' 1371 hdr = ('Digest '
1359 'realm="%s", ' 1372 'realm="%s", '
1360 'domain="/", ' 1373 'domain="/", '
1361 'qop="auth", ' 1374 'qop="auth", '
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
1921 return False 1934 return False
1922 result, raw_reply = self.server._sync_handler.HandleCreateSyncedBookmarks() 1935 result, raw_reply = self.server._sync_handler.HandleCreateSyncedBookmarks()
1923 self.send_response(result) 1936 self.send_response(result)
1924 self.send_header('Content-Type', 'text/html') 1937 self.send_header('Content-Type', 'text/html')
1925 self.send_header('Content-Length', len(raw_reply)) 1938 self.send_header('Content-Length', len(raw_reply))
1926 self.end_headers() 1939 self.end_headers()
1927 self.wfile.write(raw_reply) 1940 self.wfile.write(raw_reply)
1928 return True; 1941 return True;
1929 1942
1930 1943
1944 def MakeDataDir():
1945 if options.data_dir:
1946 if not os.path.isdir(options.data_dir):
1947 print 'specified data dir not found: ' + options.data_dir + ' exiting...'
1948 return None
1949 my_data_dir = options.data_dir
1950 else:
1951 # Create the default path to our data dir, relative to the exe dir.
1952 my_data_dir = os.path.dirname(sys.argv[0])
1953 my_data_dir = os.path.join(my_data_dir, "..", "..", "..", "..",
1954 "test", "data")
1955
1956 #TODO(ibrar): Must use Find* funtion defined in google\tools
1957 #i.e my_data_dir = FindUpward(my_data_dir, "test", "data")
1958
1959 return my_data_dir
1960
1931 class OCSPHandler(BasePageHandler): 1961 class OCSPHandler(BasePageHandler):
1932 def __init__(self, request, client_address, socket_server): 1962 def __init__(self, request, client_address, socket_server):
1933 handlers = [self.OCSPResponse] 1963 handlers = [self.OCSPResponse]
1934 self.ocsp_response = socket_server.ocsp_response 1964 self.ocsp_response = socket_server.ocsp_response
1935 BasePageHandler.__init__(self, request, client_address, socket_server, 1965 BasePageHandler.__init__(self, request, client_address, socket_server,
1936 [], handlers, [], handlers, []) 1966 [], handlers, [], handlers, [])
1937 1967
1938 def OCSPResponse(self): 1968 def OCSPResponse(self):
1939 self.send_response(200) 1969 self.send_response(200)
1940 self.send_header('Content-Type', 'application/ocsp-response') 1970 self.send_header('Content-Type', 'application/ocsp-response')
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1982 # "echo response" message if "echo request" message is valid. 2012 # "echo response" message if "echo request" message is valid.
1983 try: 2013 try:
1984 return_data = echo_message.GetEchoResponseData(data) 2014 return_data = echo_message.GetEchoResponseData(data)
1985 if not return_data: 2015 if not return_data:
1986 return 2016 return
1987 except ValueError: 2017 except ValueError:
1988 return 2018 return
1989 socket.sendto(return_data, self.client_address) 2019 socket.sendto(return_data, self.client_address)
1990 2020
1991 2021
1992 class ServerRunner(testserver_base.TestServerRunner): 2022 class FileMultiplexer:
1993 """TestServerRunner for the net test servers.""" 2023 def __init__(self, fd1, fd2) :
1994 2024 self.__fd1 = fd1
1995 def __init__(self): 2025 self.__fd2 = fd2
1996 super(ServerRunner, self).__init__() 2026
1997 self.__ocsp_server = None 2027 def __del__(self) :
1998 2028 if self.__fd1 != sys.stdout and self.__fd1 != sys.stderr:
1999 def __make_data_dir(self): 2029 self.__fd1.close()
2000 if self.options.data_dir: 2030 if self.__fd2 != sys.stdout and self.__fd2 != sys.stderr:
2001 if not os.path.isdir(self.options.data_dir): 2031 self.__fd2.close()
2002 raise testserver_base.OptionError('specified data dir not found: ' + 2032
2003 self.options.data_dir + ' exiting...') 2033 def write(self, text) :
2004 my_data_dir = self.options.data_dir 2034 self.__fd1.write(text)
2035 self.__fd2.write(text)
2036
2037 def flush(self) :
2038 self.__fd1.flush()
2039 self.__fd2.flush()
2040
2041 def main(options, args):
2042 logfile = open('testserver.log', 'w')
2043 sys.stderr = FileMultiplexer(sys.stderr, logfile)
2044 if options.log_to_console:
2045 sys.stdout = FileMultiplexer(sys.stdout, logfile)
2046 else:
2047 sys.stdout = logfile
2048
2049 port = options.port
2050 host = options.host
2051
2052 server_data = {}
2053 server_data['host'] = host
2054
2055 ocsp_server = None
2056
2057 if options.server_type == SERVER_HTTP:
2058 if options.https:
2059 pem_cert_and_key = None
2060 if options.cert_and_key_file:
2061 if not os.path.isfile(options.cert_and_key_file):
2062 print ('specified server cert file not found: ' +
2063 options.cert_and_key_file + ' exiting...')
2064 return
2065 pem_cert_and_key = file(options.cert_and_key_file, 'r').read()
2066 else:
2067 # generate a new certificate and run an OCSP server for it.
2068 ocsp_server = OCSPServer((host, 0), OCSPHandler)
2069 print ('OCSP server started on %s:%d...' %
2070 (host, ocsp_server.server_port))
2071
2072 ocsp_der = None
2073 ocsp_state = None
2074
2075 if options.ocsp == 'ok':
2076 ocsp_state = minica.OCSP_STATE_GOOD
2077 elif options.ocsp == 'revoked':
2078 ocsp_state = minica.OCSP_STATE_REVOKED
2079 elif options.ocsp == 'invalid':
2080 ocsp_state = minica.OCSP_STATE_INVALID
2081 elif options.ocsp == 'unauthorized':
2082 ocsp_state = minica.OCSP_STATE_UNAUTHORIZED
2083 elif options.ocsp == 'unknown':
2084 ocsp_state = minica.OCSP_STATE_UNKNOWN
2085 else:
2086 print 'unknown OCSP status: ' + options.ocsp_status
2087 return
2088
2089 (pem_cert_and_key, ocsp_der) = \
2090 minica.GenerateCertKeyAndOCSP(
2091 subject = "127.0.0.1",
2092 ocsp_url = ("http://%s:%d/ocsp" %
2093 (host, ocsp_server.server_port)),
2094 ocsp_state = ocsp_state)
2095
2096 ocsp_server.ocsp_response = ocsp_der
2097
2098 for ca_cert in options.ssl_client_ca:
2099 if not os.path.isfile(ca_cert):
2100 print 'specified trusted client CA file not found: ' + ca_cert + \
2101 ' exiting...'
2102 return
2103 server = HTTPSServer((host, port), TestPageHandler, pem_cert_and_key,
2104 options.ssl_client_auth, options.ssl_client_ca,
2105 options.ssl_bulk_cipher, options.record_resume,
2106 options.tls_intolerant)
2107 print 'HTTPS server started on %s:%d...' % (host, server.server_port)
2005 else: 2108 else:
2006 # Create the default path to our data dir, relative to the exe dir. 2109 server = HTTPServer((host, port), TestPageHandler)
2007 my_data_dir = os.path.join(BASE_DIR, "..", "..", "..", "..", 2110 print 'HTTP server started on %s:%d...' % (host, server.server_port)
2008 "test", "data") 2111
2009 2112 server.data_dir = MakeDataDir()
2010 #TODO(ibrar): Must use Find* funtion defined in google\tools 2113 server.file_root_url = options.file_root_url
2011 #i.e my_data_dir = FindUpward(my_data_dir, "test", "data") 2114 server_data['port'] = server.server_port
2012 2115 server._device_management_handler = None
2013 return my_data_dir 2116 server.policy_keys = options.policy_keys
2014 2117 server.policy_user = options.policy_user
2015 def create_server(self, server_data): 2118 server.gdata_auth_token = options.auth_token
2016 port = self.options.port 2119 elif options.server_type == SERVER_SYNC:
2017 host = self.options.host 2120 xmpp_port = options.xmpp_port
2018 2121 server = SyncHTTPServer((host, port), xmpp_port, SyncPageHandler)
2019 if self.options.server_type == SERVER_HTTP: 2122 print 'Sync HTTP server started on port %d...' % server.server_port
2020 if self.options.https: 2123 print 'Sync XMPP server started on port %d...' % server.xmpp_port
2021 pem_cert_and_key = None 2124 server_data['port'] = server.server_port
2022 if self.options.cert_and_key_file: 2125 server_data['xmpp_port'] = server.xmpp_port
2023 if not os.path.isfile(self.options.cert_and_key_file): 2126 elif options.server_type == SERVER_TCP_ECHO:
2024 raise testserver_base.OptionError( 2127 # Used for generating the key (randomly) that encodes the "echo request"
2025 'specified server cert file not found: ' + 2128 # message.
2026 self.options.cert_and_key_file + ' exiting...') 2129 random.seed()
2027 pem_cert_and_key = file(self.options.cert_and_key_file, 'r').read() 2130 server = TCPEchoServer((host, port), TCPEchoHandler)
2028 else: 2131 print 'Echo TCP server started on port %d...' % server.server_port
2029 # generate a new certificate and run an OCSP server for it. 2132 server_data['port'] = server.server_port
2030 self.__ocsp_server = OCSPServer((host, 0), OCSPHandler) 2133 elif options.server_type == SERVER_UDP_ECHO:
2031 print ('OCSP server started on %s:%d...' % 2134 # Used for generating the key (randomly) that encodes the "echo request"
2032 (host, self.__ocsp_server.server_port)) 2135 # message.
2033 2136 random.seed()
2034 ocsp_der = None 2137 server = UDPEchoServer((host, port), UDPEchoHandler)
2035 ocsp_state = None 2138 print 'Echo UDP server started on port %d...' % server.server_port
2036 2139 server_data['port'] = server.server_port
2037 if self.options.ocsp == 'ok': 2140 # means FTP Server
2038 ocsp_state = minica.OCSP_STATE_GOOD 2141 else:
2039 elif self.options.ocsp == 'revoked': 2142 my_data_dir = MakeDataDir()
2040 ocsp_state = minica.OCSP_STATE_REVOKED 2143
2041 elif self.options.ocsp == 'invalid': 2144 # Instantiate a dummy authorizer for managing 'virtual' users
2042 ocsp_state = minica.OCSP_STATE_INVALID 2145 authorizer = pyftpdlib.ftpserver.DummyAuthorizer()
2043 elif self.options.ocsp == 'unauthorized': 2146
2044 ocsp_state = minica.OCSP_STATE_UNAUTHORIZED 2147 # Define a new user having full r/w permissions and a read-only
2045 elif self.options.ocsp == 'unknown': 2148 # anonymous user
2046 ocsp_state = minica.OCSP_STATE_UNKNOWN 2149 authorizer.add_user('chrome', 'chrome', my_data_dir, perm='elradfmw')
2047 else: 2150
2048 raise testserver_base.OptionError('unknown OCSP status: ' + 2151 authorizer.add_anonymous(my_data_dir)
2049 self.options.ocsp_status) 2152
2050 2153 # Instantiate FTP handler class
2051 (pem_cert_and_key, ocsp_der) = minica.GenerateCertKeyAndOCSP( 2154 ftp_handler = pyftpdlib.ftpserver.FTPHandler
2052 subject = "127.0.0.1", 2155 ftp_handler.authorizer = authorizer
2053 ocsp_url = ("http://%s:%d/ocsp" % 2156
2054 (host, self.__ocsp_server.server_port)), 2157 # Define a customized banner (string returned when client connects)
2055 ocsp_state = ocsp_state) 2158 ftp_handler.banner = ("pyftpdlib %s based ftpd ready." %
2056 2159 pyftpdlib.ftpserver.__ver__)
2057 self.__ocsp_server.ocsp_response = ocsp_der 2160
2058 2161 # Instantiate FTP server class and listen to address:port
2059 for ca_cert in self.options.ssl_client_ca: 2162 server = pyftpdlib.ftpserver.FTPServer((host, port), ftp_handler)
2060 if not os.path.isfile(ca_cert): 2163 server_data['port'] = server.socket.getsockname()[1]
2061 raise testserver_base.OptionError( 2164 print 'FTP server started on port %d...' % server_data['port']
2062 'specified trusted client CA file not found: ' + ca_cert + 2165
2063 ' exiting...') 2166 # Notify the parent that we've started. (BaseServer subclasses
2064 server = HTTPSServer((host, port), TestPageHandler, pem_cert_and_key, 2167 # bind their sockets on construction.)
2065 self.options.ssl_client_auth, 2168 if options.startup_pipe is not None:
2066 self.options.ssl_client_ca, 2169 server_data_json = json.dumps(server_data)
2067 self.options.ssl_bulk_cipher, 2170 server_data_len = len(server_data_json)
2068 self.options.record_resume, 2171 print 'sending server_data: %s (%d bytes)' % (
2069 self.options.tls_intolerant) 2172 server_data_json, server_data_len)
2070 print 'HTTPS server started on %s:%d...' % (host, server.server_port) 2173 if sys.platform == 'win32':
2071 else: 2174 fd = msvcrt.open_osfhandle(options.startup_pipe, 0)
2072 server = HTTPServer((host, port), TestPageHandler)
2073 print 'HTTP server started on %s:%d...' % (host, server.server_port)
2074
2075 server.data_dir = self.__make_data_dir()
2076 server.file_root_url = self.options.file_root_url
2077 server_data['port'] = server.server_port
2078 server._device_management_handler = None
2079 server.policy_keys = self.options.policy_keys
2080 server.policy_user = self.options.policy_user
2081 server.gdata_auth_token = self.options.auth_token
2082 elif self.options.server_type == SERVER_SYNC:
2083 xmpp_port = self.options.xmpp_port
2084 server = SyncHTTPServer((host, port), xmpp_port, SyncPageHandler)
2085 print 'Sync HTTP server started on port %d...' % server.server_port
2086 print 'Sync XMPP server started on port %d...' % server.xmpp_port
2087 server_data['port'] = server.server_port
2088 server_data['xmpp_port'] = server.xmpp_port
2089 elif self.options.server_type == SERVER_TCP_ECHO:
2090 # Used for generating the key (randomly) that encodes the "echo request"
2091 # message.
2092 random.seed()
2093 server = TCPEchoServer((host, port), TCPEchoHandler)
2094 print 'Echo TCP server started on port %d...' % server.server_port
2095 server_data['port'] = server.server_port
2096 elif self.options.server_type == SERVER_UDP_ECHO:
2097 # Used for generating the key (randomly) that encodes the "echo request"
2098 # message.
2099 random.seed()
2100 server = UDPEchoServer((host, port), UDPEchoHandler)
2101 print 'Echo UDP server started on port %d...' % server.server_port
2102 server_data['port'] = server.server_port
2103 elif self.options.server_type == SERVER_FTP:
2104 my_data_dir = self.__make_data_dir()
2105
2106 # Instantiate a dummy authorizer for managing 'virtual' users
2107 authorizer = pyftpdlib.ftpserver.DummyAuthorizer()
2108
2109 # Define a new user having full r/w permissions and a read-only
2110 # anonymous user
2111 authorizer.add_user('chrome', 'chrome', my_data_dir, perm='elradfmw')
2112
2113 authorizer.add_anonymous(my_data_dir)
2114
2115 # Instantiate FTP handler class
2116 ftp_handler = pyftpdlib.ftpserver.FTPHandler
2117 ftp_handler.authorizer = authorizer
2118
2119 # Define a customized banner (string returned when client connects)
2120 ftp_handler.banner = ("pyftpdlib %s based ftpd ready." %
2121 pyftpdlib.ftpserver.__ver__)
2122
2123 # Instantiate FTP server class and listen to address:port
2124 server = pyftpdlib.ftpserver.FTPServer((host, port), ftp_handler)
2125 server_data['port'] = server.socket.getsockname()[1]
2126 print 'FTP server started on port %d...' % server_data['port']
2127 else: 2175 else:
2128 raise testserver_base.OptionError('unknown server type' + 2176 fd = options.startup_pipe
2129 self.options.server_type) 2177 startup_pipe = os.fdopen(fd, "w")
2130 2178 # First write the data length as an unsigned 4-byte value. This
2131 return server 2179 # is _not_ using network byte ordering since the other end of the
2132 2180 # pipe is on the same machine.
2133 def run_server(self): 2181 startup_pipe.write(struct.pack('=L', server_data_len))
2134 if self.__ocsp_server: 2182 startup_pipe.write(server_data_json)
2135 self.__ocsp_server.serve_forever_on_thread() 2183 startup_pipe.close()
2136 2184
2137 testserver_base.TestServerRunner.run_server(self) 2185 if ocsp_server is not None:
2138 2186 ocsp_server.serve_forever_on_thread()
2139 if self.__ocsp_server: 2187
2140 self.__ocsp_server.stop_serving() 2188 try:
2141 2189 server.serve_forever()
2142 def add_options(self): 2190 except KeyboardInterrupt:
2143 testserver_base.TestServerRunner.add_options(self) 2191 print 'shutting down server'
2144 self.option_parser.add_option('-f', '--ftp', action='store_const', 2192 if ocsp_server is not None:
2145 const=SERVER_FTP, default=SERVER_HTTP, 2193 ocsp_server.stop_serving()
2146 dest='server_type', 2194 server.stop = True
2147 help='start up an FTP server.')
2148 self.option_parser.add_option('--sync', action='store_const',
2149 const=SERVER_SYNC, default=SERVER_HTTP,
2150 dest='server_type',
2151 help='start up a sync server.')
2152 self.option_parser.add_option('--tcp-echo', action='store_const',
2153 const=SERVER_TCP_ECHO, default=SERVER_HTTP,
2154 dest='server_type',
2155 help='start up a tcp echo server.')
2156 self.option_parser.add_option('--udp-echo', action='store_const',
2157 const=SERVER_UDP_ECHO, default=SERVER_HTTP,
2158 dest='server_type',
2159 help='start up a udp echo server.')
2160 self.option_parser.add_option('--xmpp-port', default='0', type='int',
2161 help='Port used by the XMPP server. If '
2162 'unspecified, the XMPP server will listen on '
2163 'an ephemeral port.')
2164 self.option_parser.add_option('--data-dir', dest='data_dir',
2165 help='Directory from which to read the '
2166 'files.')
2167 self.option_parser.add_option('--https', action='store_true',
2168 dest='https', help='Specify that https '
2169 'should be used.')
2170 self.option_parser.add_option('--cert-and-key-file',
2171 dest='cert_and_key_file', help='specify the '
2172 'path to the file containing the certificate '
2173 'and private key for the server in PEM '
2174 'format')
2175 self.option_parser.add_option('--ocsp', dest='ocsp', default='ok',
2176 help='The type of OCSP response generated '
2177 'for the automatically generated '
2178 'certificate. One of [ok,revoked,invalid]')
2179 self.option_parser.add_option('--tls-intolerant', dest='tls_intolerant',
2180 default='0', type='int',
2181 help='If nonzero, certain TLS connections '
2182 'will be aborted in order to test version '
2183 'fallback. 1 means all TLS versions will be '
2184 'aborted. 2 means TLS 1.1 or higher will be '
2185 'aborted. 3 means TLS 1.2 or higher will be '
2186 'aborted.')
2187 self.option_parser.add_option('--https-record-resume',
2188 dest='record_resume', const=True,
2189 default=False, action='store_const',
2190 help='Record resumption cache events rather '
2191 'than resuming as normal. Allows the use of '
2192 'the /ssl-session-cache request')
2193 self.option_parser.add_option('--ssl-client-auth', action='store_true',
2194 help='Require SSL client auth on every '
2195 'connection.')
2196 self.option_parser.add_option('--ssl-client-ca', action='append',
2197 default=[], help='Specify that the client '
2198 'certificate request should include the CA '
2199 'named in the subject of the DER-encoded '
2200 'certificate contained in the specified '
2201 'file. This option may appear multiple '
2202 'times, indicating multiple CA names should '
2203 'be sent in the request.')
2204 self.option_parser.add_option('--ssl-bulk-cipher', action='append',
2205 help='Specify the bulk encryption '
2206 'algorithm(s) that will be accepted by the '
2207 'SSL server. Valid values are "aes256", '
2208 '"aes128", "3des", "rc4". If omitted, all '
2209 'algorithms will be used. This option may '
2210 'appear multiple times, indicating '
2211 'multiple algorithms should be enabled.');
2212 self.option_parser.add_option('--file-root-url', default='/files/',
2213 help='Specify a root URL for files served.')
2214 self.option_parser.add_option('--policy-key', action='append',
2215 dest='policy_keys',
2216 help='Specify a path to a PEM-encoded '
2217 'private key to use for policy signing. May '
2218 'be specified multiple times in order to '
2219 'load multipe keys into the server. If the '
2220 'server has multiple keys, it will rotate '
2221 'through them in at each request a '
2222 'round-robin fashion. The server will '
2223 'generate a random key if none is specified '
2224 'on the command line.')
2225 self.option_parser.add_option('--policy-user',
2226 default='user@example.com',
2227 dest='policy_user',
2228 help='Specify the user name the server '
2229 'should report back to the client as the '
2230 'user owning the token used for making the '
2231 'policy request.')
2232 self.option_parser.add_option('--auth-token', dest='auth_token',
2233 help='Specify the auth token which should be '
2234 'used in the authorization header for GData.')
2235
2236 2195
2237 if __name__ == '__main__': 2196 if __name__ == '__main__':
2238 sys.exit(ServerRunner().main()) 2197 option_parser = optparse.OptionParser()
2198 option_parser.add_option("-f", '--ftp', action='store_const',
2199 const=SERVER_FTP, default=SERVER_HTTP,
2200 dest='server_type',
2201 help='start up an FTP server.')
2202 option_parser.add_option('', '--sync', action='store_const',
2203 const=SERVER_SYNC, default=SERVER_HTTP,
2204 dest='server_type',
2205 help='start up a sync server.')
2206 option_parser.add_option('', '--tcp-echo', action='store_const',
2207 const=SERVER_TCP_ECHO, default=SERVER_HTTP,
2208 dest='server_type',
2209 help='start up a tcp echo server.')
2210 option_parser.add_option('', '--udp-echo', action='store_const',
2211 const=SERVER_UDP_ECHO, default=SERVER_HTTP,
2212 dest='server_type',
2213 help='start up a udp echo server.')
2214 option_parser.add_option('', '--log-to-console', action='store_const',
2215 const=True, default=False,
2216 dest='log_to_console',
2217 help='Enables or disables sys.stdout logging to '
2218 'the console.')
2219 option_parser.add_option('', '--port', default='0', type='int',
2220 help='Port used by the server. If unspecified, the '
2221 'server will listen on an ephemeral port.')
2222 option_parser.add_option('', '--xmpp-port', default='0', type='int',
2223 help='Port used by the XMPP server. If unspecified, '
2224 'the XMPP server will listen on an ephemeral port.')
2225 option_parser.add_option('', '--data-dir', dest='data_dir',
2226 help='Directory from which to read the files.')
2227 option_parser.add_option('', '--https', action='store_true', dest='https',
2228 help='Specify that https should be used.')
2229 option_parser.add_option('', '--cert-and-key-file', dest='cert_and_key_file',
2230 help='specify the path to the file containing the '
2231 'certificate and private key for the server in PEM '
2232 'format')
2233 option_parser.add_option('', '--ocsp', dest='ocsp', default='ok',
2234 help='The type of OCSP response generated for the '
2235 'automatically generated certificate. One of '
2236 '[ok,revoked,invalid]')
2237 option_parser.add_option('', '--tls-intolerant', dest='tls_intolerant',
2238 default='0', type='int',
2239 help='If nonzero, certain TLS connections will be'
2240 ' aborted in order to test version fallback. 1'
2241 ' means all TLS versions will be aborted. 2 means'
2242 ' TLS 1.1 or higher will be aborted. 3 means TLS'
2243 ' 1.2 or higher will be aborted.')
2244 option_parser.add_option('', '--https-record-resume', dest='record_resume',
2245 const=True, default=False, action='store_const',
2246 help='Record resumption cache events rather than'
2247 ' resuming as normal. Allows the use of the'
2248 ' /ssl-session-cache request')
2249 option_parser.add_option('', '--ssl-client-auth', action='store_true',
2250 help='Require SSL client auth on every connection.')
2251 option_parser.add_option('', '--ssl-client-ca', action='append', default=[],
2252 help='Specify that the client certificate request '
2253 'should include the CA named in the subject of '
2254 'the DER-encoded certificate contained in the '
2255 'specified file. This option may appear multiple '
2256 'times, indicating multiple CA names should be '
2257 'sent in the request.')
2258 option_parser.add_option('', '--ssl-bulk-cipher', action='append',
2259 help='Specify the bulk encryption algorithm(s)'
2260 'that will be accepted by the SSL server. Valid '
2261 'values are "aes256", "aes128", "3des", "rc4". If '
2262 'omitted, all algorithms will be used. This '
2263 'option may appear multiple times, indicating '
2264 'multiple algorithms should be enabled.');
2265 option_parser.add_option('', '--file-root-url', default='/files/',
2266 help='Specify a root URL for files served.')
2267 option_parser.add_option('', '--startup-pipe', type='int',
2268 dest='startup_pipe',
2269 help='File handle of pipe to parent process')
2270 option_parser.add_option('', '--policy-key', action='append',
2271 dest='policy_keys',
2272 help='Specify a path to a PEM-encoded private key '
2273 'to use for policy signing. May be specified '
2274 'multiple times in order to load multipe keys into '
2275 'the server. If ther server has multiple keys, it '
2276 'will rotate through them in at each request a '
2277 'round-robin fashion. The server will generate a '
2278 'random key if none is specified on the command '
2279 'line.')
2280 option_parser.add_option('', '--policy-user', default='user@example.com',
2281 dest='policy_user',
2282 help='Specify the user name the server should '
2283 'report back to the client as the user owning the '
2284 'token used for making the policy request.')
2285 option_parser.add_option('', '--host', default='127.0.0.1',
2286 dest='host',
2287 help='Hostname or IP upon which the server will '
2288 'listen. Client connections will also only be '
2289 'allowed from this address.')
2290 option_parser.add_option('', '--auth-token', dest='auth_token',
2291 help='Specify the auth token which should be used'
2292 'in the authorization header for GData.')
2293 options, args = option_parser.parse_args()
2294
2295 sys.exit(main(options, args))
OLDNEW
« no previous file with comments | « net/tools/testserver/run_testserver.cc ('k') | net/tools/testserver/testserver_base.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698