Changeset 51406 in webkit
- Timestamp:
- Nov 25, 2009 10:16:09 PM (14 years ago)
- Location:
- trunk/WebKitTools
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKitTools/ChangeLog
r51405 r51406 1 2009-11-25 Yuzo Fujishima <yuzo@google.com> 2 3 Reviewed by Eric Seidel. 4 5 Update pywebsocket to 0.4.2 6 7 Update pywebsocket to 0.4.2 8 https://bugs.webkit.org/show_bug.cgi?id=31861 9 10 * pywebsocket/example/echo_client.py: 11 * pywebsocket/example/echo_wsh.py: 12 * pywebsocket/mod_pywebsocket/__init__.py: 13 * pywebsocket/mod_pywebsocket/dispatch.py: 14 * pywebsocket/mod_pywebsocket/msgutil.py: 15 * pywebsocket/mod_pywebsocket/standalone.py: 16 * pywebsocket/setup.py: 17 * pywebsocket/test/test_dispatch.py: 18 * pywebsocket/test/test_msgutil.py: 19 1 20 2009-11-25 Adam Barth <abarth@webkit.org> 2 21 -
trunk/WebKitTools/pywebsocket/example/echo_client.py
r49672 r51406 47 47 48 48 49 _TIMEOUT_SEC = 10 50 49 51 _DEFAULT_PORT = 80 50 52 _DEFAULT_SECURE_PORT = 443 … … 58 60 _CONNECTION_HEADER) 59 61 62 _GOODBYE_MESSAGE = 'Goodbye' 63 60 64 61 65 def _method_line(resource): … … 97 101 """ 98 102 self._socket = socket.socket() 103 self._socket.settimeout(self._options.socket_timeout) 99 104 try: 100 105 self._socket.connect((self._options.server_host, … … 103 108 self._socket = _TLSSocket(self._socket) 104 109 self._handshake() 105 for line in self._options.message.split(',') :110 for line in self._options.message.split(',') + [_GOODBYE_MESSAGE]: 106 111 frame = '\x00' + line.encode('utf-8') + '\xff' 107 112 self._socket.send(frame) … … 112 117 raise Exception('Incorrect echo: %r' % received) 113 118 if self._options.verbose: 114 print 'Recv: %s' % received[1:-1].decode('utf-8') 119 print 'Recv: %s' % received[1:-1].decode('utf-8', 120 'replace') 115 121 finally: 116 122 self._socket.close() … … 167 173 default='/echo', help='resource path') 168 174 parser.add_option('-m', '--message', dest='message', type='string', 169 help='comma-separated messages to send') 175 help=('comma-separated messages to send excluding "%s" ' 176 'that is always sent at the end' % 177 _GOODBYE_MESSAGE)) 170 178 parser.add_option('-q', '--quiet', dest='verbose', action='store_false', 171 179 default=True, help='suppress messages') 172 180 parser.add_option('-t', '--tls', dest='use_tls', action='store_true', 173 181 default=False, help='use TLS (wss://)') 182 parser.add_option('-k', '--socket_timeout', dest='socket_timeout', 183 type='int', default=_TIMEOUT_SEC, 184 help='Timeout(sec) for sockets') 185 174 186 (options, unused_args) = parser.parse_args() 175 187 -
trunk/WebKitTools/pywebsocket/example/echo_wsh.py
r49672 r51406 32 32 33 33 34 _GOODBYE_MESSAGE = 'Goodbye' 35 36 34 37 def web_socket_do_extra_handshake(request): 35 38 pass # Always accept. … … 40 43 line = msgutil.receive_message(request) 41 44 msgutil.send_message(request, line) 45 if line == _GOODBYE_MESSAGE: 46 return 42 47 43 48 -
trunk/WebKitTools/pywebsocket/mod_pywebsocket/__init__.py
r50102 r51406 97 97 using request. mod_pywebsocket.msgutil module provides utilities 98 98 for data transfer. 99 100 A Web Socket handler must be thread-safe if the server (Apache or 101 standalone.py) is configured to use threads. 99 102 """ 100 103 -
trunk/WebKitTools/pywebsocket/mod_pywebsocket/dispatch.py
r51099 r51406 63 63 64 64 path = path.replace('\\', os.path.sep) 65 path = os.path. abspath(path)65 path = os.path.realpath(path) 66 66 path = path.replace('\\', '/') 67 67 return path … … 137 137 if scan_dir is None: 138 138 scan_dir = root_dir 139 if not os.path.realpath(scan_dir).startswith(os.path.realpath(root_dir)): 139 if not os.path.realpath(scan_dir).startswith( 140 os.path.realpath(root_dir)): 140 141 raise DispatchError('scan_dir:%s must be a directory under ' 141 142 'root_dir:%s.' % (scan_dir, root_dir)) … … 183 184 def _handler(self, request): 184 185 try: 185 return self._handlers[request.ws_resource] 186 ws_resource_path = request.ws_resource.split('?', 1)[0] 187 return self._handlers[ws_resource_path] 186 188 except KeyError: 187 189 raise DispatchError('No handler for: %r' % request.ws_resource) … … 189 191 def _source_files_in_dir(self, root_dir, scan_dir): 190 192 """Source all the handler source files in the scan_dir directory. 191 193 192 194 The resource path is determined relative to root_dir. 193 195 """ -
trunk/WebKitTools/pywebsocket/mod_pywebsocket/msgutil.py
r49672 r51406 74 74 # The payload is delimited with \xff. 75 75 bytes = _read_until(request, '\xff') 76 message = bytes.decode('utf-8') 76 # The Web Socket protocol section 4.4 specifies that invalid 77 # characters must be replaced with U+fffd REPLACEMENT CHARACTER. 78 message = bytes.decode('utf-8', 'replace') 77 79 if frame_type == 0x00: 78 80 return message -
trunk/WebKitTools/pywebsocket/mod_pywebsocket/standalone.py
r50102 r51406 39 39 [-s <scan_dir>] 40 40 [-d <document_root>] 41 ... for other options, see _main below ... 41 42 42 43 <ws_port> is the port number to use for ws:// connection. … … 60 61 import SocketServer 61 62 import logging 63 import logging.handlers 62 64 import optparse 63 65 import os … … 74 76 import dispatch 75 77 import handshake 78 79 80 _LOG_LEVELS = { 81 'debug': logging.DEBUG, 82 'info': logging.INFO, 83 'warn': logging.WARN, 84 'error': logging.ERROR, 85 'critical': logging.CRITICAL}; 86 87 _DEFAULT_LOG_MAX_BYTES = 1024 * 256 88 _DEFAULT_LOG_BACKUP_COUNT = 5 89 90 91 def _print_warnings_if_any(dispatcher): 92 warnings = dispatcher.source_warnings() 93 if warnings: 94 for warning in warnings: 95 logging.warning('mod_pywebsocket: %s' % warning) 76 96 77 97 … … 153 173 return socket_ 154 174 175 155 176 class WebSocketRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): 156 177 """SimpleHTTPRequestHandler specialized for Web Socket.""" … … 160 181 161 182 self.connection = self.request 162 self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)163 self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)183 self.rfile = socket._fileobject(self.request, 'rb', self.rbufsize) 184 self.wfile = socket._fileobject(self.request, 'wb', self.wbufsize) 164 185 165 186 def __init__(self, *args, **keywords): 166 187 self._request = _StandaloneRequest( 167 188 self, WebSocketRequestHandler.options.use_tls) 168 self._dispatcher = dispatch.Dispatcher( 169 WebSocketRequestHandler.options.websock_handlers, 170 WebSocketRequestHandler.options.scan_dir) 189 self._dispatcher = WebSocketRequestHandler.options.dispatcher 171 190 self._print_warnings_if_any() 172 191 self._handshaker = handshake.Handshaker(self._request, … … 201 220 return result 202 221 222 def log_request(self, code='-', size='-'): 223 """Override BaseHTTPServer.log_request.""" 224 225 logging.info('"%s" %s %s', 226 self.requestline, str(code), str(size)) 227 228 def log_error(self, *args): 229 """Override BaseHTTPServer.log_error.""" 230 231 # Despite the name, this method is for warnings than for errors. 232 # For example, HTTP status code is logged by this method. 233 logging.warn('%s - %s' % (self.address_string(), (args[0] % args[1:]))) 234 235 236 def _configure_logging(options): 237 logger = logging.getLogger() 238 logger.setLevel(_LOG_LEVELS[options.log_level]) 239 if options.log_file: 240 handler = logging.handlers.RotatingFileHandler( 241 options.log_file, 'a', options.log_max, options.log_count) 242 else: 243 handler = logging.StreamHandler() 244 formatter = logging.Formatter( 245 "[%(asctime)s] [%(levelname)s] %(name)s: %(message)s") 246 handler.setFormatter(formatter) 247 logger.addHandler(handler) 248 203 249 204 250 def _main(): 205 logging.basicConfig()206 207 251 parser = optparse.OptionParser() 208 252 parser.add_option('-p', '--port', dest='port', type='int', … … 225 269 parser.add_option('-c', '--certificate', dest='certificate', 226 270 default='', help='TLS certificate file.') 271 parser.add_option('-l', '--log_file', dest='log_file', 272 default='', help='Log file.') 273 parser.add_option('--log_level', type='choice', dest='log_level', 274 default='warn', 275 choices=['debug', 'info', 'warn', 'error', 'critical'], 276 help='Log level.') 277 parser.add_option('--log_max', dest='log_max', type='int', 278 default=_DEFAULT_LOG_MAX_BYTES, 279 help='Log maximum bytes') 280 parser.add_option('--log_count', dest='log_count', type='int', 281 default=_DEFAULT_LOG_BACKUP_COUNT, 282 help='Log backup count') 227 283 options = parser.parse_args()[0] 284 285 os.chdir(options.document_root) 286 287 _configure_logging(options) 228 288 229 289 if options.use_tls: 230 290 if not _HAS_OPEN_SSL: 231 print >>sys.stderr, 'To use TLS, install pyOpenSSL.'291 logging.critical('To use TLS, install pyOpenSSL.') 232 292 sys.exit(1) 233 293 if not options.private_key or not options.certificate: 234 print >>sys.stderr, ('To use TLS, specify private_key and '235 'certificate.')294 logging.critical( 295 'To use TLS, specify private_key and certificate.') 236 296 sys.exit(1) 237 297 … … 239 299 options.scan_dir = options.websock_handlers 240 300 241 WebSocketRequestHandler.options = options 242 WebSocketServer.options = options 243 244 os.chdir(options.document_root) 245 246 server = WebSocketServer(('', options.port), WebSocketRequestHandler) 247 server.serve_forever() 301 try: 302 # Share a Dispatcher among request handlers to save time for 303 # instantiation. Dispatcher can be shared because it is thread-safe. 304 options.dispatcher = dispatch.Dispatcher(options.websock_handlers, 305 options.scan_dir) 306 _print_warnings_if_any(options.dispatcher) 307 308 WebSocketRequestHandler.options = options 309 WebSocketServer.options = options 310 311 server = WebSocketServer(('', options.port), WebSocketRequestHandler) 312 server.serve_forever() 313 except Exception, e: 314 logging.critical(str(e)) 315 sys.exit(1) 248 316 249 317 -
trunk/WebKitTools/pywebsocket/setup.py
r50102 r51406 57 57 packages=[_PACKAGE_NAME], 58 58 url='http://code.google.com/p/pywebsocket/', 59 version='0.4. 1',59 version='0.4.2', 60 60 ) 61 61 -
trunk/WebKitTools/pywebsocket/test/test_dispatch.py
r50102 r51406 157 157 request.connection.written_data()) 158 158 159 request = mock.MockRequest(connection=mock.MockConn('')) 160 request.ws_resource = '/sub/plain?' 161 request.ws_protocol = None 162 dispatcher.transfer_data(request) 163 self.assertEqual('sub/plain_wsh.py is called for /sub/plain?, None', 164 request.connection.written_data()) 165 166 request = mock.MockRequest(connection=mock.MockConn('')) 167 request.ws_resource = '/sub/plain?q=v' 168 request.ws_protocol = None 169 dispatcher.transfer_data(request) 170 self.assertEqual('sub/plain_wsh.py is called for /sub/plain?q=v, None', 171 request.connection.written_data()) 172 159 173 def test_transfer_data_no_handler(self): 160 174 dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR, None) -
trunk/WebKitTools/pywebsocket/test/test_msgutil.py
r49672 r51406 71 71 # U+672c is encoded as e6,9c,ac in UTF-8 72 72 self.assertEqual(u'\u672c', msgutil.receive_message(request)) 73 74 def test_receive_message_erroneous_unicode(self): 75 # \x80 and \x81 are invalid as UTF-8. 76 request = _create_request('\x00\x80\x81\xff') 77 # Invalid characters should be replaced with 78 # U+fffd REPLACEMENT CHARACTER 79 self.assertEqual(u'\ufffd\ufffd', msgutil.receive_message(request)) 73 80 74 81 def test_receive_message_discard(self):
Note: See TracChangeset
for help on using the changeset viewer.