OLD | NEW |
1 #!/usr/bin/python2.4 | 1 #!/usr/bin/python2.4 |
2 # Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2006-2010 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 server used for testing Chrome. | 6 """This is a simple HTTP 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 It defaults to living on localhost:8888. | 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 |
| 11 explicit port if necessary. |
10 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 |
11 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. |
12 """ | 14 """ |
13 | 15 |
14 import base64 | 16 import base64 |
15 import BaseHTTPServer | 17 import BaseHTTPServer |
16 import cgi | 18 import cgi |
17 import optparse | 19 import optparse |
18 import os | 20 import os |
19 import re | 21 import re |
20 import shutil | 22 import shutil |
21 import SocketServer | 23 import SocketServer |
22 import sys | 24 import sys |
| 25 import struct |
23 import time | 26 import time |
24 import urllib2 | 27 import urllib2 |
25 import warnings | 28 import warnings |
26 | 29 |
27 # Ignore deprecation warnings, they make our output more cluttered. | 30 # Ignore deprecation warnings, they make our output more cluttered. |
28 warnings.filterwarnings("ignore", category=DeprecationWarning) | 31 warnings.filterwarnings("ignore", category=DeprecationWarning) |
29 | 32 |
30 import pyftpdlib.ftpserver | 33 import pyftpdlib.ftpserver |
31 import tlslite | 34 import tlslite |
32 import tlslite.api | 35 import tlslite.api |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 if not self._ShouldHandleRequest("/echoall"): | 496 if not self._ShouldHandleRequest("/echoall"): |
494 return False | 497 return False |
495 | 498 |
496 self.send_response(200) | 499 self.send_response(200) |
497 self.send_header('Content-type', 'text/html') | 500 self.send_header('Content-type', 'text/html') |
498 self.end_headers() | 501 self.end_headers() |
499 self.wfile.write('<html><head><style>' | 502 self.wfile.write('<html><head><style>' |
500 'pre { border: 1px solid black; margin: 5px; padding: 5px }' | 503 'pre { border: 1px solid black; margin: 5px; padding: 5px }' |
501 '</style></head><body>' | 504 '</style></head><body>' |
502 '<div style="float: right">' | 505 '<div style="float: right">' |
503 '<a href="http://localhost:8888/echo">back to referring page</a></div>' | 506 '<a href="/echo">back to referring page</a></div>' |
504 '<h1>Request Body:</h1><pre>') | 507 '<h1>Request Body:</h1><pre>') |
505 | 508 |
506 if self.command == 'POST' or self.command == 'PUT': | 509 if self.command == 'POST' or self.command == 'PUT': |
507 length = int(self.headers.getheader('content-length')) | 510 length = int(self.headers.getheader('content-length')) |
508 qs = self.rfile.read(length) | 511 qs = self.rfile.read(length) |
509 params = cgi.parse_qs(qs, keep_blank_values=1) | 512 params = cgi.parse_qs(qs, keep_blank_values=1) |
510 | 513 |
511 for param in params: | 514 for param in params: |
512 self.wfile.write('%s=%s\n' % (param, params[param][0])) | 515 self.wfile.write('%s=%s\n' % (param, params[param][0])) |
513 | 516 |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 ' exiting...' | 1171 ' exiting...' |
1169 return | 1172 return |
1170 for ca_cert in options.ssl_client_ca: | 1173 for ca_cert in options.ssl_client_ca: |
1171 if not os.path.isfile(ca_cert): | 1174 if not os.path.isfile(ca_cert): |
1172 print 'specified trusted client CA file not found: ' + ca_cert + \ | 1175 print 'specified trusted client CA file not found: ' + ca_cert + \ |
1173 ' exiting...' | 1176 ' exiting...' |
1174 return | 1177 return |
1175 server = HTTPSServer(('127.0.0.1', port), TestPageHandler, options.cert, | 1178 server = HTTPSServer(('127.0.0.1', port), TestPageHandler, options.cert, |
1176 options.ssl_client_auth, options.ssl_client_ca, | 1179 options.ssl_client_auth, options.ssl_client_ca, |
1177 options.ssl_bulk_cipher) | 1180 options.ssl_bulk_cipher) |
1178 print 'HTTPS server started on port %d...' % port | 1181 print 'HTTPS server started on port %d...' % server.server_port |
1179 else: | 1182 else: |
1180 server = StoppableHTTPServer(('127.0.0.1', port), TestPageHandler) | 1183 server = StoppableHTTPServer(('127.0.0.1', port), TestPageHandler) |
1181 print 'HTTP server started on port %d...' % port | 1184 print 'HTTP server started on port %d...' % server.server_port |
1182 | 1185 |
1183 server.data_dir = MakeDataDir() | 1186 server.data_dir = MakeDataDir() |
1184 server.file_root_url = options.file_root_url | 1187 server.file_root_url = options.file_root_url |
1185 server._sync_handler = None | 1188 server._sync_handler = None |
1186 | 1189 listen_port = server.server_port |
1187 # means FTP Server | 1190 # means FTP Server |
1188 else: | 1191 else: |
1189 my_data_dir = MakeDataDir() | 1192 my_data_dir = MakeDataDir() |
1190 | 1193 |
1191 # Instantiate a dummy authorizer for managing 'virtual' users | 1194 # Instantiate a dummy authorizer for managing 'virtual' users |
1192 authorizer = pyftpdlib.ftpserver.DummyAuthorizer() | 1195 authorizer = pyftpdlib.ftpserver.DummyAuthorizer() |
1193 | 1196 |
1194 # Define a new user having full r/w permissions and a read-only | 1197 # Define a new user having full r/w permissions and a read-only |
1195 # anonymous user | 1198 # anonymous user |
1196 authorizer.add_user('chrome', 'chrome', my_data_dir, perm='elradfmw') | 1199 authorizer.add_user('chrome', 'chrome', my_data_dir, perm='elradfmw') |
1197 | 1200 |
1198 authorizer.add_anonymous(my_data_dir) | 1201 authorizer.add_anonymous(my_data_dir) |
1199 | 1202 |
1200 # Instantiate FTP handler class | 1203 # Instantiate FTP handler class |
1201 ftp_handler = pyftpdlib.ftpserver.FTPHandler | 1204 ftp_handler = pyftpdlib.ftpserver.FTPHandler |
1202 ftp_handler.authorizer = authorizer | 1205 ftp_handler.authorizer = authorizer |
1203 | 1206 |
1204 # Define a customized banner (string returned when client connects) | 1207 # Define a customized banner (string returned when client connects) |
1205 ftp_handler.banner = ("pyftpdlib %s based ftpd ready." % | 1208 ftp_handler.banner = ("pyftpdlib %s based ftpd ready." % |
1206 pyftpdlib.ftpserver.__ver__) | 1209 pyftpdlib.ftpserver.__ver__) |
1207 | 1210 |
1208 # Instantiate FTP server class and listen to 127.0.0.1:port | 1211 # Instantiate FTP server class and listen to 127.0.0.1:port |
1209 address = ('127.0.0.1', port) | 1212 address = ('127.0.0.1', port) |
1210 server = pyftpdlib.ftpserver.FTPServer(address, ftp_handler) | 1213 server = pyftpdlib.ftpserver.FTPServer(address, ftp_handler) |
1211 print 'FTP server started on port %d...' % port | 1214 listen_port = server.socket.getsockname()[1] |
| 1215 print 'FTP server started on port %d...' % listen_port |
1212 | 1216 |
1213 # Notify the parent that we've started. (BaseServer subclasses | 1217 # Notify the parent that we've started. (BaseServer subclasses |
1214 # bind their sockets on construction.) | 1218 # bind their sockets on construction.) |
1215 if options.startup_pipe is not None: | 1219 if options.startup_pipe is not None: |
1216 if sys.platform == 'win32': | 1220 if sys.platform == 'win32': |
1217 fd = msvcrt.open_osfhandle(options.startup_pipe, 0) | 1221 fd = msvcrt.open_osfhandle(options.startup_pipe, 0) |
1218 else: | 1222 else: |
1219 fd = options.startup_pipe | 1223 fd = options.startup_pipe |
1220 startup_pipe = os.fdopen(fd, "w") | 1224 startup_pipe = os.fdopen(fd, "w") |
1221 startup_pipe.write("READY") | 1225 # Write the listening port as a 2 byte value. This is _not_ using |
| 1226 # network byte ordering since the other end of the pipe is on the same |
| 1227 # machine. |
| 1228 startup_pipe.write(struct.pack('@H', listen_port)) |
1222 startup_pipe.close() | 1229 startup_pipe.close() |
1223 | 1230 |
1224 try: | 1231 try: |
1225 server.serve_forever() | 1232 server.serve_forever() |
1226 except KeyboardInterrupt: | 1233 except KeyboardInterrupt: |
1227 print 'shutting down server' | 1234 print 'shutting down server' |
1228 server.stop = True | 1235 server.stop = True |
1229 | 1236 |
1230 if __name__ == '__main__': | 1237 if __name__ == '__main__': |
1231 option_parser = optparse.OptionParser() | 1238 option_parser = optparse.OptionParser() |
1232 option_parser.add_option("-f", '--ftp', action='store_const', | 1239 option_parser.add_option("-f", '--ftp', action='store_const', |
1233 const=SERVER_FTP, default=SERVER_HTTP, | 1240 const=SERVER_FTP, default=SERVER_HTTP, |
1234 dest='server_type', | 1241 dest='server_type', |
1235 help='FTP or HTTP server: default is HTTP.') | 1242 help='FTP or HTTP server: default is HTTP.') |
1236 option_parser.add_option('', '--port', default='8888', type='int', | 1243 option_parser.add_option('', '--port', default='0', type='int', |
1237 help='Port used by the server.') | 1244 help='Port used by the server. If unspecified, the ' |
| 1245 'server will listen on an ephemeral port.') |
1238 option_parser.add_option('', '--data-dir', dest='data_dir', | 1246 option_parser.add_option('', '--data-dir', dest='data_dir', |
1239 help='Directory from which to read the files.') | 1247 help='Directory from which to read the files.') |
1240 option_parser.add_option('', '--https', dest='cert', | 1248 option_parser.add_option('', '--https', dest='cert', |
1241 help='Specify that https should be used, specify ' | 1249 help='Specify that https should be used, specify ' |
1242 'the path to the cert containing the private key ' | 1250 'the path to the cert containing the private key ' |
1243 'the server should use.') | 1251 'the server should use.') |
1244 option_parser.add_option('', '--ssl-client-auth', action='store_true', | 1252 option_parser.add_option('', '--ssl-client-auth', action='store_true', |
1245 help='Require SSL client auth on every connection.') | 1253 help='Require SSL client auth on every connection.') |
1246 option_parser.add_option('', '--ssl-client-ca', action='append', default=[], | 1254 option_parser.add_option('', '--ssl-client-ca', action='append', default=[], |
1247 help='Specify that the client certificate request ' | 1255 help='Specify that the client certificate request ' |
(...skipping 10 matching lines...) Expand all Loading... |
1258 'option may appear multiple times, indicating ' | 1266 'option may appear multiple times, indicating ' |
1259 'multiple algorithms should be enabled.'); | 1267 'multiple algorithms should be enabled.'); |
1260 option_parser.add_option('', '--file-root-url', default='/files/', | 1268 option_parser.add_option('', '--file-root-url', default='/files/', |
1261 help='Specify a root URL for files served.') | 1269 help='Specify a root URL for files served.') |
1262 option_parser.add_option('', '--startup-pipe', type='int', | 1270 option_parser.add_option('', '--startup-pipe', type='int', |
1263 dest='startup_pipe', | 1271 dest='startup_pipe', |
1264 help='File handle of pipe to parent process') | 1272 help='File handle of pipe to parent process') |
1265 options, args = option_parser.parse_args() | 1273 options, args = option_parser.parse_args() |
1266 | 1274 |
1267 sys.exit(main(options, args)) | 1275 sys.exit(main(options, args)) |
OLD | NEW |