]>
Commit | Line | Data |
---|---|---|
9e769c12 CP |
1 | from zope.interface import implements |
2 | ||
3 | from twisted.python import usage | |
1bccb3e6 CP |
4 | |
5 | from twisted.internet import task, protocol | |
6 | from twisted.protocols import basic, policies | |
9e769c12 CP |
7 | from twisted.plugin import IPlugin |
8 | from twisted.application.service import IServiceMaker | |
5a767fca | 9 | from twisted.application import internet, strports, service |
9e769c12 | 10 | from twisted.web import static, server |
1bccb3e6 CP |
11 | import urlparse |
12 | import urllib | |
9e769c12 | 13 | |
930be88a | 14 | from qwebirc.root import RootSite |
9e769c12 CP |
15 | |
16 | class Options(usage.Options): | |
17 | optParameters = [["port", "p", "9090","Port to start the server on."], | |
ef74f2c1 | 18 | ["ip", "i", "0.0.0.0", "IP address to listen on."], |
9e769c12 CP |
19 | ["logfile", "l", None, "Path to web CLF (Combined Log Format) log file."], |
20 | ["https", None, None, "Port to listen on for Secure HTTP."], | |
21 | ["certificate", "c", "server.pem", "SSL certificate to use for HTTPS. "], | |
22 | ["privkey", "k", "server.pem", "SSL certificate to use for HTTPS."], | |
9e93b6fe | 23 | ["certificate-chain", "C", None, "Chain SSL certificate"], |
9e769c12 CP |
24 | ["staticpath", "s", "static", "Path to static content"], |
25 | ] | |
26 | ||
27 | optFlags = [["notracebacks", "n", "Display tracebacks in broken web pages. " + | |
28 | "Displaying tracebacks to users may be security risk!"], | |
29 | ] | |
9e769c12 CP |
30 | |
31 | def postOptions(self): | |
32 | if self['https']: | |
33 | try: | |
9e93b6fe | 34 | get_ssl_factory_factory() |
9e769c12 CP |
35 | except ImportError: |
36 | raise usage.UsageError("SSL support not installed") | |
1bccb3e6 | 37 | |
9e769c12 CP |
38 | class QWebIRCServiceMaker(object): |
39 | implements(IServiceMaker, IPlugin) | |
40 | tapname = "qwebirc" | |
41 | description = "QuakeNet web-based IRC client" | |
42 | options = Options | |
9e769c12 CP |
43 | |
44 | def makeService(self, config): | |
45 | if config['logfile']: | |
46 | site = RootSite(config['staticpath'], logPath=config['logfile']) | |
47 | else: | |
48 | site = RootSite(config['staticpath']) | |
5a767fca CP |
49 | |
50 | s = service.MultiService() | |
9e769c12 CP |
51 | site.displayTracebacks = not config["notracebacks"] |
52 | if config['https']: | |
9e93b6fe | 53 | ssl_factory = get_ssl_factory_factory() |
5a767fca | 54 | i = internet.SSLServer(int(config['https']), site, ssl_factory(config['privkey'], config['certificate'], certificateChainFile=config["certificate-chain"]), interface=config['ip']) |
9e769c12 | 55 | else: |
2698ec23 | 56 | i = internet.TCPServer(int(config['port']), site, interface=config['ip']) |
5a767fca CP |
57 | |
58 | i.setServiceParent(s) | |
5a767fca CP |
59 | |
60 | return s | |
9e93b6fe CP |
61 | |
62 | def get_ssl_factory_factory(): | |
63 | from twisted.internet.ssl import DefaultOpenSSLContextFactory | |
64 | class ChainingOpenSSLContextFactory(DefaultOpenSSLContextFactory): | |
65 | def __init__(self, *args, **kwargs): | |
66 | self.chain = None | |
67 | if kwargs.has_key("certificateChainFile"): | |
68 | self.chain = kwargs["certificateChainFile"] | |
69 | del kwargs["certificateChainFile"] | |
70 | ||
71 | DefaultOpenSSLContextFactory.__init__(self, *args, **kwargs) | |
72 | ||
73 | def cacheContext(self): | |
74 | DefaultOpenSSLContextFactory.cacheContext(self) | |
75 | if self.chain: | |
76 | self._context.use_certificate_chain_file(self.chain) | |
77 | self._context.use_privatekey_file(self.privateKeyFileName) | |
78 | ||
79 | return ChainingOpenSSLContextFactory | |
80 | ||
ef74f2c1 | 81 | serviceMaker = QWebIRCServiceMaker() |