[CalendarServer-changes] [4573] CalendarServer/branches/users/sagen/deployment-inherit-fds-4571

source_changes at macosforge.org source_changes at macosforge.org
Mon Oct 5 10:56:49 PDT 2009


Revision: 4573
          http://trac.macosforge.org/projects/calendarserver/changeset/4573
Author:   sagen at apple.com
Date:     2009-10-05 10:56:49 -0700 (Mon, 05 Oct 2009)
Log Message:
-----------
Applying my changes to new inherit-fd branch

Modified Paths:
--------------
    CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/memcacheclient.py
    CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/accesslog.py
    CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/cluster.py
    CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/config.py
    CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/directory/appleopendirectory.py
    CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/httpfactory.py
    CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/tap.py

Modified: CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/memcacheclient.py
===================================================================
--- CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/memcacheclient.py	2009-10-05 17:53:50 UTC (rev 4572)
+++ CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/memcacheclient.py	2009-10-05 17:56:49 UTC (rev 4573)
@@ -550,6 +550,19 @@
 
 
         """
+        # Short-circuit:
+        key_list = list(key_iterable)
+        server, ignored = self._get_server(key_list[0])
+        server_keys = {
+            server : key_list,
+        }
+        prefixed_to_orig_key = { }
+        for key in key_list:
+            prefixed_to_orig_key[key] = key
+        return (server_keys, prefixed_to_orig_key)
+
+
+
         # Check it just once ...
         key_extra_len=len(key_prefix)
         if key_prefix:

Modified: CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/accesslog.py
===================================================================
--- CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/accesslog.py	2009-10-05 17:53:50 UTC (rev 4572)
+++ CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/accesslog.py	2009-10-05 17:56:49 UTC (rev 4573)
@@ -117,7 +117,10 @@
             )
 
             try:
-                serverInstance = request.chanRequest.transport.server.port
+                if config.EnableConnectionInheriting:
+                    serverInstance = config.LogID
+                else:
+                    serverInstance = request.chanRequest.transport.server.port
             except AttributeError:
                 serverInstance = "Unknown"
             if config.EnableExtendedAccessLog:

Modified: CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/cluster.py
===================================================================
--- CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/cluster.py	2009-10-05 17:53:50 UTC (rev 4572)
+++ CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/cluster.py	2009-10-05 17:56:49 UTC (rev 4573)
@@ -17,6 +17,8 @@
 import os
 import sys
 import tempfile
+import socket
+import time
 
 from twisted.runner import procmon
 from twisted.application import internet, service
@@ -54,17 +56,24 @@
 class TwistdSlaveProcess(object):
     prefix = "caldav"
 
-    def __init__(self, twistd, tapname, configFile,
-                 interfaces, port, sslPort):
+    def __init__(self, twistd, tapname, configFile, id,
+                 interfaces, port, sslPort,
+                 inheritFDs=None, inheritSSLFDs=None):
+
         self.twistd = twistd
 
         self.tapname = tapname
 
         self.configFile = configFile
 
+        self.id = id
+
         self.ports = port
         self.sslPorts = sslPort
 
+        self.inheritFDs = inheritFDs
+        self.inheritSSLFDs = inheritSSLFDs
+
         self.interfaces = interfaces
 
     def getName(self):
@@ -72,6 +81,8 @@
             return '%s-%s' % (self.prefix, self.ports[0])
         elif self.sslPorts is not None:
             return '%s-%s' % (self.prefix, self.sslPorts[0])
+        elif self.inheritFDs or self.inheritSSLFDs:
+            return '%s-%s' % (self.prefix, self.id)
 
         raise ConfigurationError(
             "Can't create TwistdSlaveProcess without a TCP Port")
@@ -101,6 +112,7 @@
              '-o', 'BindAddresses=%s' % (','.join(self.interfaces),),
              '-o', 'PIDFile=None',
              '-o', 'ErrorLogFile=None',
+             '-o', 'LogID=%s' % (self.id,),
              '-o', 'MultiProcess/ProcessCount=%d' % (
                     config.MultiProcess['ProcessCount'],)])
 
@@ -118,9 +130,16 @@
                     '-o',
                     'BindSSLPorts=%s' % (','.join(map(str, self.sslPorts)),)])
 
+        if self.inheritFDs:
+            args.extend([
+                    '-o',
+                    'InheritFDs=%s' % (','.join(map(str, self.inheritFDs)),)])
 
+        if self.inheritSSLFDs:
+            args.extend([
+                    '-o',
+                    'InheritSSLFDs=%s' % (','.join(map(str, self.inheritSSLFDs)),)])
 
-
         return args
 
     def getHostLine(self, ssl=False):
@@ -133,6 +152,9 @@
         if ssl and self.sslPorts is not None:
             port = self.sslPorts
 
+        if self.inheritFDs or self.inheritSSLFDs:
+            port = [self.id]
+
         if port is None:
             raise ConfigurationError(
                 "Can not add a host without a port")
@@ -186,6 +208,28 @@
         except process.ProcessExitedAlready:
             pass
 
+    def startProcess(self, name):
+        if self.protocols.has_key(name):
+            return
+        p = self.protocols[name] = procmon.LoggingProtocol()
+        p.service = self
+        p.name = name
+        args, uid, gid, env = self.processes[name]
+        self.timeStarted[name] = time.time()
+
+        childFDs = { 0 : "w", 1 : "r", 2 : "r" }
+
+        # Examine args for -o InheritFDs= and -o InheritSSLFDs=
+        # Add any file descriptors listed in those args to the childFDs
+        # dictionary so those don't get closed across the spawn.
+        for i in xrange(len(args)-1):
+            if args[i] == "-o" and args[i+1].startswith("Inherit"):
+                for fd in map(int, args[i+1].split("=")[1].split(",")):
+                    childFDs[fd] = fd
+
+        reactor.spawnProcess(p, args[0], args, uid=uid, gid=gid, env=env,
+            childFDs=childFDs)
+
 def makeService_Combined(self, options):
     s = service.MultiService()
     monitor = DelayedStartupProcessMonitor()
@@ -205,6 +249,9 @@
 
     bindAddress = ['127.0.0.1']
 
+    inheritFDs = []
+    inheritSSLFDs = []
+
     # Attempt to calculate the number of processes to use
     # 1 per processor
 
@@ -234,19 +281,68 @@
         if config.BindSSLPorts:
             sslPort = config.BindSSLPorts
 
+
     if port[0] == 0:
         port = None
 
     if sslPort[0] == 0:
         sslPort = None
 
-    # If the load balancer isn't enabled, or if we only have one process
-    # We listen directly on the interfaces.
+    # If we only have one process, disable the software load balancer and
+    # listen directly on the interfaces.
 
-    if ((not config.MultiProcess['LoadBalancer']['Enabled']) or
-        (config.MultiProcess['ProcessCount'] == 1)):
+    if config.MultiProcess['ProcessCount'] == 1:
+        config.MultiProcess['LoadBalancer']['Enabled'] = False
         bindAddress = config.BindAddresses
 
+    elif config.EnableConnectionInheriting:
+        # Open the socket(s) to be inherited by the slaves
+
+        config.MultiProcess['LoadBalancer']['Enabled'] = False
+
+        if not config.BindAddresses:
+            config.BindAddresses = [""]
+
+        s._inheritedSockets = [] # keep a reference to these so they don't close
+
+        for bindAddress in config.BindAddresses:
+            if config.BindHTTPPorts:
+                if config.HTTPPort == 0:
+                    raise UsageError(
+                        "HTTPPort required if BindHTTPPorts is not empty"
+                    )
+            elif config.HTTPPort != 0:
+                config.BindHTTPPorts = [config.HTTPPort]
+
+            if config.BindSSLPorts:
+                if config.SSLPort == 0:
+                    raise UsageError(
+                        "SSLPort required if BindSSLPorts is not empty"
+                    )
+            elif config.SSLPort != 0:
+                config.BindSSLPorts = [config.SSLPort]
+
+            def _openSocket(addr, port):
+                log.info("Opening socket for inheritance at %s:%d" % (addr, port))
+                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+                sock.setblocking(0)
+                sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+                sock.bind((addr, port))
+                sock.listen(config.ListenBacklog)
+                s._inheritedSockets.append(sock)
+                return sock
+
+            for portNum in config.BindHTTPPorts:
+                sock = _openSocket(bindAddress, int(portNum))
+                inheritFDs.append(sock.fileno())
+
+            for portNum in config.BindSSLPorts:
+                sock = _openSocket(bindAddress, int(portNum))
+                inheritSSLFDs.append(sock.fileno())
+
+    if not config.MultiProcess['LoadBalancer']['Enabled']:
+        bindAddress = config.BindAddresses
+
     for p in xrange(0, config.MultiProcess['ProcessCount']):
         if config.MultiProcess['ProcessCount'] > 1:
             if port is not None:
@@ -255,11 +351,21 @@
             if sslPort is not None:
                 sslPort = [sslPort[0] + 1]
 
+        if inheritFDs:
+            port = None
+
+        if inheritSSLFDs:
+            sslPort = None
+
         process = TwistdSlaveProcess(config.Twisted['twistd'],
                                      self.tapname,
                                      options['config'],
+                                     p,
                                      bindAddress,
-                                     port, sslPort)
+                                     port, sslPort,
+                                     inheritFDs=inheritFDs,
+                                     inheritSSLFDs=inheritSSLFDs
+                                     )
 
         monitor.addProcess(process.getName(),
                            process.getCommandLine(),
@@ -340,8 +446,6 @@
                                      config.PythonDirector['pydir'],
                                      fname],
                            env=parentEnv)
-
-
     if config.Memcached["ServerEnabled"]:
         log.msg("Adding memcached service")
 

Modified: CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/config.py
===================================================================
--- CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/config.py	2009-10-05 17:53:50 UTC (rev 4572)
+++ CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/config.py	2009-10-05 17:56:49 UTC (rev 4573)
@@ -100,6 +100,9 @@
     "BindAddresses": [],   # List of IP addresses to bind to [empty = all]
     "BindHTTPPorts": [],   # List of port numbers to bind to for HTTP [empty = same as "Port"]
     "BindSSLPorts" : [],   # List of port numbers to bind to for SSL [empty = same as "SSLPort"]
+    "EnableConnectionInheriting" : False,
+    "InheritFDs"   : [],   # File descriptors to inherit for HTTP requests (empty = don't inherit)
+    "InheritSSLFDs": [],   # File descriptors to inherit for HTTPS requests (empty = don't inherit)
 
     #
     # Data store
@@ -168,6 +171,7 @@
     "EnableExtendedAccessLog" : True,
     "DefaultLogLevel"   : "",
     "LogLevels"         : {},
+    "LogID"          : "",
 
     "AccountingCategories": {
         "iTIP": False,
@@ -259,6 +263,7 @@
 
     # Set the maximum number of outstanding requests to this server.
     "MaxRequests": 600,
+    "ResumeRequests": 550,
 
     "ListenBacklog": 50,
     "IdleConnectionTimeOut": 15,

Modified: CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/directory/appleopendirectory.py	2009-10-05 17:53:50 UTC (rev 4572)
+++ CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/directory/appleopendirectory.py	2009-10-05 17:56:49 UTC (rev 4573)
@@ -33,7 +33,14 @@
 import opendirectory
 import dsattributes
 import dsquery
+import memcacheclient
 
+try:
+    from hashlib import md5
+except ImportError:
+    from md5 import new as md5
+
+
 from twisted.internet.reactor import callLater
 from twisted.internet.threads import deferToThread
 from twisted.cred.credentials import UsernamePassword
@@ -174,6 +181,14 @@
             h = (h + hash(getattr(self, attr))) & sys.maxint
         return h
 
+    def _getMemcacheClient(self, refresh=False):
+        if refresh or not hasattr(self, "memcacheClient"):
+            self.memcacheClient = memcacheclient.ClientFactory.getClient(['%s:%s' %
+                (config.Memcached.BindAddress, config.Memcached.Port)],
+                debug=0, pickleProtocol=2)
+        return self.memcacheClient
+
+
     def _lookupVHostRecord(self):
         """
         Get the OD service record for this host.
@@ -1087,20 +1102,36 @@
         result.update(self.service.readOnlyProxiesForGUID(DirectoryService.recordType_locations, self.guid))
         return result
 
+
+    def getMemcacheKey(self, shortName):
+        key = "auth-%s" % (md5(shortName).hexdigest(),)
+        return key
+
     def verifyCredentials(self, credentials):
         if isinstance(credentials, UsernamePassword):
-            # Check cached password
+            # Check cached password which is an md5 hexdigest
+
+            credPassword = md5(credentials.password).hexdigest()
             try:
-                if credentials.password == self.password:
+                if credPassword == self.password:
                     return True
             except AttributeError:
-                pass
+                # No locally stored password; check memcached
+                key = self.getMemcacheKey(self.shortName)
+                memcachePassword = self.service._getMemcacheClient().get(key)
+                if memcachePassword is not None:
+                    if credPassword == memcachePassword:
+                        # Memcached version matches, store locally
+                        self.password = credPassword
+                        return True
 
-            # Check with directory services
+            # No local version, *or* local version differs; check directory services
             try:
                 if opendirectory.authenticateUserBasic(self.service.directory, self.nodeName, self.shortName, credentials.password):
                     # Cache the password to avoid future DS queries
-                    self.password = credentials.password
+                    self.password = credPassword
+                    key = self.getMemcacheKey(self.shortName)
+                    self.service._getMemcacheClient().set(key, self.password, time=self.service.cacheTimeout*60)
                     return True
             except opendirectory.ODError, e:
                 self.log_error("Open Directory (node=%s) error while performing basic authentication for user %s: %s"

Modified: CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/httpfactory.py
===================================================================
--- CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/httpfactory.py	2009-10-05 17:53:50 UTC (rev 4572)
+++ CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/httpfactory.py	2009-10-05 17:56:49 UTC (rev 4573)
@@ -18,7 +18,7 @@
 
 from twisted.internet import protocol
 from twisted.python import log
-from twisted.web2.channel.http import HTTPFactory
+from twisted.web2.channel.http import HTTPFactory, HTTPChannel
 
 from twistedcaldav.config import config
 
@@ -61,3 +61,33 @@
         for arg,value in self.protocolArgs.iteritems():
             setattr(p, arg, value)
         return p
+
+
+class LimitingHTTPChannel(HTTPChannel):
+
+    def connectionMade(self):
+        HTTPChannel.connectionMade(self)
+        if self.factory.outstandingRequests >= self.factory.maxRequests:
+            # log.msg("Overloaded")
+            self.factory.myServer.myPort.stopReading()
+
+    def connectionLost(self, reason):
+        HTTPChannel.connectionLost(self, reason)
+        if self.factory.outstandingRequests < self.factory.resumeRequests:
+            # log.msg("Resuming")
+            self.factory.myServer.myPort.startReading()
+
+class LimitingHTTPFactory(HTTPFactory):
+    protocol = LimitingHTTPChannel
+
+    def __init__(self, requestFactory, maxRequests=600, resumeRequests=550,
+        **kwargs):
+        HTTPFactory.__init__(self, requestFactory, maxRequests, **kwargs)
+        self.resumeRequests = resumeRequests
+
+    def buildProtocol(self, addr):
+
+        p = protocol.ServerFactory.buildProtocol(self, addr)
+        for arg, value in self.protocolArgs.iteritems():
+            setattr(p, arg, value)
+        return p

Modified: CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/tap.py
===================================================================
--- CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/tap.py	2009-10-05 17:53:50 UTC (rev 4572)
+++ CalendarServer/branches/users/sagen/deployment-inherit-fds-4571/twistedcaldav/tap.py	2009-10-05 17:56:49 UTC (rev 4573)
@@ -16,10 +16,12 @@
 
 import os
 import stat
+import socket
 
 from zope.interface import implements
 
 from twisted.internet.address import IPv4Address
+from twisted.internet import tcp, ssl
 
 from twisted.python.log import FileLogObserver
 from twisted.python.usage import Options, UsageError
@@ -49,7 +51,7 @@
 from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
 from twistedcaldav.directory.aggregate import AggregateDirectoryService
 from twistedcaldav.directory.sudo import SudoDirectoryService
-from twistedcaldav.httpfactory import HTTP503LoggingFactory
+from twistedcaldav.httpfactory import HTTP503LoggingFactory, LimitingHTTPFactory
 from twistedcaldav.static import CalendarHomeProvisioningFile
 from twistedcaldav.static import TimezoneServiceFile
 from twistedcaldav.timezones import TimezoneCache
@@ -418,7 +420,71 @@
 
         self._context = ctx
 
+class InheritedPort(tcp.Port):
 
+    def __init__(self, fd, factory, reactor):
+        tcp.Port.__init__(self, 0, factory, reactor=reactor)
+        # MOR: careful because fromfd dup()'s the socket, so we need to
+        # make sure we don't leak file descriptors
+        self.socket = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
+        self._realPortNumber = self.port = self.socket.getsockname()[1]
+
+    def createInternetSocket(self):
+        return self.socket
+
+    def startListening(self):
+        log.msg("%s starting on %s" % (self.factory.__class__, self._realPortNumber))
+        self.factory.doStart()
+        self.connected = 1
+        self.fileno = self.socket.fileno
+        self.numberAccepts = self.factory.maxRequests
+        self.startReading()
+
+    def doRead(self):
+        self.numberAccepts = self.factory.maxRequests - self.factory.outstandingRequests
+        tcp.Port.doRead(self)
+
+
+class InheritedSSLPort(InheritedPort):
+    _socketShutdownMethod = 'sock_shutdown'
+
+    transport = ssl.Server
+
+    def __init__(self, fd, factory, ctxFactory, reactor):
+        InheritedPort.__init__(self, fd, factory, reactor)
+        self.ctxFactory = ctxFactory
+        self.socket = SSL.Connection(self.ctxFactory.getContext(), self.socket)
+
+    def _preMakeConnection(self, transport):
+        transport._startTLS()
+        return tcp.Port._preMakeConnection(self, transport)
+
+class InheritTCPServer(internet.TCPServer):
+
+    def __init__(self, *args, **kwargs):
+        internet.TCPServer.__init__(self, *args, **kwargs)
+        self.args[1].myServer = self
+
+    def _getPort(self):
+        from twisted.internet import reactor
+        port = InheritedPort(self.args[0], self.args[1], reactor)
+        port.startListening()
+        self.myPort = port
+        return port
+
+class InheritSSLServer(internet.SSLServer):
+
+    def __init__(self, *args, **kwargs):
+        internet.SSLServer.__init__(self, *args, **kwargs)
+        self.args[1].myServer = self
+
+    def _getPort(self):
+        from twisted.internet import reactor
+        port = InheritedSSLPort(self.args[0], self.args[1], self.args[2], reactor)
+        port.startListening()
+        self.myPort = port
+        return port
+
 class CalDAVServiceMaker(object):
     implements(IPlugin, service.IServiceMaker)
 
@@ -649,48 +715,29 @@
 
         site = Site(realRoot)
 
-        channel = HTTP503LoggingFactory(
-            site,
-            maxRequests=config.MaxRequests,
-            betweenRequestsTimeOut=config.IdleConnectionTimeOut)
 
-        def updateChannel(config, items):
-            channel.maxRequests = config.MaxRequests
+        # If inheriting file descriptors from the master, use those to handle
+        # requests instead of opening ports.
 
-        config.addHook(updateChannel)
+        if (config.EnableConnectionInheriting and
+           (config.InheritFDs or config.InheritSSLFDs)):
 
-        if not config.BindAddresses:
-            config.BindAddresses = [""]
+            channel = LimitingHTTPFactory(
+                site,
+                maxRequests=config.MaxRequests,
+                resumeRequests=config.ResumeRequests,
+                betweenRequestsTimeOut=config.IdleConnectionTimeOut)
 
-        for bindAddress in config.BindAddresses:
-            if config.BindHTTPPorts:
-                if config.HTTPPort == 0:
-                    raise UsageError(
-                        "HTTPPort required if BindHTTPPorts is not empty"
-                    )
-            elif config.HTTPPort != 0:
-                    config.BindHTTPPorts = [config.HTTPPort]
-
-            if config.BindSSLPorts:
-                if config.SSLPort == 0:
-                    raise UsageError(
-                        "SSLPort required if BindSSLPorts is not empty"
-                    )
-            elif config.SSLPort != 0:
-                config.BindSSLPorts = [config.SSLPort]
-
-            for port in config.BindHTTPPorts:
-                log.info("Adding server at %s:%s" % (bindAddress, port))
-
-                httpService = internet.TCPServer(
-                    int(port), channel,
-                    interface=bindAddress,
+            for fd in config.InheritFDs:
+                fd = int(fd)
+                inheritedService = InheritTCPServer(
+                    fd, channel,
                     backlog=config.ListenBacklog
                 )
-                httpService.setServiceParent(service)
+                inheritedService.setServiceParent(service)
 
-            for port in config.BindSSLPorts:
-                log.info("Adding SSL server at %s:%s" % (bindAddress, port))
+            for fd in config.InheritSSLFDs:
+                fd = int(fd)
 
                 try:
                     contextFactory = ChainingOpenSSLContextFactory(
@@ -701,15 +748,80 @@
                     )
                 except SSL.Error, e:
                     log.error("Unable to set up SSL context factory: %s" % (e,))
-                    log.error("Disabling SSL port: %s" % (port,))
                 else:
-                    httpsService = internet.SSLServer(
+                    inheritedService = InheritSSLServer(
+                        fd, channel,
+                        contextFactory,
+                        backlog=config.ListenBacklog
+                    )
+                    inheritedService.setServiceParent(service)
+
+
+        else: # Not inheriting, therefore open our own:
+
+            channel = HTTP503LoggingFactory(
+                site,
+                maxRequests=config.MaxRequests,
+                betweenRequestsTimeOut=config.IdleConnectionTimeOut)
+
+            if not config.BindAddresses:
+                config.BindAddresses = [""]
+
+            for bindAddress in config.BindAddresses:
+                if config.BindHTTPPorts:
+                    if config.HTTPPort == 0:
+                        raise UsageError(
+                            "HTTPPort required if BindHTTPPorts is not empty"
+                        )
+                elif config.HTTPPort != 0:
+                    config.BindHTTPPorts = [config.HTTPPort]
+
+                if config.BindSSLPorts:
+                    if config.SSLPort == 0:
+                        raise UsageError(
+                            "SSLPort required if BindSSLPorts is not empty"
+                        )
+                elif config.SSLPort != 0:
+                    config.BindSSLPorts = [config.SSLPort]
+
+                for port in config.BindHTTPPorts:
+                    log.info("Adding server at %s:%s" % (bindAddress, port))
+
+                    httpService = internet.TCPServer(
                         int(port), channel,
-                        contextFactory, interface=bindAddress,
+                        interface=bindAddress,
                         backlog=config.ListenBacklog
                     )
-                    httpsService.setServiceParent(service)
+                    httpService.setServiceParent(service)
 
+                for port in config.BindSSLPorts:
+                    log.info("Adding SSL server at %s:%s" % (bindAddress, port))
+
+                    try:
+                        contextFactory = ChainingOpenSSLContextFactory(
+                            config.SSLPrivateKey,
+                            config.SSLCertificate,
+                            certificateChainFile=config.SSLAuthorityChain,
+                            passwdCallback=_getSSLPassphrase
+                        )
+                    except SSL.Error, e:
+                        log.error("Unable to set up SSL context factory: %s" % (e,))
+                        log.error("Disabling SSL port: %s" % (port,))
+                    else:
+                        httpsService = internet.SSLServer(
+                            int(port), channel,
+                            contextFactory, interface=bindAddress,
+                            backlog=config.ListenBacklog
+                        )
+                        httpsService.setServiceParent(service)
+
+        def updateChannel(config, items):
+            channel.maxRequests = config.MaxRequests
+            channel.requestsRequests = config.ResumeRequests
+
+        config.addHook(updateChannel)
+
+
         # Change log level back to what it was before
         setLogLevelForNamespace(None, oldLogLevel)
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20091005/72a26763/attachment-0001.html>


More information about the calendarserver-changes mailing list