Переглянути джерело

Fix handler ordering (symptom: tail handler and maintailhandler never checked), and test.

Chris McDonough 17 роки тому
батько
коміт
4aa36349f8

+ 3 - 1
src/supervisor/http.py

@@ -825,9 +825,11 @@ def make_http_servers(options, supervisord):
             options.logger.critical(
                 'Server %r running without any HTTP '
                 'authentication checking' % config['section'])
+        # uihandler must be consulted last as its match method matches
+        # everything, so it's first here (indicating last checked)
+        hs.install_handler(uihandler)
         hs.install_handler(maintailhandler)
         hs.install_handler(tailhandler)
-        hs.install_handler(uihandler) # second-to-last for speed
         hs.install_handler(xmlrpchandler) # last for speed (first checked)
         servers.append((config, hs))
 

+ 5 - 0
src/supervisor/tests/base.py

@@ -556,6 +556,11 @@ class DummyRequest:
     def log(self, *arg, **kw):
         pass
 
+class DummyRPCInterfaceFactory:
+    def __init__(self, supervisord, **config):
+        self.supervisord = supervisord
+        self.config = config
+
 class DummyRPCServer:
     def __init__(self):
         self.supervisor = DummySupervisorRPCNamespace()

+ 64 - 0
src/supervisor/tests/test_http.py

@@ -1,8 +1,12 @@
 import sys
+import os
+import socket
+import tempfile
 import unittest
 
 from supervisor.tests.base import DummySupervisor
 from supervisor.tests.base import PopulatedDummySupervisor
+from supervisor.tests.base import DummyRPCInterfaceFactory
 from supervisor.tests.base import DummyPConfig
 from supervisor.tests.base import DummyOptions
 from supervisor.tests.base import DummyRequest
@@ -247,6 +251,66 @@ class DeferringHookedProducerTests(unittest.TestCase):
         self.assertEqual(producer.more(), '')
         self.assertEqual(L, [0])
 
+class TopLevelFunctionTests(unittest.TestCase):
+    def _make_http_servers(self, sconfigs):
+        options = DummyOptions()
+        options.server_configs = sconfigs
+        options.rpcinterface_factories = [('dummy',DummyRPCInterfaceFactory,{})]
+        supervisord = DummySupervisor()
+        from supervisor.http import make_http_servers
+        try:
+            servers = make_http_servers(options, supervisord)
+            for s in servers:
+                try:
+                    s.close()
+                except:
+                    pass
+            return servers
+        finally:
+            from asyncore import socket_map
+            socket_map.clear()
+            try:
+                os.unlink(socketfile)
+            except:
+                pass
+        
+    def test_make_http_servers_noauth(self):
+        socketfile = tempfile.mktemp()
+        inet = {'family':socket.AF_INET, 'host':'localhost', 'port':17735,
+                'username':None, 'password':None, 'section':'inet_http_server'}
+        unix = {'family':socket.AF_UNIX, 'file':socketfile, 'chmod':0700,
+                'chown':(-1, -1), 'username':None, 'password':None,
+                'section':'unix_http_server'}
+        servers = self._make_http_servers([inet, unix])
+        self.assertEqual(len(servers), 2)
+
+        inetdata = servers[0]
+        self.assertEqual(inetdata[0], inet)
+        server = inetdata[1]
+        paths = ['/RPC2', '/logtail', '/mainlogtail', '']
+        self.assertEqual([x.path for x in server.handlers], paths)
+
+        unixdata = servers[1]
+        self.assertEqual(unixdata[0], unix)
+        server = unixdata[1]
+        paths = ['/RPC2', '/logtail', '/mainlogtail', '']
+        self.assertEqual([x.path for x in server.handlers], paths)
+
+    def test_make_http_servers_withauth(self):
+        socketfile = tempfile.mktemp()
+        inet = {'family':socket.AF_INET, 'host':'localhost', 'port':17736,
+                'username':'username', 'password':'password',
+                'section':'inet_http_server'}
+        unix = {'family':socket.AF_UNIX, 'file':socketfile, 'chmod':0700,
+                'chown':(-1, -1), 'username':'username', 'password':'password',
+                'section':'unix_http_server'}
+        servers = self._make_http_servers([inet, unix])
+        self.assertEqual(len(servers), 2)
+        from medusa.auth_handler import auth_handler
+        for config, server in servers:
+            for handler in server.handlers:
+                self.failUnless(isinstance(handler, auth_handler), handler)
+
 class DummyProducer:
     def __init__(self, *data):
         self.data = list(data)

+ 4 - 0
src/supervisor/web.py

@@ -525,11 +525,15 @@ VIEWS = {
 
 class supervisor_ui_handler(default_handler.default_handler):
     IDENT = 'Supervisor Web UI HTTP Request Handler'
+    path = ''
 
     def __init__(self, filesystem, supervisord):
         self.supervisord = supervisord
         default_handler.default_handler.__init__(self, filesystem)
 
+    def match(self, request):
+        return request.uri.startswith(self.path)
+
     def get_view(self, request):
         path, params, query, fragment = request.split_uri()
 

+ 2 - 1
src/supervisor/xmlrpc.py

@@ -318,6 +318,7 @@ class RootRPCInterface:
             setattr(self, name, rpcinterface)
 
 class supervisor_xmlrpc_handler(xmlrpc_handler):
+    path = '/RPC2'
     def __init__(self, supervisord, subinterfaces):
         self.rpcinterface = RootRPCInterface(subinterfaces)
         self.supervisord = supervisord
@@ -331,7 +332,7 @@ class supervisor_xmlrpc_handler(xmlrpc_handler):
             self.loads = xmlrpclib.loads
 
     def match(self, request):
-        return request.uri.startswith('/RPC2')
+        return request.uri.startswith(self.path)
         
     def continue_request (self, data, request):
         logger = self.supervisord.options.logger