Index: paste/httpserver.py
===================================================================
--- paste/httpserver.py	(revision 7318)
+++ paste/httpserver.py	(working copy)
@@ -27,7 +27,7 @@
 from itertools import count
 from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
 from SocketServer import ThreadingMixIn
-from paste.util import converters
+from paste.util import converters, import_string
 import logging
 try:
     from paste.util import killthread
@@ -430,6 +430,13 @@
         # don't bother logging disconnects while handling a request
         try:
             BaseHTTPRequestHandler.handle(self)
+        except (SSL.WantReadError, SSL.WantWriteError,
+                SSL.WantX509LookupError), error:
+            self.wsgi_connection_drop(error)
+        except SSL.ZeroReturnError, error:
+            self.wsgi_connection_drop(error)
+        except SSL.Error, error:
+            self.wsgi_connection_drop(error)
         except SocketErrors, exce:
             self.wsgi_connection_drop(exce)
 
@@ -1127,9 +1134,9 @@
     """
 
 def serve(application, host=None, port=None, handler=None, ssl_pem=None,
-          ssl_context=None, server_version=None, protocol_version=None,
-          start_loop=True, daemon_threads=None, socket_timeout=None,
-          use_threadpool=None, threadpool_workers=10,
+          ssl_context=None, ssl_context_options=None, server_version=None,
+          protocol_version=None, start_loop=True, daemon_threads=None,
+          socket_timeout=None, use_threadpool=None, threadpool_workers=10,
           threadpool_options=None):
     """
     Serves your ``application`` over HTTP(S) via WSGI interface
@@ -1171,6 +1178,35 @@
         ``ssl_pem``.  Supply this to use a context of your own
         construction.
 
+        If you set a module path on the config file, that module will be loaded,
+        and on that module you must have a function ``get_ssl_context`` where
+        you setup your custom context and then return in. All options will be
+        passed to that function for your convenience.
+        For example::
+
+            def ssl_verify_callback_stub(ssl_ctx_ptr, x509_ptr, errnum,
+                                         errdepth, ok):
+                print 'Got Client Certificate: ', x509_ptr.get_subject()
+                return ok
+
+            def get_ssl_context(**ssl_context_options):
+                ctx = SSL.Context(SSL.SSLv3_METHOD)
+                ctx.use_privatekey_file(ssl_context_options.get('ssl_key'))
+                ctx.use_certificate_file(ssl_context_options.get('ssl_cert'))
+                ctx.load_verify_locations(ssl_context_options.get('ssl_ca_cert'))
+                ctx.set_verify(
+                    SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
+                    ssl_verify_callback_stub) # Demand a certificate
+                return ctx
+
+        Then, on your config file you would have something like::
+
+            ssl_context = myapp.lib.custom_ssl_context
+
+    ``ssl_context_options``
+
+        These are extra options passed to the custom ssl_context.
+
     ``server_version``
 
         The version of the server as reported in HTTP response line. This
@@ -1226,6 +1262,7 @@
         threadpool.  See paste.httpserver.ThreadPool for specific
         options (``threadpool_workers`` is a specific option that can
         also go here).
+
     """
     is_ssl = False
     if ssl_pem or ssl_context:
@@ -1239,6 +1276,16 @@
                 ssl_context = SSL.Context(SSL.SSLv23_METHOD)
                 ssl_context.use_privatekey_file(ssl_pem)
                 ssl_context.use_certificate_chain_file(ssl_pem)
+        else:
+            if isinstance(ssl_context, basestring):
+                # Is this a module path from the config file
+                module = import_string.try_import_module(ssl_context)
+                # module has the necessary function to setup ssl_context?
+                if not hasattr(module, 'get_ssl_context'):
+                    raise SystemExit, "'%s' does not " % module + \
+                                      "have a get_ssl_context() function"
+                # Get the ssl_context all configured
+                ssl_context = module.get_ssl_context(**ssl_context_options)
 
     host = host or '127.0.0.1'
     if port is None:
@@ -1305,15 +1352,22 @@
     for name in ['use_threadpool', 'daemon_threads']:
         if name in kwargs:
             kwargs[name] = asbool(kwargs[name])
+    ssl_context_options = {}
+    if 'ssl_pem' in kwargs:
+        ssl_context_options['ssl_pem'] = kwargs['ssl_pem']
     threadpool_options = {}
     for name, value in kwargs.items():
         if name.startswith('threadpool_') and name != 'threadpool_workers':
             threadpool_options[name[len('threadpool_'):]] = value
             del kwargs[name]
+        elif name.startswith('ssl_context_'):
+            ssl_context_options[name[len('ssl_context_'):]] = value
+            del kwargs[name]
     if ('error_email' not in threadpool_options
         and 'error_email' in global_conf):
         threadpool_options['error_email'] = global_conf['error_email']
     kwargs['threadpool_options'] = threadpool_options
+    kwargs['ssl_context_options'] = ssl_context_options
     serve(wsgi_app, **kwargs)
 
 server_runner.__doc__ = (serve.__doc__ or '') + """

