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 |
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 | 21 import hashlib |
22 import httplib | 22 import httplib |
23 import json | 23 import json |
| 24 import logging |
24 import minica | 25 import minica |
25 import optparse | 26 import optparse |
26 import os | 27 import os |
27 import random | 28 import random |
28 import re | 29 import re |
29 import select | 30 import select |
30 import socket | 31 import socket |
31 import SocketServer | 32 import SocketServer |
32 import struct | 33 import struct |
33 import sys | 34 import sys |
34 import threading | 35 import threading |
35 import time | 36 import time |
36 import urllib | 37 import urllib |
37 import urlparse | 38 import urlparse |
38 import warnings | 39 import warnings |
39 import zlib | 40 import zlib |
40 | 41 |
41 # Ignore deprecation warnings, they make our output more cluttered. | 42 # Ignore deprecation warnings, they make our output more cluttered. |
42 warnings.filterwarnings("ignore", category=DeprecationWarning) | 43 warnings.filterwarnings("ignore", category=DeprecationWarning) |
43 | 44 |
44 import echo_message | 45 import echo_message |
| 46 from mod_pywebsocket.standalone import WebSocketServer |
45 import pyftpdlib.ftpserver | 47 import pyftpdlib.ftpserver |
46 import tlslite | 48 import tlslite |
47 import tlslite.api | 49 import tlslite.api |
48 | 50 |
49 if sys.platform == 'win32': | 51 if sys.platform == 'win32': |
50 import msvcrt | 52 import msvcrt |
51 | 53 |
52 SERVER_HTTP = 0 | 54 SERVER_HTTP = 0 |
53 SERVER_FTP = 1 | 55 SERVER_FTP = 1 |
54 SERVER_SYNC = 2 | 56 SERVER_SYNC = 2 |
55 SERVER_TCP_ECHO = 3 | 57 SERVER_TCP_ECHO = 3 |
56 SERVER_UDP_ECHO = 4 | 58 SERVER_UDP_ECHO = 4 |
57 SERVER_BASIC_AUTH_PROXY = 5 | 59 SERVER_BASIC_AUTH_PROXY = 5 |
| 60 SERVER_WEBSOCKET = 6 |
| 61 |
| 62 # Default request queue size for WebSocketServer. |
| 63 _DEFAULT_REQUEST_QUEUE_SIZE = 128 |
58 | 64 |
59 # Using debug() seems to cause hangs on XP: see http://crbug.com/64515 . | 65 # Using debug() seems to cause hangs on XP: see http://crbug.com/64515 . |
60 debug_output = sys.stderr | 66 debug_output = sys.stderr |
61 def debug(str): | 67 def debug(str): |
62 debug_output.write(str + "\n") | 68 debug_output.write(str + "\n") |
63 debug_output.flush() | 69 debug_output.flush() |
64 | 70 |
| 71 class WebSocketOptions: |
| 72 """Holds options for WebSocketServer.""" |
| 73 |
| 74 def __init__(self, host, port, data_dir): |
| 75 self.request_queue_size = _DEFAULT_REQUEST_QUEUE_SIZE |
| 76 self.server_host = host |
| 77 self.port = port |
| 78 self.websock_handlers = data_dir |
| 79 self.scan_dir = None |
| 80 self.allow_handlers_outside_root_dir = False |
| 81 self.websock_handlers_map_file = None |
| 82 self.cgi_directories = [] |
| 83 self.is_executable_method = None |
| 84 self.allow_draft75 = False |
| 85 self.strict = True |
| 86 |
| 87 # TODO(toyoshim): Support SSL and authenticates (http://crbug.com/137639) |
| 88 self.use_tls = False |
| 89 self.private_key = None |
| 90 self.certificate = None |
| 91 self.tls_client_ca = None |
| 92 self.use_basic_auth = False |
| 93 |
65 class RecordingSSLSessionCache(object): | 94 class RecordingSSLSessionCache(object): |
66 """RecordingSSLSessionCache acts as a TLS session cache and maintains a log of | 95 """RecordingSSLSessionCache acts as a TLS session cache and maintains a log of |
67 lookups and inserts in order to test session cache behaviours.""" | 96 lookups and inserts in order to test session cache behaviours.""" |
68 | 97 |
69 def __init__(self): | 98 def __init__(self): |
70 self.log = [] | 99 self.log = [] |
71 | 100 |
72 def __getitem__(self, sessionID): | 101 def __getitem__(self, sessionID): |
73 self.log.append(('lookup', sessionID)) | 102 self.log.append(('lookup', sessionID)) |
74 raise KeyError() | 103 raise KeyError() |
(...skipping 2134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2209 server = HTTPServer((host, port), TestPageHandler) | 2238 server = HTTPServer((host, port), TestPageHandler) |
2210 print 'HTTP server started on %s:%d...' % (host, server.server_port) | 2239 print 'HTTP server started on %s:%d...' % (host, server.server_port) |
2211 | 2240 |
2212 server.data_dir = MakeDataDir() | 2241 server.data_dir = MakeDataDir() |
2213 server.file_root_url = options.file_root_url | 2242 server.file_root_url = options.file_root_url |
2214 server_data['port'] = server.server_port | 2243 server_data['port'] = server.server_port |
2215 server._device_management_handler = None | 2244 server._device_management_handler = None |
2216 server.policy_keys = options.policy_keys | 2245 server.policy_keys = options.policy_keys |
2217 server.policy_user = options.policy_user | 2246 server.policy_user = options.policy_user |
2218 server.gdata_auth_token = options.auth_token | 2247 server.gdata_auth_token = options.auth_token |
| 2248 elif options.server_type == SERVER_WEBSOCKET: |
| 2249 # Launch pywebsocket via WebSocketServer. |
| 2250 logger = logging.getLogger() |
| 2251 logger.addHandler(logging.StreamHandler()) |
| 2252 # TODO(toyoshim): Remove following os.chdir. Currently this operation |
| 2253 # is required to work correctly. It should be fixed from pywebsocket side. |
| 2254 os.chdir(MakeDataDir()) |
| 2255 server = WebSocketServer(WebSocketOptions(host, port, MakeDataDir())) |
| 2256 print 'WebSocket server started on %s:%d...' % (host, server.server_port) |
| 2257 server_data['port'] = server.server_port |
2219 elif options.server_type == SERVER_SYNC: | 2258 elif options.server_type == SERVER_SYNC: |
2220 xmpp_port = options.xmpp_port | 2259 xmpp_port = options.xmpp_port |
2221 server = SyncHTTPServer((host, port), xmpp_port, SyncPageHandler) | 2260 server = SyncHTTPServer((host, port), xmpp_port, SyncPageHandler) |
2222 print 'Sync HTTP server started on port %d...' % server.server_port | 2261 print 'Sync HTTP server started on port %d...' % server.server_port |
2223 print 'Sync XMPP server started on port %d...' % server.xmpp_port | 2262 print 'Sync XMPP server started on port %d...' % server.xmpp_port |
2224 server_data['port'] = server.server_port | 2263 server_data['port'] = server.server_port |
2225 server_data['xmpp_port'] = server.xmpp_port | 2264 server_data['xmpp_port'] = server.xmpp_port |
2226 elif options.server_type == SERVER_TCP_ECHO: | 2265 elif options.server_type == SERVER_TCP_ECHO: |
2227 # Used for generating the key (randomly) that encodes the "echo request" | 2266 # Used for generating the key (randomly) that encodes the "echo request" |
2228 # message. | 2267 # message. |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2313 help='start up a tcp echo server.') | 2352 help='start up a tcp echo server.') |
2314 option_parser.add_option('', '--udp-echo', action='store_const', | 2353 option_parser.add_option('', '--udp-echo', action='store_const', |
2315 const=SERVER_UDP_ECHO, default=SERVER_HTTP, | 2354 const=SERVER_UDP_ECHO, default=SERVER_HTTP, |
2316 dest='server_type', | 2355 dest='server_type', |
2317 help='start up a udp echo server.') | 2356 help='start up a udp echo server.') |
2318 option_parser.add_option('', '--basic-auth-proxy', action='store_const', | 2357 option_parser.add_option('', '--basic-auth-proxy', action='store_const', |
2319 const=SERVER_BASIC_AUTH_PROXY, default=SERVER_HTTP, | 2358 const=SERVER_BASIC_AUTH_PROXY, default=SERVER_HTTP, |
2320 dest='server_type', | 2359 dest='server_type', |
2321 help='start up a proxy server which requires basic ' | 2360 help='start up a proxy server which requires basic ' |
2322 'authentication.') | 2361 'authentication.') |
| 2362 option_parser.add_option('', '--websocket', action='store_const', |
| 2363 const=SERVER_WEBSOCKET, default=SERVER_HTTP, |
| 2364 dest='server_type', |
| 2365 help='start up a WebSocket server.') |
2323 option_parser.add_option('', '--log-to-console', action='store_const', | 2366 option_parser.add_option('', '--log-to-console', action='store_const', |
2324 const=True, default=False, | 2367 const=True, default=False, |
2325 dest='log_to_console', | 2368 dest='log_to_console', |
2326 help='Enables or disables sys.stdout logging to ' | 2369 help='Enables or disables sys.stdout logging to ' |
2327 'the console.') | 2370 'the console.') |
2328 option_parser.add_option('', '--port', default='0', type='int', | 2371 option_parser.add_option('', '--port', default='0', type='int', |
2329 help='Port used by the server. If unspecified, the ' | 2372 help='Port used by the server. If unspecified, the ' |
2330 'server will listen on an ephemeral port.') | 2373 'server will listen on an ephemeral port.') |
2331 option_parser.add_option('', '--xmpp-port', default='0', type='int', | 2374 option_parser.add_option('', '--xmpp-port', default='0', type='int', |
2332 help='Port used by the XMPP server. If unspecified, ' | 2375 help='Port used by the XMPP server. If unspecified, ' |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2395 dest='host', | 2438 dest='host', |
2396 help='Hostname or IP upon which the server will ' | 2439 help='Hostname or IP upon which the server will ' |
2397 'listen. Client connections will also only be ' | 2440 'listen. Client connections will also only be ' |
2398 'allowed from this address.') | 2441 'allowed from this address.') |
2399 option_parser.add_option('', '--auth-token', dest='auth_token', | 2442 option_parser.add_option('', '--auth-token', dest='auth_token', |
2400 help='Specify the auth token which should be used' | 2443 help='Specify the auth token which should be used' |
2401 'in the authorization header for GData.') | 2444 'in the authorization header for GData.') |
2402 options, args = option_parser.parse_args() | 2445 options, args = option_parser.parse_args() |
2403 | 2446 |
2404 sys.exit(main(options, args)) | 2447 sys.exit(main(options, args)) |
OLD | NEW |