Chromium Code Reviews| Index: net/tools/testserver/testserver.py |
| diff --git a/net/tools/testserver/testserver.py b/net/tools/testserver/testserver.py |
| index b69eb2f141efd0f9ce499ab7f70d8880f6bc0b8a..d87d67366979c79c60bad1ebdb725f3dff313568 100755 |
| --- a/net/tools/testserver/testserver.py |
| +++ b/net/tools/testserver/testserver.py |
| @@ -13,14 +13,17 @@ It can use https if you specify the flag --https=CERT where CERT is the path |
| to a pem file containing the certificate and private key that should be used. |
| """ |
| +import asyncore |
| import base64 |
| import BaseHTTPServer |
| import cgi |
| +import errno |
| import optparse |
| import os |
| import re |
| -import shutil |
| +import select |
| import SocketServer |
| +import socket |
| import sys |
| import struct |
| import time |
| @@ -122,12 +125,88 @@ class SyncHTTPServer(StoppableHTTPServer): |
| # We import here to avoid pulling in chromiumsync's dependencies |
| # unless strictly necessary. |
| import chromiumsync |
| - self._sync_handler = chromiumsync.TestServer() |
| + import xmppserver |
| StoppableHTTPServer.__init__(self, server_address, request_handler_class) |
| + self._sync_handler = chromiumsync.TestServer() |
| + self._xmpp_socket_map = {} |
| + self._xmpp_server = xmppserver.XmppServer( |
| + self._xmpp_socket_map, ('localhost', 0)) |
| + self.xmpp_port = self._xmpp_server.getsockname()[1] |
| def HandleCommand(self, query, raw_request): |
| return self._sync_handler.HandleCommand(query, raw_request) |
| + def HandleRequestNoBlock(self): |
| + """Handles a single request. |
| + |
| + Copied from SocketServer._handle_request_noblock(). |
| + """ |
| + try: |
| + request, client_address = self.get_request() |
| + except socket.error: |
| + return |
| + if self.verify_request(request, client_address): |
| + try: |
| + self.process_request(request, client_address) |
| + except: |
| + self.handle_error(request, client_address) |
| + self.close_request(request) |
| + |
| + def serve_forever(self): |
| + """This is a merge of asyncore.loop() and SocketServer.serve_forever(). |
| + """ |
| + |
| + def RunDispatcherHandler(dispatcher, handler): |
| + """Handles a single event for an asyncore.dispatcher. |
| + |
| + Adapted from asyncore.read() et al. |
| + """ |
| + try: |
| + handler(dispatcher) |
| + except (asyncore.ExitNow, KeyboardInterrupt, SystemExit): |
| + raise |
| + except: |
| + dispatcher.handle_error() |
| + |
| + while True: |
| + 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.
|
| + w = [] |
| + e = [] |
| + |
| + 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.
|
| + is_r = obj.readable() |
| + is_w = obj.writable() |
| + if is_r: |
| + r.append(fd) |
| + if is_w: |
| + w.append(fd) |
| + if is_r or is_w: |
| + e.append(fd) |
| + |
| + select_timeout = 0.5 |
| + try: |
| + 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.
|
| + except select.error, err: |
| + if err.args[0] != errno.EINTR: |
| + raise |
| + else: |
| + continue |
| + |
| + for fd in r: |
| + if fd == self.fileno(): |
| + self.HandleRequestNoBlock() |
| + continue |
| + obj = self._xmpp_socket_map.get(fd) |
| + RunDispatcherHandler(obj, asyncore.dispatcher.handle_read_event) |
| + |
| + for fd in w: |
| + obj = self._xmpp_socket_map.get(fd) |
| + RunDispatcherHandler(obj, asyncore.dispatcher.handle_write_event) |
| + |
| + for fd in e: |
| + obj = self._xmpp_socket_map.get(fd) |
| + RunDispatcherHandler(obj, asyncore.dispatcher.handle_expt_event) |
| + |
| class BasePageHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
| @@ -1270,6 +1349,8 @@ def main(options, args): |
| port = options.port |
| + 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
|
| + |
| if options.server_type == SERVER_HTTP: |
| if options.cert: |
| # let's make sure the cert file exists. |
| @@ -1292,12 +1373,14 @@ def main(options, args): |
| server.data_dir = MakeDataDir() |
| server.file_root_url = options.file_root_url |
| - listen_port = server.server_port |
| + server_data['port'] = server.server_port |
| server._device_management_handler = None |
| elif options.server_type == SERVER_SYNC: |
| server = SyncHTTPServer(('127.0.0.1', port), SyncPageHandler) |
| print 'Sync HTTP server started on port %d...' % server.server_port |
| - listen_port = server.server_port |
| + print 'Sync XMPP server started on port %d...' % server.xmpp_port |
| + server_data['port'] = server.server_port |
| + server_data['xmpp_port'] = server.xmpp_port |
| # means FTP Server |
| else: |
| my_data_dir = MakeDataDir() |
| @@ -1322,15 +1405,12 @@ def main(options, args): |
| # Instantiate FTP server class and listen to 127.0.0.1:port |
| address = ('127.0.0.1', port) |
| server = pyftpdlib.ftpserver.FTPServer(address, ftp_handler) |
| - listen_port = server.socket.getsockname()[1] |
| - print 'FTP server started on port %d...' % listen_port |
| + server_data['port'] = server.socket.getsockname()[1] |
| + print 'FTP server started on port %d...' % server_data['port'] |
| # Notify the parent that we've started. (BaseServer subclasses |
| # bind their sockets on construction.) |
| if options.startup_pipe is not None: |
| - server_data = { |
| - 'port': listen_port |
| - } |
| server_data_json = json.dumps(server_data) |
| debug('sending server_data: %s' % server_data_json) |
| server_data_len = len(server_data_json) |