diff options
author | Steve Block <steveblock@google.com> | 2010-04-27 16:31:00 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-05-11 14:42:12 +0100 |
commit | dcc8cf2e65d1aa555cce12431a16547e66b469ee (patch) | |
tree | 92a8d65cd5383bca9749f5327fb5e440563926e6 /WebKitTools/pywebsocket | |
parent | ccac38a6b48843126402088a309597e682f40fe6 (diff) | |
download | external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.zip external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.gz external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.bz2 |
Merge webkit.org at r58033 : Initial merge by git
Change-Id: If006c38561af287c50cd578d251629b51e4d8cd1
Diffstat (limited to 'WebKitTools/pywebsocket')
31 files changed, 0 insertions, 3644 deletions
diff --git a/WebKitTools/pywebsocket/COPYING b/WebKitTools/pywebsocket/COPYING deleted file mode 100644 index ab9d52d..0000000 --- a/WebKitTools/pywebsocket/COPYING +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2009, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/WebKitTools/pywebsocket/MANIFEST.in b/WebKitTools/pywebsocket/MANIFEST.in deleted file mode 100644 index 1925688..0000000 --- a/WebKitTools/pywebsocket/MANIFEST.in +++ /dev/null @@ -1,6 +0,0 @@ -include COPYING -include MANIFEST.in -include README -recursive-include example *.py -recursive-include mod_pywebsocket *.py -recursive-include test *.py diff --git a/WebKitTools/pywebsocket/README b/WebKitTools/pywebsocket/README deleted file mode 100644 index 1f9f05f..0000000 --- a/WebKitTools/pywebsocket/README +++ /dev/null @@ -1,6 +0,0 @@ -Install this package by: -$ python setup.py build -$ sudo python setup.py install - -Then read document by: -$ pydoc mod_pywebsocket diff --git a/WebKitTools/pywebsocket/example/echo_client.py b/WebKitTools/pywebsocket/example/echo_client.py deleted file mode 100644 index 3262a6d..0000000 --- a/WebKitTools/pywebsocket/example/echo_client.py +++ /dev/null @@ -1,207 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Web Socket Echo client. - -This is an example Web Socket client that talks with echo_wsh.py. -This may be useful for checking mod_pywebsocket installation. - -Note: -This code is far from robust, e.g., we cut corners in handshake. -""" - - -import codecs -from optparse import OptionParser -import socket -import sys - - -_TIMEOUT_SEC = 10 - -_DEFAULT_PORT = 80 -_DEFAULT_SECURE_PORT = 443 -_UNDEFINED_PORT = -1 - -_UPGRADE_HEADER = 'Upgrade: WebSocket\r\n' -_CONNECTION_HEADER = 'Connection: Upgrade\r\n' -_EXPECTED_RESPONSE = ( - 'HTTP/1.1 101 Web Socket Protocol Handshake\r\n' + - _UPGRADE_HEADER + - _CONNECTION_HEADER) - -_GOODBYE_MESSAGE = 'Goodbye' - - -def _method_line(resource): - return 'GET %s HTTP/1.1\r\n' % resource - - -def _origin_header(origin): - return 'Origin: %s\r\n' % origin - - -class _TLSSocket(object): - """Wrapper for a TLS connection.""" - - def __init__(self, raw_socket): - self._ssl = socket.ssl(raw_socket) - - def send(self, bytes): - return self._ssl.write(bytes) - - def recv(self, size=-1): - return self._ssl.read(size) - - def close(self): - # Nothing to do. - pass - - -class EchoClient(object): - """Web Socket echo client.""" - - def __init__(self, options): - self._options = options - self._socket = None - - def run(self): - """Run the client. - - Shake hands and then repeat sending message and receiving its echo. - """ - self._socket = socket.socket() - self._socket.settimeout(self._options.socket_timeout) - try: - self._socket.connect((self._options.server_host, - self._options.server_port)) - if self._options.use_tls: - self._socket = _TLSSocket(self._socket) - self._handshake() - for line in self._options.message.split(',') + [_GOODBYE_MESSAGE]: - frame = '\x00' + line.encode('utf-8') + '\xff' - self._socket.send(frame) - if self._options.verbose: - print 'Send: %s' % line - received = self._socket.recv(len(frame)) - if received != frame: - raise Exception('Incorrect echo: %r' % received) - if self._options.verbose: - print 'Recv: %s' % received[1:-1].decode('utf-8', - 'replace') - finally: - self._socket.close() - - def _handshake(self): - self._socket.send(_method_line(self._options.resource)) - self._socket.send(_UPGRADE_HEADER) - self._socket.send(_CONNECTION_HEADER) - self._socket.send(self._format_host_header()) - self._socket.send(_origin_header(self._options.origin)) - self._socket.send('\r\n') - - for expected_char in _EXPECTED_RESPONSE: - received = self._socket.recv(1)[0] - if expected_char != received: - raise Exception('Handshake failure') - # We cut corners and skip other headers. - self._skip_headers() - - def _skip_headers(self): - terminator = '\r\n\r\n' - pos = 0 - while pos < len(terminator): - received = self._socket.recv(1)[0] - if received == terminator[pos]: - pos += 1 - elif received == terminator[0]: - pos = 1 - else: - pos = 0 - - def _format_host_header(self): - host = 'Host: ' + self._options.server_host - if ((not self._options.use_tls and - self._options.server_port != _DEFAULT_PORT) or - (self._options.use_tls and - self._options.server_port != _DEFAULT_SECURE_PORT)): - host += ':' + str(self._options.server_port) - host += '\r\n' - return host - - -def main(): - sys.stdout = codecs.getwriter('utf-8')(sys.stdout) - - parser = OptionParser() - parser.add_option('-s', '--server_host', dest='server_host', type='string', - default='localhost', help='server host') - parser.add_option('-p', '--server_port', dest='server_port', type='int', - default=_UNDEFINED_PORT, help='server port') - parser.add_option('-o', '--origin', dest='origin', type='string', - default='http://localhost/', help='origin') - parser.add_option('-r', '--resource', dest='resource', type='string', - default='/echo', help='resource path') - parser.add_option('-m', '--message', dest='message', type='string', - help=('comma-separated messages to send excluding "%s" ' - 'that is always sent at the end' % - _GOODBYE_MESSAGE)) - parser.add_option('-q', '--quiet', dest='verbose', action='store_false', - default=True, help='suppress messages') - parser.add_option('-t', '--tls', dest='use_tls', action='store_true', - default=False, help='use TLS (wss://)') - parser.add_option('-k', '--socket_timeout', dest='socket_timeout', - type='int', default=_TIMEOUT_SEC, - help='Timeout(sec) for sockets') - - (options, unused_args) = parser.parse_args() - - # Default port number depends on whether TLS is used. - if options.server_port == _UNDEFINED_PORT: - if options.use_tls: - options.server_port = _DEFAULT_SECURE_PORT - else: - options.server_port = _DEFAULT_PORT - - # optparse doesn't seem to handle non-ascii default values. - # Set default message here. - if not options.message: - options.message = u'Hello,\u65e5\u672c' # "Japan" in Japanese - - EchoClient(options).run() - - -if __name__ == '__main__': - main() - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/example/echo_wsh.py b/WebKitTools/pywebsocket/example/echo_wsh.py deleted file mode 100644 index 50cad31..0000000 --- a/WebKitTools/pywebsocket/example/echo_wsh.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -from mod_pywebsocket import msgutil - - -_GOODBYE_MESSAGE = 'Goodbye' - - -def web_socket_do_extra_handshake(request): - pass # Always accept. - - -def web_socket_transfer_data(request): - while True: - line = msgutil.receive_message(request) - msgutil.send_message(request, line) - if line == _GOODBYE_MESSAGE: - return - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/mod_pywebsocket/__init__.py b/WebKitTools/pywebsocket/mod_pywebsocket/__init__.py deleted file mode 100644 index 05e80e8..0000000 --- a/WebKitTools/pywebsocket/mod_pywebsocket/__init__.py +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Web Socket extension for Apache HTTP Server. - -mod_pywebsocket is a Web Socket extension for Apache HTTP Server -intended for testing or experimental purposes. mod_python is required. - -Installation: - -0. Prepare an Apache HTTP Server for which mod_python is enabled. - -1. Specify the following Apache HTTP Server directives to suit your - configuration. - - If mod_pywebsocket is not in the Python path, specify the following. - <websock_lib> is the directory where mod_pywebsocket is installed. - - PythonPath "sys.path+['<websock_lib>']" - - Always specify the following. <websock_handlers> is the directory where - user-written Web Socket handlers are placed. - - PythonOption mod_pywebsocket.handler_root <websock_handlers> - PythonHeaderParserHandler mod_pywebsocket.headerparserhandler - - To limit the search for Web Socket handlers to a directory <scan_dir> - under <websock_handlers>, configure as follows: - - PythonOption mod_pywebsocket.handler_scan <scan_dir> - - <scan_dir> is useful in saving scan time when <websock_handlers> - contains many non-Web Socket handler files. - - Example snippet of httpd.conf: - (mod_pywebsocket is in /websock_lib, Web Socket handlers are in - /websock_handlers, port is 80 for ws, 443 for wss.) - - <IfModule python_module> - PythonPath "sys.path+['/websock_lib']" - PythonOption mod_pywebsocket.handler_root /websock_handlers - PythonHeaderParserHandler mod_pywebsocket.headerparserhandler - </IfModule> - -Writing Web Socket handlers: - -When a Web Socket request comes in, the resource name -specified in the handshake is considered as if it is a file path under -<websock_handlers> and the handler defined in -<websock_handlers>/<resource_name>_wsh.py is invoked. - -For example, if the resource name is /example/chat, the handler defined in -<websock_handlers>/example/chat_wsh.py is invoked. - -A Web Socket handler is composed of the following two functions: - - web_socket_do_extra_handshake(request) - web_socket_transfer_data(request) - -where: - request: mod_python request. - -web_socket_do_extra_handshake is called during the handshake after the -headers are successfully parsed and Web Socket properties (ws_location, -ws_origin, ws_protocol, and ws_resource) are added to request. A handler -can reject the request by raising an exception. - -web_socket_transfer_data is called after the handshake completed -successfully. A handler can receive/send messages from/to the client -using request. mod_pywebsocket.msgutil module provides utilities -for data transfer. - -A Web Socket handler must be thread-safe if the server (Apache or -standalone.py) is configured to use threads. -""" - - -# vi:sts=4 sw=4 et tw=72 diff --git a/WebKitTools/pywebsocket/mod_pywebsocket/dispatch.py b/WebKitTools/pywebsocket/mod_pywebsocket/dispatch.py deleted file mode 100644 index c52e9eb..0000000 --- a/WebKitTools/pywebsocket/mod_pywebsocket/dispatch.py +++ /dev/null @@ -1,231 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Dispatch Web Socket request. -""" - - -import os -import re - -import util - - -_SOURCE_PATH_PATTERN = re.compile(r'(?i)_wsh\.py$') -_SOURCE_SUFFIX = '_wsh.py' -_DO_EXTRA_HANDSHAKE_HANDLER_NAME = 'web_socket_do_extra_handshake' -_TRANSFER_DATA_HANDLER_NAME = 'web_socket_transfer_data' - - -class DispatchError(Exception): - """Exception in dispatching Web Socket request.""" - - pass - - -def _normalize_path(path): - """Normalize path. - - Args: - path: the path to normalize. - - Path is converted to the absolute path. - The input path can use either '\\' or '/' as the separator. - The normalized path always uses '/' regardless of the platform. - """ - - path = path.replace('\\', os.path.sep) - path = os.path.realpath(path) - path = path.replace('\\', '/') - return path - - -def _path_to_resource_converter(base_dir): - base_dir = _normalize_path(base_dir) - base_len = len(base_dir) - suffix_len = len(_SOURCE_SUFFIX) - def converter(path): - if not path.endswith(_SOURCE_SUFFIX): - return None - path = _normalize_path(path) - if not path.startswith(base_dir): - return None - return path[base_len:-suffix_len] - return converter - - -def _source_file_paths(directory): - """Yield Web Socket Handler source file names in the given directory.""" - - for root, unused_dirs, files in os.walk(directory): - for base in files: - path = os.path.join(root, base) - if _SOURCE_PATH_PATTERN.search(path): - yield path - - -def _source(source_str): - """Source a handler definition string.""" - - global_dic = {} - try: - exec source_str in global_dic - except Exception: - raise DispatchError('Error in sourcing handler:' + - util.get_stack_trace()) - return (_extract_handler(global_dic, _DO_EXTRA_HANDSHAKE_HANDLER_NAME), - _extract_handler(global_dic, _TRANSFER_DATA_HANDLER_NAME)) - - -def _extract_handler(dic, name): - if name not in dic: - raise DispatchError('%s is not defined.' % name) - handler = dic[name] - if not callable(handler): - raise DispatchError('%s is not callable.' % name) - return handler - - -class Dispatcher(object): - """Dispatches Web Socket requests. - - This class maintains a map from resource name to handlers. - """ - - def __init__(self, root_dir, scan_dir=None): - """Construct an instance. - - Args: - root_dir: The directory where handler definition files are - placed. - scan_dir: The directory where handler definition files are - searched. scan_dir must be a directory under root_dir, - including root_dir itself. If scan_dir is None, root_dir - is used as scan_dir. scan_dir can be useful in saving - scan time when root_dir contains many subdirectories. - """ - - self._handlers = {} - self._source_warnings = [] - if scan_dir is None: - scan_dir = root_dir - if not os.path.realpath(scan_dir).startswith( - os.path.realpath(root_dir)): - raise DispatchError('scan_dir:%s must be a directory under ' - 'root_dir:%s.' % (scan_dir, root_dir)) - self._source_files_in_dir(root_dir, scan_dir) - - def add_resource_path_alias(self, - alias_resource_path, existing_resource_path): - """Add resource path alias. - - Once added, request to alias_resource_path would be handled by - handler registered for existing_resource_path. - - Args: - alias_resource_path: alias resource path - existing_resource_path: existing resource path - """ - try: - handler = self._handlers[existing_resource_path] - self._handlers[alias_resource_path] = handler - except KeyError: - raise DispatchError('No handler for: %r' % existing_resource_path) - - def source_warnings(self): - """Return warnings in sourcing handlers.""" - - return self._source_warnings - - def do_extra_handshake(self, request): - """Do extra checking in Web Socket handshake. - - Select a handler based on request.uri and call its - web_socket_do_extra_handshake function. - - Args: - request: mod_python request. - """ - - do_extra_handshake_, unused_transfer_data = self._handler(request) - try: - do_extra_handshake_(request) - except Exception, e: - util.prepend_message_to_exception( - '%s raised exception for %s: ' % ( - _DO_EXTRA_HANDSHAKE_HANDLER_NAME, - request.ws_resource), - e) - raise - - def transfer_data(self, request): - """Let a handler transfer_data with a Web Socket client. - - Select a handler based on request.ws_resource and call its - web_socket_transfer_data function. - - Args: - request: mod_python request. - """ - - unused_do_extra_handshake, transfer_data_ = self._handler(request) - try: - transfer_data_(request) - except Exception, e: - util.prepend_message_to_exception( - '%s raised exception for %s: ' % ( - _TRANSFER_DATA_HANDLER_NAME, request.ws_resource), - e) - raise - - def _handler(self, request): - try: - ws_resource_path = request.ws_resource.split('?', 1)[0] - return self._handlers[ws_resource_path] - except KeyError: - raise DispatchError('No handler for: %r' % request.ws_resource) - - def _source_files_in_dir(self, root_dir, scan_dir): - """Source all the handler source files in the scan_dir directory. - - The resource path is determined relative to root_dir. - """ - - to_resource = _path_to_resource_converter(root_dir) - for path in _source_file_paths(scan_dir): - try: - handlers = _source(open(path).read()) - except DispatchError, e: - self._source_warnings.append('%s: %s' % (path, e)) - continue - self._handlers[to_resource(path)] = handlers - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/mod_pywebsocket/handshake.py b/WebKitTools/pywebsocket/mod_pywebsocket/handshake.py deleted file mode 100644 index b86278e..0000000 --- a/WebKitTools/pywebsocket/mod_pywebsocket/handshake.py +++ /dev/null @@ -1,220 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Web Socket handshaking. - -Note: request.connection.write/read are used in this module, even though -mod_python document says that they should be used only in connection handlers. -Unfortunately, we have no other options. For example, request.write/read are -not suitable because they don't allow direct raw bytes writing/reading. -""" - - -import re - -import util - - -_DEFAULT_WEB_SOCKET_PORT = 80 -_DEFAULT_WEB_SOCKET_SECURE_PORT = 443 -_WEB_SOCKET_SCHEME = 'ws' -_WEB_SOCKET_SECURE_SCHEME = 'wss' - -_MANDATORY_HEADERS = [ - # key, expected value or None - ['Upgrade', 'WebSocket'], - ['Connection', 'Upgrade'], - ['Host', None], - ['Origin', None], -] - -_FIRST_FIVE_LINES = map(re.compile, [ - r'^GET /[\S]* HTTP/1.1\r\n$', - r'^Upgrade: WebSocket\r\n$', - r'^Connection: Upgrade\r\n$', - r'^Host: [\S]+\r\n$', - r'^Origin: [\S]+\r\n$', -]) - -_SIXTH_AND_LATER = re.compile( - r'^' - r'(WebSocket-Protocol: [\x20-\x7e]+\r\n)?' - r'(Cookie: [^\r]*\r\n)*' - r'(Cookie2: [^\r]*\r\n)?' - r'(Cookie: [^\r]*\r\n)*' - r'\r\n') - - -def _default_port(is_secure): - if is_secure: - return _DEFAULT_WEB_SOCKET_SECURE_PORT - else: - return _DEFAULT_WEB_SOCKET_PORT - - -class HandshakeError(Exception): - """Exception in Web Socket Handshake.""" - - pass - - -def _validate_protocol(protocol): - """Validate WebSocket-Protocol string.""" - - if not protocol: - raise HandshakeError('Invalid WebSocket-Protocol: empty') - for c in protocol: - if not 0x20 <= ord(c) <= 0x7e: - raise HandshakeError('Illegal character in protocol: %r' % c) - - -class Handshaker(object): - """This class performs Web Socket handshake.""" - - def __init__(self, request, dispatcher, strict=False): - """Construct an instance. - - Args: - request: mod_python request. - dispatcher: Dispatcher (dispatch.Dispatcher). - strict: Strictly check handshake request. Default: False. - If True, request.connection must provide get_memorized_lines - method. - - Handshaker will add attributes such as ws_resource in performing - handshake. - """ - - self._request = request - self._dispatcher = dispatcher - self._strict = strict - - def do_handshake(self): - """Perform Web Socket Handshake.""" - - self._check_header_lines() - self._set_resource() - self._set_origin() - self._set_location() - self._set_protocol() - self._dispatcher.do_extra_handshake(self._request) - self._send_handshake() - - def _set_resource(self): - self._request.ws_resource = self._request.uri - - def _set_origin(self): - self._request.ws_origin = self._request.headers_in['Origin'] - - def _set_location(self): - location_parts = [] - if self._request.is_https(): - location_parts.append(_WEB_SOCKET_SECURE_SCHEME) - else: - location_parts.append(_WEB_SOCKET_SCHEME) - location_parts.append('://') - host, port = self._parse_host_header() - connection_port = self._request.connection.local_addr[1] - if port != connection_port: - raise HandshakeError('Header/connection port mismatch: %d/%d' % - (port, connection_port)) - location_parts.append(host) - if (port != _default_port(self._request.is_https())): - location_parts.append(':') - location_parts.append(str(port)) - location_parts.append(self._request.uri) - self._request.ws_location = ''.join(location_parts) - - def _parse_host_header(self): - fields = self._request.headers_in['Host'].split(':', 1) - if len(fields) == 1: - return fields[0], _default_port(self._request.is_https()) - try: - return fields[0], int(fields[1]) - except ValueError, e: - raise HandshakeError('Invalid port number format: %r' % e) - - def _set_protocol(self): - protocol = self._request.headers_in.get('WebSocket-Protocol') - if protocol is not None: - _validate_protocol(protocol) - self._request.ws_protocol = protocol - - def _send_handshake(self): - self._request.connection.write( - 'HTTP/1.1 101 Web Socket Protocol Handshake\r\n') - self._request.connection.write('Upgrade: WebSocket\r\n') - self._request.connection.write('Connection: Upgrade\r\n') - self._request.connection.write('WebSocket-Origin: ') - self._request.connection.write(self._request.ws_origin) - self._request.connection.write('\r\n') - self._request.connection.write('WebSocket-Location: ') - self._request.connection.write(self._request.ws_location) - self._request.connection.write('\r\n') - if self._request.ws_protocol: - self._request.connection.write('WebSocket-Protocol: ') - self._request.connection.write(self._request.ws_protocol) - self._request.connection.write('\r\n') - self._request.connection.write('\r\n') - - def _check_header_lines(self): - for key, expected_value in _MANDATORY_HEADERS: - actual_value = self._request.headers_in.get(key) - if not actual_value: - raise HandshakeError('Header %s is not defined' % key) - if expected_value: - if actual_value != expected_value: - raise HandshakeError('Illegal value for header %s: %s' % - (key, actual_value)) - if self._strict: - try: - lines = self._request.connection.get_memorized_lines() - except AttributeError, e: - util.prepend_message_to_exception( - 'Strict handshake is specified but the connection ' - 'doesn\'t provide get_memorized_lines()', e) - raise - self._check_first_lines(lines) - - def _check_first_lines(self, lines): - if len(lines) < len(_FIRST_FIVE_LINES): - raise HandshakeError('Too few header lines: %d' % len(lines)) - for line, regexp in zip(lines, _FIRST_FIVE_LINES): - if not regexp.search(line): - raise HandshakeError('Unexpected header: %r doesn\'t match %r' - % (line, regexp.pattern)) - sixth_and_later = ''.join(lines[5:]) - if not _SIXTH_AND_LATER.search(sixth_and_later): - raise HandshakeError('Unexpected header: %r doesn\'t match %r' - % (sixth_and_later, - _SIXTH_AND_LATER.pattern)) - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/mod_pywebsocket/headerparserhandler.py b/WebKitTools/pywebsocket/mod_pywebsocket/headerparserhandler.py deleted file mode 100644 index 124b9f1..0000000 --- a/WebKitTools/pywebsocket/mod_pywebsocket/headerparserhandler.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""PythonHeaderParserHandler for mod_pywebsocket. - -Apache HTTP Server and mod_python must be configured such that this -function is called to handle Web Socket request. -""" - - -from mod_python import apache - -import dispatch -import handshake -import util - - -# PythonOption to specify the handler root directory. -_PYOPT_HANDLER_ROOT = 'mod_pywebsocket.handler_root' - -# PythonOption to specify the handler scan directory. -# This must be a directory under the root directory. -# The default is the root directory. -_PYOPT_HANDLER_SCAN = 'mod_pywebsocket.handler_scan' - - -def _create_dispatcher(): - _HANDLER_ROOT = apache.main_server.get_options().get( - _PYOPT_HANDLER_ROOT, None) - if not _HANDLER_ROOT: - raise Exception('PythonOption %s is not defined' % _PYOPT_HANDLER_ROOT, - apache.APLOG_ERR) - _HANDLER_SCAN = apache.main_server.get_options().get( - _PYOPT_HANDLER_SCAN, _HANDLER_ROOT) - dispatcher = dispatch.Dispatcher(_HANDLER_ROOT, _HANDLER_SCAN) - for warning in dispatcher.source_warnings(): - apache.log_error('mod_pywebsocket: %s' % warning, apache.APLOG_WARNING) - return dispatcher - - -# Initialize -_dispatcher = _create_dispatcher() - - -def headerparserhandler(request): - """Handle request. - - Args: - request: mod_python request. - - This function is named headerparserhandler because it is the default name - for a PythonHeaderParserHandler. - """ - - try: - handshaker = handshake.Handshaker(request, _dispatcher) - handshaker.do_handshake() - request.log_error('mod_pywebsocket: resource: %r' % request.ws_resource, - apache.APLOG_DEBUG) - _dispatcher.transfer_data(request) - except handshake.HandshakeError, e: - # Handshake for ws/wss failed. - # But the request can be valid http/https request. - request.log_error('mod_pywebsocket: %s' % e, apache.APLOG_INFO) - return apache.DECLINED - except dispatch.DispatchError, e: - request.log_error('mod_pywebsocket: %s' % e, apache.APLOG_WARNING) - return apache.DECLINED - return apache.DONE # Return DONE such that no other handlers are invoked. - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/mod_pywebsocket/memorizingfile.py b/WebKitTools/pywebsocket/mod_pywebsocket/memorizingfile.py deleted file mode 100644 index 2f8a54e..0000000 --- a/WebKitTools/pywebsocket/mod_pywebsocket/memorizingfile.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Memorizing file. - -A memorizing file wraps a file and memorizes lines read by readline. -""" - - -import sys - - -class MemorizingFile(object): - """MemorizingFile wraps a file and memorizes lines read by readline. - - Note that data read by other methods are not memorized. This behavior - is good enough for memorizing lines SimpleHTTPServer reads before - the control reaches WebSocketRequestHandler. - """ - def __init__(self, file_, max_memorized_lines=sys.maxint): - """Construct an instance. - - Args: - file_: the file object to wrap. - max_memorized_lines: the maximum number of lines to memorize. - Only the first max_memorized_lines are memorized. - Default: sys.maxint. - """ - self._file = file_ - self._memorized_lines = [] - self._max_memorized_lines = max_memorized_lines - - def __getattribute__(self, name): - if name in ('_file', '_memorized_lines', '_max_memorized_lines', - 'readline', 'get_memorized_lines'): - return object.__getattribute__(self, name) - return self._file.__getattribute__(name) - - def readline(self): - """Override file.readline and memorize the line read.""" - - line = self._file.readline() - if line and len(self._memorized_lines) < self._max_memorized_lines: - self._memorized_lines.append(line) - return line - - def get_memorized_lines(self): - """Get lines memorized so far.""" - return self._memorized_lines - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/mod_pywebsocket/msgutil.py b/WebKitTools/pywebsocket/mod_pywebsocket/msgutil.py deleted file mode 100644 index 90ae715..0000000 --- a/WebKitTools/pywebsocket/mod_pywebsocket/msgutil.py +++ /dev/null @@ -1,250 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Message related utilities. - -Note: request.connection.write/read are used in this module, even though -mod_python document says that they should be used only in connection handlers. -Unfortunately, we have no other options. For example, request.write/read are -not suitable because they don't allow direct raw bytes writing/reading. -""" - - -import Queue -import threading -import util - - -class MsgUtilException(Exception): - pass - - -def _read(request, length): - bytes = request.connection.read(length) - if not bytes: - raise MsgUtilException( - 'Failed to receive message from %r' % - (request.connection.remote_addr,)) - return bytes - - -def _write(request, bytes): - try: - request.connection.write(bytes) - except Exception, e: - util.prepend_message_to_exception( - 'Failed to send message to %r: ' % - (request.connection.remote_addr,), - e) - raise - - -def send_message(request, message): - """Send message. - - Args: - request: mod_python request. - message: unicode string to send. - """ - - _write(request, '\x00' + message.encode('utf-8') + '\xff') - - -def receive_message(request): - """Receive a Web Socket frame and return its payload as unicode string. - - Args: - request: mod_python request. - """ - - while True: - # Read 1 byte. - # mp_conn.read will block if no bytes are available. - # Timeout is controlled by TimeOut directive of Apache. - frame_type_str = _read(request, 1) - frame_type = ord(frame_type_str[0]) - if (frame_type & 0x80) == 0x80: - # The payload length is specified in the frame. - # Read and discard. - length = _payload_length(request) - _receive_bytes(request, length) - else: - # The payload is delimited with \xff. - bytes = _read_until(request, '\xff') - # The Web Socket protocol section 4.4 specifies that invalid - # characters must be replaced with U+fffd REPLACEMENT CHARACTER. - message = bytes.decode('utf-8', 'replace') - if frame_type == 0x00: - return message - # Discard data of other types. - - -def _payload_length(request): - length = 0 - while True: - b_str = _read(request, 1) - b = ord(b_str[0]) - length = length * 128 + (b & 0x7f) - if (b & 0x80) == 0: - break - return length - - -def _receive_bytes(request, length): - bytes = [] - while length > 0: - new_bytes = _read(request, length) - bytes.append(new_bytes) - length -= len(new_bytes) - return ''.join(bytes) - - -def _read_until(request, delim_char): - bytes = [] - while True: - ch = _read(request, 1) - if ch == delim_char: - break - bytes.append(ch) - return ''.join(bytes) - - -class MessageReceiver(threading.Thread): - """This class receives messages from the client. - - This class provides three ways to receive messages: blocking, non-blocking, - and via callback. Callback has the highest precedence. - - Note: This class should not be used with the standalone server for wss - because pyOpenSSL used by the server raises a fatal error if the socket - is accessed from multiple threads. - """ - def __init__(self, request, onmessage=None): - """Construct an instance. - - Args: - request: mod_python request. - onmessage: a function to be called when a message is received. - May be None. If not None, the function is called on - another thread. In that case, MessageReceiver.receive - and MessageReceiver.receive_nowait are useless because - they will never return any messages. - """ - threading.Thread.__init__(self) - self._request = request - self._queue = Queue.Queue() - self._onmessage = onmessage - self._stop_requested = False - self.setDaemon(True) - self.start() - - def run(self): - while not self._stop_requested: - message = receive_message(self._request) - if self._onmessage: - self._onmessage(message) - else: - self._queue.put(message) - - def receive(self): - """ Receive a message from the channel, blocking. - - Returns: - message as a unicode string. - """ - return self._queue.get() - - def receive_nowait(self): - """ Receive a message from the channel, non-blocking. - - Returns: - message as a unicode string if available. None otherwise. - """ - try: - message = self._queue.get_nowait() - except Queue.Empty: - message = None - return message - - def stop(self): - """Request to stop this instance. - - The instance will be stopped after receiving the next message. - This method may not be very useful, but there is no clean way - in Python to forcefully stop a running thread. - """ - self._stop_requested = True - - -class MessageSender(threading.Thread): - """This class sends messages to the client. - - This class provides both synchronous and asynchronous ways to send - messages. - - Note: This class should not be used with the standalone server for wss - because pyOpenSSL used by the server raises a fatal error if the socket - is accessed from multiple threads. - """ - def __init__(self, request): - """Construct an instance. - - Args: - request: mod_python request. - """ - threading.Thread.__init__(self) - self._request = request - self._queue = Queue.Queue() - self.setDaemon(True) - self.start() - - def run(self): - while True: - message, condition = self._queue.get() - condition.acquire() - send_message(self._request, message) - condition.notify() - condition.release() - - def send(self, message): - """Send a message, blocking.""" - - condition = threading.Condition() - condition.acquire() - self._queue.put((message, condition)) - condition.wait() - - def send_nowait(self, message): - """Send a message, non-blocking.""" - - self._queue.put((message, threading.Condition())) - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/mod_pywebsocket/standalone.py b/WebKitTools/pywebsocket/mod_pywebsocket/standalone.py deleted file mode 100644 index 8628ff9..0000000 --- a/WebKitTools/pywebsocket/mod_pywebsocket/standalone.py +++ /dev/null @@ -1,421 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Standalone Web Socket server. - -Use this server to run mod_pywebsocket without Apache HTTP Server. - -Usage: - python standalone.py [-p <ws_port>] [-w <websock_handlers>] - [-s <scan_dir>] - [-d <document_root>] - [-m <websock_handlers_map_file>] - ... for other options, see _main below ... - -<ws_port> is the port number to use for ws:// connection. - -<document_root> is the path to the root directory of HTML files. - -<websock_handlers> is the path to the root directory of Web Socket handlers. -See __init__.py for details of <websock_handlers> and how to write Web Socket -handlers. If this path is relative, <document_root> is used as the base. - -<scan_dir> is a path under the root directory. If specified, only the handlers -under scan_dir are scanned. This is useful in saving scan time. - -Note: -This server is derived from SocketServer.ThreadingMixIn. Hence a thread is -used for each request. -""" - -import BaseHTTPServer -import CGIHTTPServer -import SimpleHTTPServer -import SocketServer -import logging -import logging.handlers -import optparse -import os -import re -import socket -import sys - -_HAS_OPEN_SSL = False -try: - import OpenSSL.SSL - _HAS_OPEN_SSL = True -except ImportError: - pass - -import dispatch -import handshake -import memorizingfile -import util - - -_LOG_LEVELS = { - 'debug': logging.DEBUG, - 'info': logging.INFO, - 'warn': logging.WARN, - 'error': logging.ERROR, - 'critical': logging.CRITICAL}; - -_DEFAULT_LOG_MAX_BYTES = 1024 * 256 -_DEFAULT_LOG_BACKUP_COUNT = 5 - -_DEFAULT_REQUEST_QUEUE_SIZE = 128 - -# 1024 is practically large enough to contain WebSocket handshake lines. -_MAX_MEMORIZED_LINES = 1024 - -def _print_warnings_if_any(dispatcher): - warnings = dispatcher.source_warnings() - if warnings: - for warning in warnings: - logging.warning('mod_pywebsocket: %s' % warning) - - -class _StandaloneConnection(object): - """Mimic mod_python mp_conn.""" - - def __init__(self, request_handler): - """Construct an instance. - - Args: - request_handler: A WebSocketRequestHandler instance. - """ - self._request_handler = request_handler - - def get_local_addr(self): - """Getter to mimic mp_conn.local_addr.""" - return (self._request_handler.server.server_name, - self._request_handler.server.server_port) - local_addr = property(get_local_addr) - - def get_remote_addr(self): - """Getter to mimic mp_conn.remote_addr. - - Setting the property in __init__ won't work because the request - handler is not initialized yet there.""" - return self._request_handler.client_address - remote_addr = property(get_remote_addr) - - def write(self, data): - """Mimic mp_conn.write().""" - return self._request_handler.wfile.write(data) - - def read(self, length): - """Mimic mp_conn.read().""" - return self._request_handler.rfile.read(length) - - def get_memorized_lines(self): - """Get memorized lines.""" - return self._request_handler.rfile.get_memorized_lines() - - -class _StandaloneRequest(object): - """Mimic mod_python request.""" - - def __init__(self, request_handler, use_tls): - """Construct an instance. - - Args: - request_handler: A WebSocketRequestHandler instance. - """ - self._request_handler = request_handler - self.connection = _StandaloneConnection(request_handler) - self._use_tls = use_tls - - def get_uri(self): - """Getter to mimic request.uri.""" - return self._request_handler.path - uri = property(get_uri) - - def get_headers_in(self): - """Getter to mimic request.headers_in.""" - return self._request_handler.headers - headers_in = property(get_headers_in) - - def is_https(self): - """Mimic request.is_https().""" - return self._use_tls - - -class WebSocketServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer): - """HTTPServer specialized for Web Socket.""" - - SocketServer.ThreadingMixIn.daemon_threads = True - - def __init__(self, server_address, RequestHandlerClass): - """Override SocketServer.BaseServer.__init__.""" - - SocketServer.BaseServer.__init__( - self, server_address, RequestHandlerClass) - self.socket = self._create_socket() - self.server_bind() - self.server_activate() - - def _create_socket(self): - socket_ = socket.socket(self.address_family, self.socket_type) - if WebSocketServer.options.use_tls: - ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD) - ctx.use_privatekey_file(WebSocketServer.options.private_key) - ctx.use_certificate_file(WebSocketServer.options.certificate) - socket_ = OpenSSL.SSL.Connection(ctx, socket_) - return socket_ - - def handle_error(self, rquest, client_address): - """Override SocketServer.handle_error.""" - - logging.error( - ('Exception in processing request from: %r' % (client_address,)) + - '\n' + util.get_stack_trace()) - # Note: client_address is a tuple. To match it against %r, we need the - # trailing comma. - - -class WebSocketRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler): - """CGIHTTPRequestHandler specialized for Web Socket.""" - - def setup(self): - """Override SocketServer.StreamRequestHandler.setup.""" - - self.connection = self.request - self.rfile = memorizingfile.MemorizingFile( - socket._fileobject(self.request, 'rb', self.rbufsize), - max_memorized_lines=_MAX_MEMORIZED_LINES) - self.wfile = socket._fileobject(self.request, 'wb', self.wbufsize) - - def __init__(self, *args, **keywords): - self._request = _StandaloneRequest( - self, WebSocketRequestHandler.options.use_tls) - self._dispatcher = WebSocketRequestHandler.options.dispatcher - self._print_warnings_if_any() - self._handshaker = handshake.Handshaker( - self._request, self._dispatcher, - WebSocketRequestHandler.options.strict) - CGIHTTPServer.CGIHTTPRequestHandler.__init__( - self, *args, **keywords) - - def _print_warnings_if_any(self): - warnings = self._dispatcher.source_warnings() - if warnings: - for warning in warnings: - logging.warning('mod_pywebsocket: %s' % warning) - - def parse_request(self): - """Override BaseHTTPServer.BaseHTTPRequestHandler.parse_request. - - Return True to continue processing for HTTP(S), False otherwise. - """ - result = CGIHTTPServer.CGIHTTPRequestHandler.parse_request(self) - if result: - try: - self._handshaker.do_handshake() - self._dispatcher.transfer_data(self._request) - return False - except handshake.HandshakeError, e: - # Handshake for ws(s) failed. Assume http(s). - logging.info('mod_pywebsocket: %s' % e) - return True - except dispatch.DispatchError, e: - logging.warning('mod_pywebsocket: %s' % e) - return False - except Exception, e: - logging.warning('mod_pywebsocket: %s' % e) - logging.info('mod_pywebsocket: %s' % util.get_stack_trace()) - return False - return result - - def log_request(self, code='-', size='-'): - """Override BaseHTTPServer.log_request.""" - - logging.info('"%s" %s %s', - self.requestline, str(code), str(size)) - - def log_error(self, *args): - """Override BaseHTTPServer.log_error.""" - - # Despite the name, this method is for warnings than for errors. - # For example, HTTP status code is logged by this method. - logging.warn('%s - %s' % (self.address_string(), (args[0] % args[1:]))) - - def is_cgi(self): - """Test whether self.path corresponds to a CGI script. - - Add extra check that self.path doesn't contains ..""" - if CGIHTTPServer.CGIHTTPRequestHandler.is_cgi(self): - if '..' in self.path: - return False - return True - return False - - -def _configure_logging(options): - logger = logging.getLogger() - logger.setLevel(_LOG_LEVELS[options.log_level]) - if options.log_file: - handler = logging.handlers.RotatingFileHandler( - options.log_file, 'a', options.log_max, options.log_count) - else: - handler = logging.StreamHandler() - formatter = logging.Formatter( - "[%(asctime)s] [%(levelname)s] %(name)s: %(message)s") - handler.setFormatter(formatter) - logger.addHandler(handler) - -def _alias_handlers(dispatcher, websock_handlers_map_file): - """Set aliases specified in websock_handler_map_file in dispatcher. - - Args: - dispatcher: dispatch.Dispatcher instance - websock_handler_map_file: alias map file - """ - fp = open(websock_handlers_map_file) - try: - for line in fp: - if line[0] == '#' or line.isspace(): - continue - m = re.match('(\S+)\s+(\S+)', line) - if not m: - logging.warning('Wrong format in map file:' + line) - continue - try: - dispatcher.add_resource_path_alias( - m.group(1), m.group(2)) - except dispatch.DispatchError, e: - logging.error(str(e)) - finally: - fp.close() - - - -def _main(): - parser = optparse.OptionParser() - parser.add_option('-p', '--port', dest='port', type='int', - default=handshake._DEFAULT_WEB_SOCKET_PORT, - help='port to listen to') - parser.add_option('-w', '--websock_handlers', dest='websock_handlers', - default='.', - help='Web Socket handlers root directory.') - parser.add_option('-m', '--websock_handlers_map_file', - dest='websock_handlers_map_file', - default=None, - help=('Web Socket handlers map file. ' - 'Each line consists of alias_resource_path and ' - 'existing_resource_path, separated by spaces.')) - parser.add_option('-s', '--scan_dir', dest='scan_dir', - default=None, - help=('Web Socket handlers scan directory. ' - 'Must be a directory under websock_handlers.')) - parser.add_option('-d', '--document_root', dest='document_root', - default='.', - help='Document root directory.') - parser.add_option('-x', '--cgi_paths', dest='cgi_paths', - default=None, - help=('CGI paths relative to document_root.' - 'Comma-separated. (e.g -x /cgi,/htbin) ' - 'Files under document_root/cgi_path are handled ' - 'as CGI programs. Must be executable.')) - parser.add_option('-t', '--tls', dest='use_tls', action='store_true', - default=False, help='use TLS (wss://)') - parser.add_option('-k', '--private_key', dest='private_key', - default='', help='TLS private key file.') - parser.add_option('-c', '--certificate', dest='certificate', - default='', help='TLS certificate file.') - parser.add_option('-l', '--log_file', dest='log_file', - default='', help='Log file.') - parser.add_option('--log_level', type='choice', dest='log_level', - default='warn', - choices=['debug', 'info', 'warn', 'error', 'critical'], - help='Log level.') - parser.add_option('--log_max', dest='log_max', type='int', - default=_DEFAULT_LOG_MAX_BYTES, - help='Log maximum bytes') - parser.add_option('--log_count', dest='log_count', type='int', - default=_DEFAULT_LOG_BACKUP_COUNT, - help='Log backup count') - parser.add_option('--strict', dest='strict', action='store_true', - default=False, help='Strictly check handshake request') - parser.add_option('-q', '--queue', dest='request_queue_size', type='int', - default=_DEFAULT_REQUEST_QUEUE_SIZE, - help='request queue size') - options = parser.parse_args()[0] - - os.chdir(options.document_root) - - _configure_logging(options) - - SocketServer.TCPServer.request_queue_size = options.request_queue_size - CGIHTTPServer.CGIHTTPRequestHandler.cgi_directories = [] - - if options.cgi_paths: - CGIHTTPServer.CGIHTTPRequestHandler.cgi_directories = \ - options.cgi_paths.split(',') - - if options.use_tls: - if not _HAS_OPEN_SSL: - logging.critical('To use TLS, install pyOpenSSL.') - sys.exit(1) - if not options.private_key or not options.certificate: - logging.critical( - 'To use TLS, specify private_key and certificate.') - sys.exit(1) - - if not options.scan_dir: - options.scan_dir = options.websock_handlers - - try: - # Share a Dispatcher among request handlers to save time for - # instantiation. Dispatcher can be shared because it is thread-safe. - options.dispatcher = dispatch.Dispatcher(options.websock_handlers, - options.scan_dir) - if options.websock_handlers_map_file: - _alias_handlers(options.dispatcher, - options.websock_handlers_map_file) - _print_warnings_if_any(options.dispatcher) - - WebSocketRequestHandler.options = options - WebSocketServer.options = options - - server = WebSocketServer(('', options.port), WebSocketRequestHandler) - server.serve_forever() - except Exception, e: - logging.critical(str(e)) - sys.exit(1) - - -if __name__ == '__main__': - _main() - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/mod_pywebsocket/util.py b/WebKitTools/pywebsocket/mod_pywebsocket/util.py deleted file mode 100644 index 0ea8053..0000000 --- a/WebKitTools/pywebsocket/mod_pywebsocket/util.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Web Sockets utilities. -""" - - -import StringIO -import traceback - - -def get_stack_trace(): - """Get the current stack trace as string. - - This is needed to support Python 2.3. - TODO: Remove this when we only support Python 2.4 and above. - Use traceback.format_exc instead. - """ - - out = StringIO.StringIO() - traceback.print_exc(file=out) - return out.getvalue() - - -def prepend_message_to_exception(message, exc): - """Prepend message to the exception.""" - - exc.args = (message + str(exc),) - return - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/setup.py b/WebKitTools/pywebsocket/setup.py deleted file mode 100644 index 9729322..0000000 --- a/WebKitTools/pywebsocket/setup.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Set up script for mod_pywebsocket. -""" - - -from distutils.core import setup -import sys - - -_PACKAGE_NAME = 'mod_pywebsocket' - -if sys.version < '2.3': - print >>sys.stderr, '%s requires Python 2.3 or later.' % _PACKAGE_NAME - sys.exit(1) - -setup(author='Yuzo Fujishima', - author_email='yuzo@chromium.org', - description='Web Socket extension for Apache HTTP Server.', - long_description=( - 'mod_pywebsocket is an Apache HTTP Server extension for ' - 'Web Socket (http://tools.ietf.org/html/' - 'draft-hixie-thewebsocketprotocol). ' - 'See mod_pywebsocket/__init__.py for more detail.'), - license='See COPYING', - name=_PACKAGE_NAME, - packages=[_PACKAGE_NAME], - url='http://code.google.com/p/pywebsocket/', - version='0.4.8', - ) - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/config.py b/WebKitTools/pywebsocket/test/config.py deleted file mode 100644 index 5aaab8c..0000000 --- a/WebKitTools/pywebsocket/test/config.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Configuration for testing. - -Test files should import this module before mod_pywebsocket. -""" - - -import os -import sys - - -# Add the parent directory to sys.path to enable importing mod_pywebsocket. -sys.path += [os.path.join(os.path.split(__file__)[0], '..')] - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/mock.py b/WebKitTools/pywebsocket/test/mock.py deleted file mode 100644 index 3b85d64..0000000 --- a/WebKitTools/pywebsocket/test/mock.py +++ /dev/null @@ -1,205 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Mocks for testing. -""" - - -import Queue -import threading - - -class _MockConnBase(object): - """Base class of mocks for mod_python.apache.mp_conn. - - This enables tests to check what is written to a (mock) mp_conn. - """ - - def __init__(self): - self._write_data = [] - - def write(self, data): - """Override mod_python.apache.mp_conn.write.""" - - self._write_data.append(data) - - def written_data(self): - """Get bytes written to this mock.""" - - return ''.join(self._write_data) - - -class MockConn(_MockConnBase): - """Mock for mod_python.apache.mp_conn. - - This enables tests to specify what should be read from a (mock) mp_conn as - well as to check what is written to it. - """ - - def __init__(self, read_data): - """Constructs an instance. - - Args: - read_data: bytes that should be returned when read* methods are - called. - """ - - _MockConnBase.__init__(self) - self._read_data = read_data - self._read_pos = 0 - - def readline(self): - """Override mod_python.apache.mp_conn.readline.""" - - if self._read_pos >= len(self._read_data): - return '' - end_index = self._read_data.find('\n', self._read_pos) + 1 - if not end_index: - end_index = len(self._read_data) - return self._read_up_to(end_index) - - def read(self, length): - """Override mod_python.apache.mp_conn.read.""" - - if self._read_pos >= len(self._read_data): - return '' - end_index = min(len(self._read_data), self._read_pos + length) - return self._read_up_to(end_index) - - def _read_up_to(self, end_index): - line = self._read_data[self._read_pos:end_index] - self._read_pos = end_index - return line - - -class MockBlockingConn(_MockConnBase): - """Blocking mock for mod_python.apache.mp_conn. - - This enables tests to specify what should be read from a (mock) mp_conn as - well as to check what is written to it. - Callers of read* methods will block if there is no bytes available. - """ - - def __init__(self): - _MockConnBase.__init__(self) - self._queue = Queue.Queue() - - def readline(self): - """Override mod_python.apache.mp_conn.readline.""" - line = '' - while True: - c = self._queue.get() - line += c - if c == '\n': - return line - - def read(self, length): - """Override mod_python.apache.mp_conn.read.""" - - data = '' - for unused in range(length): - data += self._queue.get() - return data - - def put_bytes(self, bytes): - """Put bytes to be read from this mock. - - Args: - bytes: bytes to be read. - """ - - for byte in bytes: - self._queue.put(byte) - - -class MockTable(dict): - """Mock table. - - This mimics mod_python mp_table. Note that only the methods used by - tests are overridden. - """ - - def __init__(self, copy_from={}): - if isinstance(copy_from, dict): - copy_from = copy_from.items() - for key, value in copy_from: - self.__setitem__(key, value) - - def __getitem__(self, key): - return super(MockTable, self).__getitem__(key.lower()) - - def __setitem__(self, key, value): - super(MockTable, self).__setitem__(key.lower(), value) - - def get(self, key, def_value=None): - return super(MockTable, self).get(key.lower(), def_value) - - -class MockRequest(object): - """Mock request. - - This mimics mod_python request. - """ - - def __init__(self, uri=None, headers_in={}, connection=None, - is_https=False): - """Construct an instance. - - Arguments: - uri: URI of the request. - headers_in: Request headers. - connection: Connection used for the request. - is_https: Whether this request is over SSL. - - See the document of mod_python Request for details. - """ - self.uri = uri - self.connection = connection - self.headers_in = MockTable(headers_in) - # self.is_https_ needs to be accessible from tests. To avoid name - # conflict with self.is_https(), it is named as such. - self.is_https_ = is_https - - def is_https(self): - """Return whether this request is over SSL.""" - return self.is_https_ - - -class MockDispatcher(object): - """Mock for dispatch.Dispatcher.""" - - def do_extra_handshake(self, conn_context): - pass - - def transfer_data(self, conn_context): - pass - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/run_all.py b/WebKitTools/pywebsocket/test/run_all.py deleted file mode 100644 index 3885618..0000000 --- a/WebKitTools/pywebsocket/test/run_all.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Run all tests in the same directory. -""" - - -import os -import re -import unittest - - -_TEST_MODULE_PATTERN = re.compile(r'^(test_.+)\.py$') - - -def _list_test_modules(directory): - module_names = [] - for filename in os.listdir(directory): - match = _TEST_MODULE_PATTERN.search(filename) - if match: - module_names.append(match.group(1)) - return module_names - - -def _suite(): - loader = unittest.TestLoader() - return loader.loadTestsFromNames( - _list_test_modules(os.path.join(os.path.split(__file__)[0], '.'))) - - -if __name__ == '__main__': - unittest.main(defaultTest='_suite') - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/test_dispatch.py b/WebKitTools/pywebsocket/test/test_dispatch.py deleted file mode 100644 index 5403228..0000000 --- a/WebKitTools/pywebsocket/test/test_dispatch.py +++ /dev/null @@ -1,244 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Tests for dispatch module.""" - - - -import os -import unittest - -import config # This must be imported before mod_pywebsocket. -from mod_pywebsocket import dispatch - -import mock - - -_TEST_HANDLERS_DIR = os.path.join( - os.path.split(__file__)[0], 'testdata', 'handlers') - -_TEST_HANDLERS_SUB_DIR = os.path.join(_TEST_HANDLERS_DIR, 'sub') - -class DispatcherTest(unittest.TestCase): - def test_normalize_path(self): - self.assertEqual(os.path.abspath('/a/b').replace('\\', '/'), - dispatch._normalize_path('/a/b')) - self.assertEqual(os.path.abspath('/a/b').replace('\\', '/'), - dispatch._normalize_path('\\a\\b')) - self.assertEqual(os.path.abspath('/a/b').replace('\\', '/'), - dispatch._normalize_path('/a/c/../b')) - self.assertEqual(os.path.abspath('abc').replace('\\', '/'), - dispatch._normalize_path('abc')) - - def test_converter(self): - converter = dispatch._path_to_resource_converter('/a/b') - self.assertEqual('/h', converter('/a/b/h_wsh.py')) - self.assertEqual('/c/h', converter('/a/b/c/h_wsh.py')) - self.assertEqual(None, converter('/a/b/h.py')) - self.assertEqual(None, converter('a/b/h_wsh.py')) - - converter = dispatch._path_to_resource_converter('a/b') - self.assertEqual('/h', converter('a/b/h_wsh.py')) - - converter = dispatch._path_to_resource_converter('/a/b///') - self.assertEqual('/h', converter('/a/b/h_wsh.py')) - self.assertEqual('/h', converter('/a/b/../b/h_wsh.py')) - - converter = dispatch._path_to_resource_converter('/a/../a/b/../b/') - self.assertEqual('/h', converter('/a/b/h_wsh.py')) - - converter = dispatch._path_to_resource_converter(r'\a\b') - self.assertEqual('/h', converter(r'\a\b\h_wsh.py')) - self.assertEqual('/h', converter(r'/a/b/h_wsh.py')) - - def test_source_file_paths(self): - paths = list(dispatch._source_file_paths(_TEST_HANDLERS_DIR)) - paths.sort() - self.assertEqual(7, len(paths)) - expected_paths = [ - os.path.join(_TEST_HANDLERS_DIR, 'blank_wsh.py'), - os.path.join(_TEST_HANDLERS_DIR, 'origin_check_wsh.py'), - os.path.join(_TEST_HANDLERS_DIR, 'sub', - 'exception_in_transfer_wsh.py'), - os.path.join(_TEST_HANDLERS_DIR, 'sub', 'non_callable_wsh.py'), - os.path.join(_TEST_HANDLERS_DIR, 'sub', 'plain_wsh.py'), - os.path.join(_TEST_HANDLERS_DIR, 'sub', - 'wrong_handshake_sig_wsh.py'), - os.path.join(_TEST_HANDLERS_DIR, 'sub', - 'wrong_transfer_sig_wsh.py'), - ] - for expected, actual in zip(expected_paths, paths): - self.assertEqual(expected, actual) - - def test_source(self): - self.assertRaises(dispatch.DispatchError, dispatch._source, '') - self.assertRaises(dispatch.DispatchError, dispatch._source, 'def') - self.assertRaises(dispatch.DispatchError, dispatch._source, '1/0') - self.failUnless(dispatch._source( - 'def web_socket_do_extra_handshake(request):pass\n' - 'def web_socket_transfer_data(request):pass\n')) - - def test_source_warnings(self): - dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR, None) - warnings = dispatcher.source_warnings() - warnings.sort() - expected_warnings = [ - (os.path.join(_TEST_HANDLERS_DIR, 'blank_wsh.py') + - ': web_socket_do_extra_handshake is not defined.'), - (os.path.join(_TEST_HANDLERS_DIR, 'sub', - 'non_callable_wsh.py') + - ': web_socket_do_extra_handshake is not callable.'), - (os.path.join(_TEST_HANDLERS_DIR, 'sub', - 'wrong_handshake_sig_wsh.py') + - ': web_socket_do_extra_handshake is not defined.'), - (os.path.join(_TEST_HANDLERS_DIR, 'sub', - 'wrong_transfer_sig_wsh.py') + - ': web_socket_transfer_data is not defined.'), - ] - self.assertEquals(4, len(warnings)) - for expected, actual in zip(expected_warnings, warnings): - self.assertEquals(expected, actual) - - def test_do_extra_handshake(self): - dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR, None) - request = mock.MockRequest() - request.ws_resource = '/origin_check' - request.ws_origin = 'http://example.com' - dispatcher.do_extra_handshake(request) # Must not raise exception. - - request.ws_origin = 'http://bad.example.com' - self.assertRaises(Exception, dispatcher.do_extra_handshake, request) - - def test_transfer_data(self): - dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR, None) - request = mock.MockRequest(connection=mock.MockConn('')) - request.ws_resource = '/origin_check' - request.ws_protocol = 'p1' - - dispatcher.transfer_data(request) - self.assertEqual('origin_check_wsh.py is called for /origin_check, p1', - request.connection.written_data()) - - request = mock.MockRequest(connection=mock.MockConn('')) - request.ws_resource = '/sub/plain' - request.ws_protocol = None - dispatcher.transfer_data(request) - self.assertEqual('sub/plain_wsh.py is called for /sub/plain, None', - request.connection.written_data()) - - request = mock.MockRequest(connection=mock.MockConn('')) - request.ws_resource = '/sub/plain?' - request.ws_protocol = None - dispatcher.transfer_data(request) - self.assertEqual('sub/plain_wsh.py is called for /sub/plain?, None', - request.connection.written_data()) - - request = mock.MockRequest(connection=mock.MockConn('')) - request.ws_resource = '/sub/plain?q=v' - request.ws_protocol = None - dispatcher.transfer_data(request) - self.assertEqual('sub/plain_wsh.py is called for /sub/plain?q=v, None', - request.connection.written_data()) - - def test_transfer_data_no_handler(self): - dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR, None) - for resource in ['/blank', '/sub/non_callable', - '/sub/no_wsh_at_the_end', '/does/not/exist']: - request = mock.MockRequest(connection=mock.MockConn('')) - request.ws_resource = resource - request.ws_protocol = 'p2' - try: - dispatcher.transfer_data(request) - self.fail() - except dispatch.DispatchError, e: - self.failUnless(str(e).find('No handler') != -1) - except Exception: - self.fail() - - def test_transfer_data_handler_exception(self): - dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR, None) - request = mock.MockRequest(connection=mock.MockConn('')) - request.ws_resource = '/sub/exception_in_transfer' - request.ws_protocol = 'p3' - try: - dispatcher.transfer_data(request) - self.fail() - except Exception, e: - self.failUnless(str(e).find('Intentional') != -1) - - def test_scan_dir(self): - disp = dispatch.Dispatcher(_TEST_HANDLERS_DIR, None) - self.assertEqual(3, len(disp._handlers)) - self.failUnless(disp._handlers.has_key('/origin_check')) - self.failUnless(disp._handlers.has_key('/sub/exception_in_transfer')) - self.failUnless(disp._handlers.has_key('/sub/plain')) - - def test_scan_sub_dir(self): - disp = dispatch.Dispatcher(_TEST_HANDLERS_DIR, _TEST_HANDLERS_SUB_DIR) - self.assertEqual(2, len(disp._handlers)) - self.failIf(disp._handlers.has_key('/origin_check')) - self.failUnless(disp._handlers.has_key('/sub/exception_in_transfer')) - self.failUnless(disp._handlers.has_key('/sub/plain')) - - def test_scan_sub_dir_as_root(self): - disp = dispatch.Dispatcher(_TEST_HANDLERS_SUB_DIR, - _TEST_HANDLERS_SUB_DIR) - self.assertEqual(2, len(disp._handlers)) - self.failIf(disp._handlers.has_key('/origin_check')) - self.failIf(disp._handlers.has_key('/sub/exception_in_transfer')) - self.failIf(disp._handlers.has_key('/sub/plain')) - self.failUnless(disp._handlers.has_key('/exception_in_transfer')) - self.failUnless(disp._handlers.has_key('/plain')) - - def test_scan_dir_must_under_root(self): - dispatch.Dispatcher('a/b', 'a/b/c') # OK - dispatch.Dispatcher('a/b///', 'a/b') # OK - self.assertRaises(dispatch.DispatchError, - dispatch.Dispatcher, 'a/b/c', 'a/b') - - def test_resource_path_alias(self): - disp = dispatch.Dispatcher(_TEST_HANDLERS_DIR, None) - disp.add_resource_path_alias('/', '/origin_check') - self.assertEqual(4, len(disp._handlers)) - self.failUnless(disp._handlers.has_key('/origin_check')) - self.failUnless(disp._handlers.has_key('/sub/exception_in_transfer')) - self.failUnless(disp._handlers.has_key('/sub/plain')) - self.failUnless(disp._handlers.has_key('/')) - self.assertRaises(dispatch.DispatchError, - disp.add_resource_path_alias, '/alias', '/not-exist') - - -if __name__ == '__main__': - unittest.main() - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/test_handshake.py b/WebKitTools/pywebsocket/test/test_handshake.py deleted file mode 100644 index 8bf07be..0000000 --- a/WebKitTools/pywebsocket/test/test_handshake.py +++ /dev/null @@ -1,513 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Tests for handshake module.""" - - -import unittest - -import config # This must be imported before mod_pywebsocket. -from mod_pywebsocket import handshake - -import mock - - -_GOOD_REQUEST = ( - 80, - '/demo', - { - 'Upgrade':'WebSocket', - 'Connection':'Upgrade', - 'Host':'example.com', - 'Origin':'http://example.com', - 'WebSocket-Protocol':'sample', - } -) - -_GOOD_RESPONSE_DEFAULT_PORT = ( - 'HTTP/1.1 101 Web Socket Protocol Handshake\r\n' - 'Upgrade: WebSocket\r\n' - 'Connection: Upgrade\r\n' - 'WebSocket-Origin: http://example.com\r\n' - 'WebSocket-Location: ws://example.com/demo\r\n' - 'WebSocket-Protocol: sample\r\n' - '\r\n') - -_GOOD_RESPONSE_SECURE = ( - 'HTTP/1.1 101 Web Socket Protocol Handshake\r\n' - 'Upgrade: WebSocket\r\n' - 'Connection: Upgrade\r\n' - 'WebSocket-Origin: http://example.com\r\n' - 'WebSocket-Location: wss://example.com/demo\r\n' - 'WebSocket-Protocol: sample\r\n' - '\r\n') - -_GOOD_REQUEST_NONDEFAULT_PORT = ( - 8081, - '/demo', - { - 'Upgrade':'WebSocket', - 'Connection':'Upgrade', - 'Host':'example.com:8081', - 'Origin':'http://example.com', - 'WebSocket-Protocol':'sample', - } -) - -_GOOD_RESPONSE_NONDEFAULT_PORT = ( - 'HTTP/1.1 101 Web Socket Protocol Handshake\r\n' - 'Upgrade: WebSocket\r\n' - 'Connection: Upgrade\r\n' - 'WebSocket-Origin: http://example.com\r\n' - 'WebSocket-Location: ws://example.com:8081/demo\r\n' - 'WebSocket-Protocol: sample\r\n' - '\r\n') - -_GOOD_RESPONSE_SECURE_NONDEF = ( - 'HTTP/1.1 101 Web Socket Protocol Handshake\r\n' - 'Upgrade: WebSocket\r\n' - 'Connection: Upgrade\r\n' - 'WebSocket-Origin: http://example.com\r\n' - 'WebSocket-Location: wss://example.com:8081/demo\r\n' - 'WebSocket-Protocol: sample\r\n' - '\r\n') - -_GOOD_REQUEST_NO_PROTOCOL = ( - 80, - '/demo', - { - 'Upgrade':'WebSocket', - 'Connection':'Upgrade', - 'Host':'example.com', - 'Origin':'http://example.com', - } -) - -_GOOD_RESPONSE_NO_PROTOCOL = ( - 'HTTP/1.1 101 Web Socket Protocol Handshake\r\n' - 'Upgrade: WebSocket\r\n' - 'Connection: Upgrade\r\n' - 'WebSocket-Origin: http://example.com\r\n' - 'WebSocket-Location: ws://example.com/demo\r\n' - '\r\n') - -_GOOD_REQUEST_WITH_OPTIONAL_HEADERS = ( - 80, - '/demo', - { - 'Upgrade':'WebSocket', - 'Connection':'Upgrade', - 'Host':'example.com', - 'Origin':'http://example.com', - 'WebSocket-Protocol':'sample', - 'AKey':'AValue', - 'EmptyValue':'', - } -) - -_BAD_REQUESTS = ( - ( # HTTP request - 80, - '/demo', - { - 'Host':'www.google.com', - 'User-Agent':'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5;' - ' en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3' - ' GTB6 GTBA', - 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,' - '*/*;q=0.8', - 'Accept-Language':'en-us,en;q=0.5', - 'Accept-Encoding':'gzip,deflate', - 'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.7', - 'Keep-Alive':'300', - 'Connection':'keep-alive', - } - ), - ( # Missing Upgrade - 80, - '/demo', - { - 'Connection':'Upgrade', - 'Host':'example.com', - 'Origin':'http://example.com', - 'WebSocket-Protocol':'sample', - } - ), - ( # Wrong Upgrade - 80, - '/demo', - { - 'Upgrade':'NonWebSocket', - 'Connection':'Upgrade', - 'Host':'example.com', - 'Origin':'http://example.com', - 'WebSocket-Protocol':'sample', - } - ), - ( # Empty WebSocket-Protocol - 80, - '/demo', - { - 'Upgrade':'WebSocket', - 'Connection':'Upgrade', - 'Host':'example.com', - 'Origin':'http://example.com', - 'WebSocket-Protocol':'', - } - ), - ( # Wrong port number format - 80, - '/demo', - { - 'Upgrade':'WebSocket', - 'Connection':'Upgrade', - 'Host':'example.com:0x50', - 'Origin':'http://example.com', - 'WebSocket-Protocol':'sample', - } - ), - ( # Header/connection port mismatch - 8080, - '/demo', - { - 'Upgrade':'WebSocket', - 'Connection':'Upgrade', - 'Host':'example.com', - 'Origin':'http://example.com', - 'WebSocket-Protocol':'sample', - } - ), - ( # Illegal WebSocket-Protocol - 80, - '/demo', - { - 'Upgrade':'WebSocket', - 'Connection':'Upgrade', - 'Host':'example.com', - 'Origin':'http://example.com', - 'WebSocket-Protocol':'illegal\x09protocol', - } - ), -) - -_STRICTLY_GOOD_REQUESTS = ( - ( - 'GET /demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - '\r\n', - ), - ( # WebSocket-Protocol - 'GET /demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - 'WebSocket-Protocol: sample\r\n', - '\r\n', - ), - ( # WebSocket-Protocol and Cookie - 'GET /demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - 'WebSocket-Protocol: sample\r\n', - 'Cookie: xyz\r\n' - '\r\n', - ), - ( # Cookie - 'GET /demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - 'Cookie: abc/xyz\r\n' - 'Cookie2: $Version=1\r\n' - 'Cookie: abc\r\n' - '\r\n', - ), - ( - 'GET / HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - '\r\n', - ), -) - -_NOT_STRICTLY_GOOD_REQUESTS = ( - ( # Extra space after GET - 'GET /demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - '\r\n', - ), - ( # Resource name doesn't stat with '/' - 'GET demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - '\r\n', - ), - ( # No space after : - 'GET /demo HTTP/1.1\r\n', - 'Upgrade:WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - '\r\n', - ), - ( # Lower case Upgrade header - 'GET /demo HTTP/1.1\r\n', - 'upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - '\r\n', - ), - ( # Connection comes before Upgrade - 'GET /demo HTTP/1.1\r\n', - 'Connection: Upgrade\r\n', - 'Upgrade: WebSocket\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - '\r\n', - ), - ( # Origin comes before Host - 'GET /demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Origin: http://example.com\r\n', - 'Host: example.com\r\n', - '\r\n', - ), - ( # Host continued to the next line - 'GET /demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example\r\n', - ' .com\r\n', - 'Origin: http://example.com\r\n', - '\r\n', - ), - ( # Cookie comes before WebSocket-Protocol - 'GET /demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - 'Cookie: xyz\r\n' - 'WebSocket-Protocol: sample\r\n', - '\r\n', - ), - ( # Unknown header - 'GET /demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - 'Content-Type: text/html\r\n' - '\r\n', - ), - ( # Cookie with continuation lines - 'GET /demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - 'Cookie: xyz\r\n', - ' abc\r\n', - ' defg\r\n', - '\r\n', - ), - ( # Wrong-case cookie - 'GET /demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - 'cookie: abc/xyz\r\n' - '\r\n', - ), - ( # Cookie, no space after colon - 'GET /demo HTTP/1.1\r\n', - 'Upgrade: WebSocket\r\n', - 'Connection: Upgrade\r\n', - 'Host: example.com\r\n', - 'Origin: http://example.com\r\n', - 'Cookie:abc/xyz\r\n' - '\r\n', - ), -) - - -def _create_request(request_def): - conn = mock.MockConn('') - conn.local_addr = ('0.0.0.0', request_def[0]) - return mock.MockRequest( - uri=request_def[1], - headers_in=request_def[2], - connection=conn) - - -def _create_get_memorized_lines(lines): - def get_memorized_lines(): - return lines - return get_memorized_lines - - -def _create_requests_with_lines(request_lines_set): - requests = [] - for lines in request_lines_set: - request = _create_request(_GOOD_REQUEST) - request.connection.get_memorized_lines = _create_get_memorized_lines( - lines) - requests.append(request) - return requests - - -class HandshakerTest(unittest.TestCase): - def test_validate_protocol(self): - handshake._validate_protocol('sample') # should succeed. - handshake._validate_protocol('Sample') # should succeed. - handshake._validate_protocol('sample\x20protocol') # should succeed. - handshake._validate_protocol('sample\x7eprotocol') # should succeed. - self.assertRaises(handshake.HandshakeError, - handshake._validate_protocol, - '') - self.assertRaises(handshake.HandshakeError, - handshake._validate_protocol, - 'sample\x19protocol') - self.assertRaises(handshake.HandshakeError, - handshake._validate_protocol, - 'sample\x7fprotocol') - self.assertRaises(handshake.HandshakeError, - handshake._validate_protocol, - # "Japan" in Japanese - u'\u65e5\u672c') - - def test_good_request_default_port(self): - request = _create_request(_GOOD_REQUEST) - handshaker = handshake.Handshaker(request, - mock.MockDispatcher()) - handshaker.do_handshake() - self.assertEqual(_GOOD_RESPONSE_DEFAULT_PORT, - request.connection.written_data()) - self.assertEqual('/demo', request.ws_resource) - self.assertEqual('http://example.com', request.ws_origin) - self.assertEqual('ws://example.com/demo', request.ws_location) - self.assertEqual('sample', request.ws_protocol) - - def test_good_request_secure_default_port(self): - request = _create_request(_GOOD_REQUEST) - request.connection.local_addr = ('0.0.0.0', 443) - request.is_https_ = True - handshaker = handshake.Handshaker(request, - mock.MockDispatcher()) - handshaker.do_handshake() - self.assertEqual(_GOOD_RESPONSE_SECURE, - request.connection.written_data()) - self.assertEqual('sample', request.ws_protocol) - - def test_good_request_nondefault_port(self): - request = _create_request(_GOOD_REQUEST_NONDEFAULT_PORT) - handshaker = handshake.Handshaker(request, - mock.MockDispatcher()) - handshaker.do_handshake() - self.assertEqual(_GOOD_RESPONSE_NONDEFAULT_PORT, - request.connection.written_data()) - self.assertEqual('sample', request.ws_protocol) - - def test_good_request_secure_non_default_port(self): - request = _create_request(_GOOD_REQUEST_NONDEFAULT_PORT) - request.is_https_ = True - handshaker = handshake.Handshaker(request, - mock.MockDispatcher()) - handshaker.do_handshake() - self.assertEqual(_GOOD_RESPONSE_SECURE_NONDEF, - request.connection.written_data()) - self.assertEqual('sample', request.ws_protocol) - - def test_good_request_default_no_protocol(self): - request = _create_request(_GOOD_REQUEST_NO_PROTOCOL) - handshaker = handshake.Handshaker(request, - mock.MockDispatcher()) - handshaker.do_handshake() - self.assertEqual(_GOOD_RESPONSE_NO_PROTOCOL, - request.connection.written_data()) - self.assertEqual(None, request.ws_protocol) - - def test_good_request_optional_headers(self): - request = _create_request(_GOOD_REQUEST_WITH_OPTIONAL_HEADERS) - handshaker = handshake.Handshaker(request, - mock.MockDispatcher()) - handshaker.do_handshake() - self.assertEqual('AValue', - request.headers_in['AKey']) - self.assertEqual('', - request.headers_in['EmptyValue']) - - def test_bad_requests(self): - for request in map(_create_request, _BAD_REQUESTS): - handshaker = handshake.Handshaker(request, - mock.MockDispatcher()) - self.assertRaises(handshake.HandshakeError, handshaker.do_handshake) - - def test_strictly_good_requests(self): - for request in _create_requests_with_lines(_STRICTLY_GOOD_REQUESTS): - strict_handshaker = handshake.Handshaker(request, - mock.MockDispatcher(), - True) - strict_handshaker.do_handshake() - - def test_not_strictly_good_requests(self): - for request in _create_requests_with_lines(_NOT_STRICTLY_GOOD_REQUESTS): - strict_handshaker = handshake.Handshaker(request, - mock.MockDispatcher(), - True) - self.assertRaises(handshake.HandshakeError, - strict_handshaker.do_handshake) - - - -if __name__ == '__main__': - unittest.main() - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/test_memorizingfile.py b/WebKitTools/pywebsocket/test/test_memorizingfile.py deleted file mode 100644 index 2de77ba..0000000 --- a/WebKitTools/pywebsocket/test/test_memorizingfile.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Tests for memorizingfile module.""" - - -import StringIO -import unittest - -import config # This must be imported before mod_pywebsocket. -from mod_pywebsocket import memorizingfile - - -class UtilTest(unittest.TestCase): - def check(self, memorizing_file, num_read, expected_list): - for unused in range(num_read): - memorizing_file.readline() - actual_list = memorizing_file.get_memorized_lines() - self.assertEqual(len(expected_list), len(actual_list)) - for expected, actual in zip(expected_list, actual_list): - self.assertEqual(expected, actual) - - def test_get_memorized_lines(self): - memorizing_file = memorizingfile.MemorizingFile(StringIO.StringIO( - 'Hello\nWorld\nWelcome')) - self.check(memorizing_file, 3, ['Hello\n', 'World\n', 'Welcome']) - - def test_get_memorized_lines_limit_memorized_lines(self): - memorizing_file = memorizingfile.MemorizingFile(StringIO.StringIO( - 'Hello\nWorld\nWelcome'), 2) - self.check(memorizing_file, 3, ['Hello\n', 'World\n']) - - def test_get_memorized_lines_empty_file(self): - memorizing_file = memorizingfile.MemorizingFile(StringIO.StringIO( - '')) - self.check(memorizing_file, 10, []) - - -if __name__ == '__main__': - unittest.main() - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/test_mock.py b/WebKitTools/pywebsocket/test/test_mock.py deleted file mode 100644 index 8b137d1..0000000 --- a/WebKitTools/pywebsocket/test/test_mock.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Tests for mock module.""" - - -import Queue -import threading -import unittest - -import mock - - -class MockConnTest(unittest.TestCase): - def setUp(self): - self._conn = mock.MockConn('ABC\r\nDEFG\r\n\r\nHIJK') - - def test_readline(self): - self.assertEqual('ABC\r\n', self._conn.readline()) - self.assertEqual('DEFG\r\n', self._conn.readline()) - self.assertEqual('\r\n', self._conn.readline()) - self.assertEqual('HIJK', self._conn.readline()) - self.assertEqual('', self._conn.readline()) - - def test_read(self): - self.assertEqual('ABC\r\nD', self._conn.read(6)) - self.assertEqual('EFG\r\n\r\nHI', self._conn.read(9)) - self.assertEqual('JK', self._conn.read(10)) - self.assertEqual('', self._conn.read(10)) - - def test_read_and_readline(self): - self.assertEqual('ABC\r\nD', self._conn.read(6)) - self.assertEqual('EFG\r\n', self._conn.readline()) - self.assertEqual('\r\nHIJK', self._conn.read(9)) - self.assertEqual('', self._conn.readline()) - - def test_write(self): - self._conn.write('Hello\r\n') - self._conn.write('World\r\n') - self.assertEqual('Hello\r\nWorld\r\n', self._conn.written_data()) - - -class MockBlockingConnTest(unittest.TestCase): - def test_read(self): - class LineReader(threading.Thread): - def __init__(self, conn, queue): - threading.Thread.__init__(self) - self._queue = queue - self._conn = conn - self.setDaemon(True) - self.start() - def run(self): - while True: - data = self._conn.readline() - self._queue.put(data) - conn = mock.MockBlockingConn() - queue = Queue.Queue() - reader = LineReader(conn, queue) - self.failUnless(queue.empty()) - conn.put_bytes('Foo bar\r\n') - read = queue.get() - self.assertEqual('Foo bar\r\n', read) - - -class MockTableTest(unittest.TestCase): - def test_create_from_dict(self): - table = mock.MockTable({'Key':'Value'}) - self.assertEqual('Value', table.get('KEY')) - self.assertEqual('Value', table['key']) - - def test_create_from_list(self): - table = mock.MockTable([('Key', 'Value')]) - self.assertEqual('Value', table.get('KEY')) - self.assertEqual('Value', table['key']) - - def test_create_from_tuple(self): - table = mock.MockTable((('Key', 'Value'),)) - self.assertEqual('Value', table.get('KEY')) - self.assertEqual('Value', table['key']) - - def test_set_and_get(self): - table = mock.MockTable() - self.assertEqual(None, table.get('Key')) - table['Key'] = 'Value' - self.assertEqual('Value', table.get('Key')) - self.assertEqual('Value', table.get('key')) - self.assertEqual('Value', table.get('KEY')) - self.assertEqual('Value', table['Key']) - self.assertEqual('Value', table['key']) - self.assertEqual('Value', table['KEY']) - - -if __name__ == '__main__': - unittest.main() - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/test_msgutil.py b/WebKitTools/pywebsocket/test/test_msgutil.py deleted file mode 100644 index 16b88e0..0000000 --- a/WebKitTools/pywebsocket/test/test_msgutil.py +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Tests for msgutil module.""" - - -import Queue -import unittest - -import config # This must be imported before mod_pywebsocket. -from mod_pywebsocket import msgutil - -import mock - - -def _create_request(read_data): - return mock.MockRequest(connection=mock.MockConn(read_data)) - -def _create_blocking_request(): - return mock.MockRequest(connection=mock.MockBlockingConn()) - -class MessageTest(unittest.TestCase): - def test_send_message(self): - request = _create_request('') - msgutil.send_message(request, 'Hello') - self.assertEqual('\x00Hello\xff', request.connection.written_data()) - - def test_send_message_unicode(self): - request = _create_request('') - msgutil.send_message(request, u'\u65e5') - # U+65e5 is encoded as e6,97,a5 in UTF-8 - self.assertEqual('\x00\xe6\x97\xa5\xff', - request.connection.written_data()) - - def test_receive_message(self): - request = _create_request('\x00Hello\xff\x00World!\xff') - self.assertEqual('Hello', msgutil.receive_message(request)) - self.assertEqual('World!', msgutil.receive_message(request)) - - def test_receive_message_unicode(self): - request = _create_request('\x00\xe6\x9c\xac\xff') - # U+672c is encoded as e6,9c,ac in UTF-8 - self.assertEqual(u'\u672c', msgutil.receive_message(request)) - - def test_receive_message_erroneous_unicode(self): - # \x80 and \x81 are invalid as UTF-8. - request = _create_request('\x00\x80\x81\xff') - # Invalid characters should be replaced with - # U+fffd REPLACEMENT CHARACTER - self.assertEqual(u'\ufffd\ufffd', msgutil.receive_message(request)) - - def test_receive_message_discard(self): - request = _create_request('\x80\x06IGNORE\x00Hello\xff' - '\x01DISREGARD\xff\x00World!\xff') - self.assertEqual('Hello', msgutil.receive_message(request)) - self.assertEqual('World!', msgutil.receive_message(request)) - - def test_payload_length(self): - for length, bytes in ((0, '\x00'), (0x7f, '\x7f'), (0x80, '\x81\x00'), - (0x1234, '\x80\xa4\x34')): - self.assertEqual(length, - msgutil._payload_length(_create_request(bytes))) - - def test_receive_bytes(self): - request = _create_request('abcdefg') - self.assertEqual('abc', msgutil._receive_bytes(request, 3)) - self.assertEqual('defg', msgutil._receive_bytes(request, 4)) - - def test_read_until(self): - request = _create_request('abcXdefgX') - self.assertEqual('abc', msgutil._read_until(request, 'X')) - self.assertEqual('defg', msgutil._read_until(request, 'X')) - - -class MessageReceiverTest(unittest.TestCase): - def test_queue(self): - request = _create_blocking_request() - receiver = msgutil.MessageReceiver(request) - - self.assertEqual(None, receiver.receive_nowait()) - - request.connection.put_bytes('\x00Hello!\xff') - self.assertEqual('Hello!', receiver.receive()) - - def test_onmessage(self): - onmessage_queue = Queue.Queue() - def onmessage_handler(message): - onmessage_queue.put(message) - - request = _create_blocking_request() - receiver = msgutil.MessageReceiver(request, onmessage_handler) - - request.connection.put_bytes('\x00Hello!\xff') - self.assertEqual('Hello!', onmessage_queue.get()) - - -class MessageSenderTest(unittest.TestCase): - def test_send(self): - request = _create_blocking_request() - sender = msgutil.MessageSender(request) - - sender.send('World') - self.assertEqual('\x00World\xff', request.connection.written_data()) - - def test_send_nowait(self): - # Use a queue to check the bytes written by MessageSender. - # request.connection.written_data() cannot be used here because - # MessageSender runs in a separate thread. - send_queue = Queue.Queue() - def write(bytes): - send_queue.put(bytes) - request = _create_blocking_request() - request.connection.write = write - - sender = msgutil.MessageSender(request) - - sender.send_nowait('Hello') - sender.send_nowait('World') - self.assertEqual('\x00Hello\xff', send_queue.get()) - self.assertEqual('\x00World\xff', send_queue.get()) - - -if __name__ == '__main__': - unittest.main() - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/test_util.py b/WebKitTools/pywebsocket/test/test_util.py deleted file mode 100644 index 83e2635..0000000 --- a/WebKitTools/pywebsocket/test/test_util.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Tests for util module.""" - - -import unittest - -import config # This must be imported before mod_pywebsocket. -from mod_pywebsocket import util - - -class UtilTest(unittest.TestCase): - def test_get_stack_trace(self): - self.assertEqual('None\n', util.get_stack_trace()) - try: - a = 1 / 0 # Intentionally raise exception. - except Exception: - trace = util.get_stack_trace() - self.failUnless(trace.startswith('Traceback')) - self.failUnless(trace.find('ZeroDivisionError') != -1) - - def test_prepend_message_to_exception(self): - exc = Exception('World') - self.assertEqual('World', str(exc)) - util.prepend_message_to_exception('Hello ', exc) - self.assertEqual('Hello World', str(exc)) - - -if __name__ == '__main__': - unittest.main() - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/testdata/handlers/blank_wsh.py b/WebKitTools/pywebsocket/test/testdata/handlers/blank_wsh.py deleted file mode 100644 index 7f87c6a..0000000 --- a/WebKitTools/pywebsocket/test/testdata/handlers/blank_wsh.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -# intentionally left blank diff --git a/WebKitTools/pywebsocket/test/testdata/handlers/origin_check_wsh.py b/WebKitTools/pywebsocket/test/testdata/handlers/origin_check_wsh.py deleted file mode 100644 index 2c139fa..0000000 --- a/WebKitTools/pywebsocket/test/testdata/handlers/origin_check_wsh.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -def web_socket_do_extra_handshake(request): - if request.ws_origin == 'http://example.com': - return - raise ValueError('Unacceptable origin: %r' % request.ws_origin) - - -def web_socket_transfer_data(request): - request.connection.write('origin_check_wsh.py is called for %s, %s' % - (request.ws_resource, request.ws_protocol)) - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/testdata/handlers/sub/exception_in_transfer_wsh.py b/WebKitTools/pywebsocket/test/testdata/handlers/sub/exception_in_transfer_wsh.py deleted file mode 100644 index b982d02..0000000 --- a/WebKitTools/pywebsocket/test/testdata/handlers/sub/exception_in_transfer_wsh.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Exception in web_socket_transfer_data(). -""" - - -def web_socket_do_extra_handshake(request): - pass - - -def web_socket_transfer_data(request): - raise Exception('Intentional Exception for %s, %s' % - (request.ws_resource, request.ws_protocol)) - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/testdata/handlers/sub/no_wsh_at_the_end.py b/WebKitTools/pywebsocket/test/testdata/handlers/sub/no_wsh_at_the_end.py deleted file mode 100644 index 17e7be1..0000000 --- a/WebKitTools/pywebsocket/test/testdata/handlers/sub/no_wsh_at_the_end.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Correct signatures, wrong file name. -""" - - -def web_socket_do_extra_handshake(request): - pass - - -def web_socket_transfer_data(request): - request.connection.write( - 'sub/no_wsh_at_the_end.py is called for %s, %s' % - (request.ws_resource, request.ws_protocol)) - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/testdata/handlers/sub/non_callable_wsh.py b/WebKitTools/pywebsocket/test/testdata/handlers/sub/non_callable_wsh.py deleted file mode 100644 index 26352eb..0000000 --- a/WebKitTools/pywebsocket/test/testdata/handlers/sub/non_callable_wsh.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Non-callable handlers. -""" - - -web_socket_do_extra_handshake = True -web_socket_transfer_data = 1 - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/testdata/handlers/sub/plain_wsh.py b/WebKitTools/pywebsocket/test/testdata/handlers/sub/plain_wsh.py deleted file mode 100644 index db3ff69..0000000 --- a/WebKitTools/pywebsocket/test/testdata/handlers/sub/plain_wsh.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -def web_socket_do_extra_handshake(request): - pass - - -def web_socket_transfer_data(request): - request.connection.write('sub/plain_wsh.py is called for %s, %s' % - (request.ws_resource, request.ws_protocol)) - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/testdata/handlers/sub/wrong_handshake_sig_wsh.py b/WebKitTools/pywebsocket/test/testdata/handlers/sub/wrong_handshake_sig_wsh.py deleted file mode 100644 index 6bf659b..0000000 --- a/WebKitTools/pywebsocket/test/testdata/handlers/sub/wrong_handshake_sig_wsh.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Wrong web_socket_do_extra_handshake signature. -""" - - -def no_web_socket_do_extra_handshake(request): - pass - - -def web_socket_transfer_data(request): - request.connection.write( - 'sub/wrong_handshake_sig_wsh.py is called for %s, %s' % - (request.ws_resource, request.ws_protocol)) - - -# vi:sts=4 sw=4 et diff --git a/WebKitTools/pywebsocket/test/testdata/handlers/sub/wrong_transfer_sig_wsh.py b/WebKitTools/pywebsocket/test/testdata/handlers/sub/wrong_transfer_sig_wsh.py deleted file mode 100644 index e0e2e55..0000000 --- a/WebKitTools/pywebsocket/test/testdata/handlers/sub/wrong_transfer_sig_wsh.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2009, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""Wrong web_socket_transfer_data() signature. -""" - - -def web_socket_do_extra_handshake(request): - pass - - -def no_web_socket_transfer_data(request): - request.connection.write( - 'sub/wrong_transfer_sig_wsh.py is called for %s, %s' % - (request.ws_resource, request.ws_protocol)) - - -# vi:sts=4 sw=4 et |