Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 61 additions & 15 deletions trunserv/management/commands/trunserver.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import sys
import os
import re

from optparse import make_option

from django.core.management.base import BaseCommand, CommandError
from django.contrib.staticfiles.handlers import StaticFilesHandler
from django.core.servers.basehttp import get_internal_wsgi_application
#from django.utils import autoreload
from trunserv import autoreload

from twisted.application import internet, service, app
from twisted.web import server, resource, wsgi, static
from twisted.web import server, resource, wsgi
from twisted.python import threadpool, log
from twisted.internet import reactor
from twisted.internet import reactor, ssl
from twisted.internet.error import CannotListenError

from optparse import make_option
import sys
import os
import re
#from django.utils import autoreload
from trunserv import autoreload


naiveip_re = re.compile(r"""^(?:
Expand Down Expand Up @@ -48,15 +51,23 @@ def wsgi_resource():
class Command(BaseCommand):
option_list = BaseCommand.option_list + (
make_option('--noreload', action='store_false', dest='use_reloader',
default=True, help='Do NOT use the auto-reloader.'),
default=True, help='Do NOT use the auto-reloader.'),
make_option('--ssl-priv-key', action='store', dest='priv_key_file',
default=None, help='Private SSL key file'),
make_option('--ssl-cert', action='store', dest='cert_file',
default=None, help='SSL certificate file'),
)
help = "Starts a Twisted Web server for development."
args = '[optional port number, or ipaddr:port]'
args = '[optional port number, or ipaddr:port] '\
'[--ssl-priv-key=KEY --ssl-cert=CERT]'

# Validation is called explicitly each time the server is reloaded.
requires_model_validation = False

def handle(self, addrport='', *args, **options):
#
# Handle bind address configuration
#
if not addrport:
self.addr = ''
self.port = DEFAULT_PORT
Expand All @@ -72,6 +83,34 @@ def handle(self, addrport='', *args, **options):
if not self.addr:
self.addr = '127.0.0.1'

#
# Handle SSL configuration
#
priv_key_file = options.get('priv_key_file', '')
cert_file = options.get('cert_file', '')
self.use_ssl = False

if priv_key_file:
if not os.path.exists(priv_key_file):
error = 'The SSL private key file "%s" does not exist'
raise CommandError(error % priv_key_file)
else:
self.priv_key_file = priv_key_file

if cert_file:
if not os.path.exists(cert_file):
error = 'The SSL certificate file "%s" does not exist'
raise CommandError(error % cert_file)
else:
self.cert_file = cert_file

if (cert_file and not priv_key_file) or (priv_key_file and not cert_file):
error = 'You need to specify both --ssl-priv-key and --ssl-cert'
raise CommandError(error)

if cert_file and priv_key_file:
self.use_ssl = True

self.run(*args, **options)

def run(self, *args, **options):
Expand All @@ -87,15 +126,22 @@ def _inner_run():
root = Root(wsgi_root)

main_site = server.Site(root)
internet.TCPServer(int(self.port), main_site
).setServiceParent(application)

if self.use_ssl:
context = ssl.DefaultOpenSSLContextFactory(self.priv_key_file,
self.cert_file)
tcp_server = internet.SSLServer(int(self.port), main_site, context)
else:
tcp_server = internet.TCPServer(int(self.port), main_site)

tcp_server.setServiceParent(application)

service.IService(application).startService()
app.startApplication(application, False)

reactor.addSystemEventTrigger('before', 'shutdown',
service.IService(application).stopService)

stop = service.IService(application).stopService
reactor.addSystemEventTrigger('before', 'shutdown', stop)
reactor.run()

if use_reloader:
Expand Down