2009-10-26 Yuzo Fujishima <yuzo@google.com>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Oct 2009 22:10:26 +0000 (22:10 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Oct 2009 22:10:26 +0000 (22:10 +0000)
        Reviewed by Eric Seidel.

        Upgrade pywebsocket to 0.4.1. This will make reusing LayoutTests/fast/js/resources easier, for example.

        https://bugs.webkit.org/show_bug.cgi?id=30763

        * pywebsocket/mod_pywebsocket/__init__.py:
        * pywebsocket/mod_pywebsocket/dispatch.py:
        * pywebsocket/mod_pywebsocket/headerparserhandler.py:
        * pywebsocket/mod_pywebsocket/standalone.py:
        * pywebsocket/setup.py:
        * pywebsocket/test/test_dispatch.py:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@50102 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKitTools/ChangeLog
WebKitTools/pywebsocket/mod_pywebsocket/__init__.py
WebKitTools/pywebsocket/mod_pywebsocket/dispatch.py
WebKitTools/pywebsocket/mod_pywebsocket/headerparserhandler.py
WebKitTools/pywebsocket/mod_pywebsocket/standalone.py
WebKitTools/pywebsocket/setup.py
WebKitTools/pywebsocket/test/test_dispatch.py

index 87475a9..29f2fb1 100644 (file)
@@ -1,3 +1,18 @@
+2009-10-26  Yuzo Fujishima  <yuzo@google.com>
+
+        Reviewed by Eric Seidel.
+
+        Upgrade pywebsocket to 0.4.1. This will make reusing LayoutTests/fast/js/resources easier, for example.
+
+        https://bugs.webkit.org/show_bug.cgi?id=30763
+
+        * pywebsocket/mod_pywebsocket/__init__.py:
+        * pywebsocket/mod_pywebsocket/dispatch.py:
+        * pywebsocket/mod_pywebsocket/headerparserhandler.py:
+        * pywebsocket/mod_pywebsocket/standalone.py:
+        * pywebsocket/setup.py:
+        * pywebsocket/test/test_dispatch.py:
+
 2009-10-26  Carol Szabo  <carol.szabo@nokia.com>
 
         Reviewed by David Levin.
index 8acd133..beacc9e 100644 (file)
@@ -51,6 +51,14 @@ Installation:
        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.)
index 908b0b4..84422eb 100644 (file)
@@ -119,17 +119,27 @@ class Dispatcher(object):
     This class maintains a map from resource name to handlers.
     """
 
-    def __init__(self, root_dir):
+    def __init__(self, root_dir, scan_dir=None):
         """Construct an instance.
 
         Args:
             root_dir: The directory where handler definition files are
-            placed.
+                      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 = []
-        self._source_files_in_dir(root_dir)
+        if scan_dir is None:
+            scan_dir = root_dir
+        if not os.path.abspath(scan_dir).startswith(os.path.abspath(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 source_warnings(self):
         """Return warnings in sourcing handlers."""
@@ -176,11 +186,14 @@ class Dispatcher(object):
         except KeyError:
             raise DispatchError('No handler for: %r' % request.ws_resource)
 
-    def _source_files_in_dir(self, root_dir):
-        """Source all the handler source files in the directory."""
+    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(root_dir):
+        for path in _source_file_paths(scan_dir):
             try:
                 handlers = _source(open(path).read())
             except DispatchError, e:
index c38a1de..124b9f1 100644 (file)
@@ -45,6 +45,11 @@ 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(
@@ -52,7 +57,9 @@ def _create_dispatcher():
     if not _HANDLER_ROOT:
         raise Exception('PythonOption %s is not defined' % _PYOPT_HANDLER_ROOT,
                         apache.APLOG_ERR)
-    dispatcher = dispatch.Dispatcher(_HANDLER_ROOT)
+    _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
index b7874fa..a4c142b 100644 (file)
@@ -36,6 +36,7 @@ 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>]
 
 <ws_port> is the port number to use for ws:// connection.
@@ -46,6 +47,9 @@ Usage:
 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.
@@ -162,7 +166,8 @@ class WebSocketRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
         self._request = _StandaloneRequest(
                 self, WebSocketRequestHandler.options.use_tls)
         self._dispatcher = dispatch.Dispatcher(
-                WebSocketRequestHandler.options.websock_handlers)
+                WebSocketRequestHandler.options.websock_handlers,
+                WebSocketRequestHandler.options.scan_dir)
         self._print_warnings_if_any()
         self._handshaker = handshake.Handshaker(self._request,
                                                 self._dispatcher)
@@ -206,6 +211,10 @@ def _main():
     parser.add_option('-w', '--websock_handlers', dest='websock_handlers',
                       default='.',
                       help='Web Socket handlers root directory.')
+    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.')
@@ -226,6 +235,9 @@ def _main():
                                  'certificate.')
             sys.exit(1)
 
+    if not options.scan_dir:
+        options.scan_dir = options.websock_handlers
+
     WebSocketRequestHandler.options = options
     WebSocketServer.options = options
 
index 8309eec..1810a6d 100644 (file)
@@ -56,7 +56,7 @@ setup(author='Yuzo Fujishima',
       name=_PACKAGE_NAME,
       packages=[_PACKAGE_NAME],
       url='http://code.google.com/p/pywebsocket/',
-      version='0.4.0',
+      version='0.4.1',
       )
 
 
index e2585c8..d617205 100644 (file)
@@ -46,6 +46,8 @@ 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('\\', '/'),
@@ -106,7 +108,7 @@ class DispatcherTest(unittest.TestCase):
                 'def web_socket_transfer_data(request):pass\n'))
 
     def test_source_warnings(self):
-        dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR)
+        dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR, None)
         warnings = dispatcher.source_warnings()
         warnings.sort()
         expected_warnings = [
@@ -126,8 +128,8 @@ class DispatcherTest(unittest.TestCase):
         for expected, actual in zip(expected_warnings, warnings):
             self.assertEquals(expected, actual)
 
-    def test_shake_hand(self):
-        dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR)
+    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'
@@ -138,7 +140,7 @@ class DispatcherTest(unittest.TestCase):
                           dispatcher.do_extra_handshake, request)
 
     def test_transfer_data(self):
-        dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR)
+        dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR, None)
         request = mock.MockRequest(connection=mock.MockConn(''))
         request.ws_resource = '/origin_check'
         request.ws_protocol = 'p1'
@@ -155,7 +157,7 @@ class DispatcherTest(unittest.TestCase):
                          request.connection.written_data())
 
     def test_transfer_data_no_handler(self):
-        dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR)
+        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(''))
@@ -170,7 +172,7 @@ class DispatcherTest(unittest.TestCase):
                 self.fail()
 
     def test_transfer_data_handler_exception(self):
-        dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR)
+        dispatcher = dispatch.Dispatcher(_TEST_HANDLERS_DIR, None)
         request = mock.MockRequest(connection=mock.MockConn(''))
         request.ws_resource = '/sub/exception_in_transfer'
         request.ws_protocol = 'p3'
@@ -182,6 +184,36 @@ class DispatcherTest(unittest.TestCase):
         except Exception:
             self.fail()
 
+    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')
+
 
 if __name__ == '__main__':
     unittest.main()