summaryrefslogtreecommitdiffstats
path: root/WebKitTools/pywebsocket/mod_pywebsocket/dispatch.py
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-04-27 16:31:00 +0100
committerSteve Block <steveblock@google.com>2010-05-11 14:42:12 +0100
commitdcc8cf2e65d1aa555cce12431a16547e66b469ee (patch)
tree92a8d65cd5383bca9749f5327fb5e440563926e6 /WebKitTools/pywebsocket/mod_pywebsocket/dispatch.py
parentccac38a6b48843126402088a309597e682f40fe6 (diff)
downloadexternal_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/mod_pywebsocket/dispatch.py')
-rw-r--r--WebKitTools/pywebsocket/mod_pywebsocket/dispatch.py231
1 files changed, 0 insertions, 231 deletions
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