Package flumotion :: Package common :: Module server
[hide private]

Source Code for Module flumotion.common.server

  1  # -*- Mode: Python -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  """helper classes for creating a twisted server 
 23  """ 
 24   
 25  import os 
 26   
 27  from twisted.internet import reactor 
 28  from zope.interface import Interface 
 29   
 30  from flumotion.common import log 
 31   
 32  __version__ = "$Rev: 6964 $" 
 33   
 34   
35 -class _ServerContextFactory(log.Loggable):
36 37 logCategory = "SSLServer" 38
39 - def __init__(self, pemFile):
40 self._pemFile = pemFile
41
42 - def getContext(self):
43 """ 44 Create an SSL context. 45 """ 46 from OpenSSL import SSL 47 ctx = SSL.Context(SSL.SSLv23_METHOD) 48 try: 49 ctx.use_certificate_file(self._pemFile) 50 ctx.use_privatekey_file(self._pemFile) 51 except SSL.Error, e: 52 self.warning('SSL error: %r' % e.args) 53 self.error('Could not open certificate %s' % self._pemFile) 54 return ctx
55 56
57 -class IServable(Interface):
58 """ 59 I am an interface for objects that want to be servable through a 60 L{Server}. 61 """
62 - def getFactory():
63 """ 64 @rtype: L{twisted.spread.pb.PBServerFactory} 65 """
66
67 - def setConnectionInfo(host, port, useSSL):
68 """ 69 @param host: the host to listen as 70 @type host: str 71 @param port: the port to listen on 72 @type port: int 73 @param useSSL: whether this connection uses SSL 74 @type useSSL: bool 75 """
76
77 -class Server(log.Loggable):
78 logCategory = "server" 79
80 - def __init__(self, servable):
81 """ 82 I expose a servable to the network using TCP or SSL. 83 84 @type servable: an implemtor of L{IServable} 85 """ 86 self._servable = servable
87
88 - def startSSL(self, host, port, pemFile, configDir):
89 """ 90 Listen as the given host and on the given port using SSL. 91 Use the given .pem file, or look for it in the config directory. 92 93 @param pemFile: File containing the SSL certificate. 94 If it's a full path, respects the full path. 95 If not, looks in configDir for this file. 96 @param configDir: directory where .pem file is stored 97 @returns: {twisted.internet.interfaces.IListeningPort} on which 98 we are listening; call .stopListening() to stop. 99 """ 100 from flumotion.common import common 101 common.assertSSLAvailable() 102 103 # if no path in pemFile, then look for it in the config directory 104 if not os.path.split(pemFile)[0]: 105 pemFile = os.path.join(configDir, pemFile) 106 if not os.path.exists(pemFile): 107 self.error(".pem file %s does not exist.\n" \ 108 "For more information, see \n" \ 109 "http://www.flumotion.net/doc/flumotion/manual/html/" \ 110 "chapter-security.html" % pemFile) 111 log.debug('manager', 'Using PEM certificate file %s' % pemFile) 112 ctxFactory = _ServerContextFactory(pemFile) 113 114 self.info('Starting on port %d using SSL' % port) 115 if not host == "": 116 self.info('Listening as host %s' % host) 117 self._servable.setConnectionInfo(host, port, True) 118 return reactor.listenSSL(port, self._servable.getFactory(), 119 ctxFactory, interface=host)
120
121 - def startTCP(self, host, port):
122 """ 123 Listen as the given host and on the given port using normal TCP. 124 125 @returns: {twisted.internet.interfaces.IListeningPort} on which 126 we are listening; call .stopListening() to stop. 127 """ 128 self.info('Starting on port %d using TCP' % port) 129 if not host == "": 130 self.info('Listening as host %s' % host) 131 self._servable.setConnectionInfo(host, port, False) 132 return reactor.listenTCP(port, self._servable.getFactory(), 133 interface=host)
134