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

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

Issue 5104004: Spin up XMPP server for testservers of type sync. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments Created 10 years, 1 month 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 | « no previous file | net/tools/testserver/xmppserver.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/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 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 base64 17 import base64
17 import BaseHTTPServer 18 import BaseHTTPServer
18 import cgi 19 import cgi
20 import errno
19 import optparse 21 import optparse
20 import os 22 import os
21 import re 23 import re
22 import shutil 24 import select
23 import SocketServer 25 import SocketServer
26 import socket
24 import sys 27 import sys
25 import struct 28 import struct
26 import time 29 import time
27 import urlparse 30 import urlparse
28 import warnings 31 import warnings
29 32
30 # If we use simplejson always, we get some warnings when we run under 33 # If we use simplejson always, we get some warnings when we run under
31 # 2.6. 34 # 2.6.
32 if sys.version_info < (2, 6): 35 if sys.version_info < (2, 6):
33 import simplejson as json 36 import simplejson as json
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 return False 118 return False
116 119
117 120
118 class SyncHTTPServer(StoppableHTTPServer): 121 class SyncHTTPServer(StoppableHTTPServer):
119 """An HTTP server that handles sync commands.""" 122 """An HTTP server that handles sync commands."""
120 123
121 def __init__(self, server_address, request_handler_class): 124 def __init__(self, server_address, request_handler_class):
122 # We import here to avoid pulling in chromiumsync's dependencies 125 # We import here to avoid pulling in chromiumsync's dependencies
123 # unless strictly necessary. 126 # unless strictly necessary.
124 import chromiumsync 127 import chromiumsync
128 import xmppserver
129 StoppableHTTPServer.__init__(self, server_address, request_handler_class)
125 self._sync_handler = chromiumsync.TestServer() 130 self._sync_handler = chromiumsync.TestServer()
126 StoppableHTTPServer.__init__(self, server_address, request_handler_class) 131 self._xmpp_socket_map = {}
132 self._xmpp_server = xmppserver.XmppServer(
133 self._xmpp_socket_map, ('localhost', 0))
134 self.xmpp_port = self._xmpp_server.getsockname()[1]
127 135
128 def HandleCommand(self, query, raw_request): 136 def HandleCommand(self, query, raw_request):
129 return self._sync_handler.HandleCommand(query, raw_request) 137 return self._sync_handler.HandleCommand(query, raw_request)
130 138
139 def HandleRequestNoBlock(self):
140 """Handles a single request.
141
142 Copied from SocketServer._handle_request_noblock().
143 """
144 try:
145 request, client_address = self.get_request()
146 except socket.error:
147 return
148 if self.verify_request(request, client_address):
149 try:
150 self.process_request(request, client_address)
151 except:
152 self.handle_error(request, client_address)
153 self.close_request(request)
154
155 def serve_forever(self):
156 """This is a merge of asyncore.loop() and SocketServer.serve_forever().
157 """
158
159 def RunDispatcherHandler(dispatcher, handler):
160 """Handles a single event for an asyncore.dispatcher.
161
162 Adapted from asyncore.read() et al.
163 """
164 try:
165 handler(dispatcher)
166 except (asyncore.ExitNow, KeyboardInterrupt, SystemExit):
167 raise
168 except:
169 dispatcher.handle_error()
170
171 while True:
172 r = [ self.fileno() ]
cbentzel 2010/11/19 15:39:29 Nit: are r,w,e too short? [maybe at least r,w,x si
akalin 2010/11/19 18:06:17 Done.
173 w = []
174 e = []
175
176 for fd, obj in self._xmpp_socket_map.items():
cbentzel 2010/11/19 15:39:29 xmpp_connection instead of obj?
akalin 2010/11/19 18:06:17 Done.
177 is_r = obj.readable()
178 is_w = obj.writable()
179 if is_r:
180 r.append(fd)
181 if is_w:
182 w.append(fd)
183 if is_r or is_w:
184 e.append(fd)
185
186 select_timeout = 0.5
187 try:
188 r, w, e = select.select(r, w, e, select_timeout)
cbentzel 2010/11/19 15:39:29 Why do you need a timeout here? The tests that spa
akalin 2010/11/19 18:06:17 Done.
189 except select.error, err:
190 if err.args[0] != errno.EINTR:
191 raise
192 else:
193 continue
194
195 for fd in r:
196 if fd == self.fileno():
197 self.HandleRequestNoBlock()
198 continue
199 obj = self._xmpp_socket_map.get(fd)
200 RunDispatcherHandler(obj, asyncore.dispatcher.handle_read_event)
201
202 for fd in w:
203 obj = self._xmpp_socket_map.get(fd)
204 RunDispatcherHandler(obj, asyncore.dispatcher.handle_write_event)
205
206 for fd in e:
207 obj = self._xmpp_socket_map.get(fd)
208 RunDispatcherHandler(obj, asyncore.dispatcher.handle_expt_event)
209
131 210
132 class BasePageHandler(BaseHTTPServer.BaseHTTPRequestHandler): 211 class BasePageHandler(BaseHTTPServer.BaseHTTPRequestHandler):
133 212
134 def __init__(self, request, client_address, socket_server, 213 def __init__(self, request, client_address, socket_server,
135 connect_handlers, get_handlers, post_handlers, put_handlers): 214 connect_handlers, get_handlers, post_handlers, put_handlers):
136 self._connect_handlers = connect_handlers 215 self._connect_handlers = connect_handlers
137 self._get_handlers = get_handlers 216 self._get_handlers = get_handlers
138 self._post_handlers = post_handlers 217 self._post_handlers = post_handlers
139 self._put_handlers = put_handlers 218 self._put_handlers = put_handlers
140 BaseHTTPServer.BaseHTTPRequestHandler.__init__( 219 BaseHTTPServer.BaseHTTPRequestHandler.__init__(
(...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 self.__fd1.flush() 1342 self.__fd1.flush()
1264 self.__fd2.flush() 1343 self.__fd2.flush()
1265 1344
1266 def main(options, args): 1345 def main(options, args):
1267 logfile = open('testserver.log', 'w') 1346 logfile = open('testserver.log', 'w')
1268 sys.stdout = FileMultiplexer(sys.stdout, logfile) 1347 sys.stdout = FileMultiplexer(sys.stdout, logfile)
1269 sys.stderr = FileMultiplexer(sys.stderr, logfile) 1348 sys.stderr = FileMultiplexer(sys.stderr, logfile)
1270 1349
1271 port = options.port 1350 port = options.port
1272 1351
1352 server_data = {}
cbentzel 2010/11/19 15:39:29 Maybe server_ports instead of server_data?
akalin 2010/11/19 18:06:17 Hmm, it's a JSON grab-bag, so I think we shouldn't
1353
1273 if options.server_type == SERVER_HTTP: 1354 if options.server_type == SERVER_HTTP:
1274 if options.cert: 1355 if options.cert:
1275 # let's make sure the cert file exists. 1356 # let's make sure the cert file exists.
1276 if not os.path.isfile(options.cert): 1357 if not os.path.isfile(options.cert):
1277 print 'specified server cert file not found: ' + options.cert + \ 1358 print 'specified server cert file not found: ' + options.cert + \
1278 ' exiting...' 1359 ' exiting...'
1279 return 1360 return
1280 for ca_cert in options.ssl_client_ca: 1361 for ca_cert in options.ssl_client_ca:
1281 if not os.path.isfile(ca_cert): 1362 if not os.path.isfile(ca_cert):
1282 print 'specified trusted client CA file not found: ' + ca_cert + \ 1363 print 'specified trusted client CA file not found: ' + ca_cert + \
1283 ' exiting...' 1364 ' exiting...'
1284 return 1365 return
1285 server = HTTPSServer(('127.0.0.1', port), TestPageHandler, options.cert, 1366 server = HTTPSServer(('127.0.0.1', port), TestPageHandler, options.cert,
1286 options.ssl_client_auth, options.ssl_client_ca, 1367 options.ssl_client_auth, options.ssl_client_ca,
1287 options.ssl_bulk_cipher) 1368 options.ssl_bulk_cipher)
1288 print 'HTTPS server started on port %d...' % server.server_port 1369 print 'HTTPS server started on port %d...' % server.server_port
1289 else: 1370 else:
1290 server = StoppableHTTPServer(('127.0.0.1', port), TestPageHandler) 1371 server = StoppableHTTPServer(('127.0.0.1', port), TestPageHandler)
1291 print 'HTTP server started on port %d...' % server.server_port 1372 print 'HTTP server started on port %d...' % server.server_port
1292 1373
1293 server.data_dir = MakeDataDir() 1374 server.data_dir = MakeDataDir()
1294 server.file_root_url = options.file_root_url 1375 server.file_root_url = options.file_root_url
1295 listen_port = server.server_port 1376 server_data['port'] = server.server_port
1296 server._device_management_handler = None 1377 server._device_management_handler = None
1297 elif options.server_type == SERVER_SYNC: 1378 elif options.server_type == SERVER_SYNC:
1298 server = SyncHTTPServer(('127.0.0.1', port), SyncPageHandler) 1379 server = SyncHTTPServer(('127.0.0.1', port), SyncPageHandler)
1299 print 'Sync HTTP server started on port %d...' % server.server_port 1380 print 'Sync HTTP server started on port %d...' % server.server_port
1300 listen_port = server.server_port 1381 print 'Sync XMPP server started on port %d...' % server.xmpp_port
1382 server_data['port'] = server.server_port
1383 server_data['xmpp_port'] = server.xmpp_port
1301 # means FTP Server 1384 # means FTP Server
1302 else: 1385 else:
1303 my_data_dir = MakeDataDir() 1386 my_data_dir = MakeDataDir()
1304 1387
1305 # Instantiate a dummy authorizer for managing 'virtual' users 1388 # Instantiate a dummy authorizer for managing 'virtual' users
1306 authorizer = pyftpdlib.ftpserver.DummyAuthorizer() 1389 authorizer = pyftpdlib.ftpserver.DummyAuthorizer()
1307 1390
1308 # Define a new user having full r/w permissions and a read-only 1391 # Define a new user having full r/w permissions and a read-only
1309 # anonymous user 1392 # anonymous user
1310 authorizer.add_user('chrome', 'chrome', my_data_dir, perm='elradfmw') 1393 authorizer.add_user('chrome', 'chrome', my_data_dir, perm='elradfmw')
1311 1394
1312 authorizer.add_anonymous(my_data_dir) 1395 authorizer.add_anonymous(my_data_dir)
1313 1396
1314 # Instantiate FTP handler class 1397 # Instantiate FTP handler class
1315 ftp_handler = pyftpdlib.ftpserver.FTPHandler 1398 ftp_handler = pyftpdlib.ftpserver.FTPHandler
1316 ftp_handler.authorizer = authorizer 1399 ftp_handler.authorizer = authorizer
1317 1400
1318 # Define a customized banner (string returned when client connects) 1401 # Define a customized banner (string returned when client connects)
1319 ftp_handler.banner = ("pyftpdlib %s based ftpd ready." % 1402 ftp_handler.banner = ("pyftpdlib %s based ftpd ready." %
1320 pyftpdlib.ftpserver.__ver__) 1403 pyftpdlib.ftpserver.__ver__)
1321 1404
1322 # Instantiate FTP server class and listen to 127.0.0.1:port 1405 # Instantiate FTP server class and listen to 127.0.0.1:port
1323 address = ('127.0.0.1', port) 1406 address = ('127.0.0.1', port)
1324 server = pyftpdlib.ftpserver.FTPServer(address, ftp_handler) 1407 server = pyftpdlib.ftpserver.FTPServer(address, ftp_handler)
1325 listen_port = server.socket.getsockname()[1] 1408 server_data['port'] = server.socket.getsockname()[1]
1326 print 'FTP server started on port %d...' % listen_port 1409 print 'FTP server started on port %d...' % server_data['port']
1327 1410
1328 # Notify the parent that we've started. (BaseServer subclasses 1411 # Notify the parent that we've started. (BaseServer subclasses
1329 # bind their sockets on construction.) 1412 # bind their sockets on construction.)
1330 if options.startup_pipe is not None: 1413 if options.startup_pipe is not None:
1331 server_data = {
1332 'port': listen_port
1333 }
1334 server_data_json = json.dumps(server_data) 1414 server_data_json = json.dumps(server_data)
1335 debug('sending server_data: %s' % server_data_json) 1415 debug('sending server_data: %s' % server_data_json)
1336 server_data_len = len(server_data_json) 1416 server_data_len = len(server_data_json)
1337 if sys.platform == 'win32': 1417 if sys.platform == 'win32':
1338 fd = msvcrt.open_osfhandle(options.startup_pipe, 0) 1418 fd = msvcrt.open_osfhandle(options.startup_pipe, 0)
1339 else: 1419 else:
1340 fd = options.startup_pipe 1420 fd = options.startup_pipe
1341 startup_pipe = os.fdopen(fd, "w") 1421 startup_pipe = os.fdopen(fd, "w")
1342 # First write the data length as an unsigned 4-byte value. This 1422 # First write the data length as an unsigned 4-byte value. This
1343 # is _not_ using network byte ordering since the other end of the 1423 # is _not_ using network byte ordering since the other end of the
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 'option may appear multiple times, indicating ' 1468 'option may appear multiple times, indicating '
1389 'multiple algorithms should be enabled.'); 1469 'multiple algorithms should be enabled.');
1390 option_parser.add_option('', '--file-root-url', default='/files/', 1470 option_parser.add_option('', '--file-root-url', default='/files/',
1391 help='Specify a root URL for files served.') 1471 help='Specify a root URL for files served.')
1392 option_parser.add_option('', '--startup-pipe', type='int', 1472 option_parser.add_option('', '--startup-pipe', type='int',
1393 dest='startup_pipe', 1473 dest='startup_pipe',
1394 help='File handle of pipe to parent process') 1474 help='File handle of pipe to parent process')
1395 options, args = option_parser.parse_args() 1475 options, args = option_parser.parse_args()
1396 1476
1397 sys.exit(main(options, args)) 1477 sys.exit(main(options, args))
OLDNEW
« no previous file with comments | « no previous file | net/tools/testserver/xmppserver.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698