# Twisted, the Framework of Your Internet
# Copyright (C) 2001 Matthew W. Lefkowitz
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""I am the support module for creating web servers with 'mktap'
"""
import string, os
# Twisted Imports
from twisted.web import server,static,twcgi,script,test,distrib,trp
from twisted.internet import interfaces
from twisted.python import usage,reflect
from twisted.spread import pb
import sys
class Options(usage.Options):
synopsis = "Usage: mktap web [options]"
optParameters = [["port", "p", "8080","Port to start the server on."],
["telnet", "t", None, "Run a telnet server on this port."],
["logfile", "l", None, "Path to web log file."],
["https", "s", None, "Port to listen on for Secure HTTP."],
["certificate", "c", "server.pem", "SSL certificate to use for HTTPS."],
["privkey", "k", "server.pem", "SSL certificate to use for HTTPS."],
]
optFlags = [["personal", "",
"Instead of generating a webserver, generate a "
"ResourcePublisher which listens on "
"~/%s" % distrib.UserDirectory.userSocketName]]
longdesc = """\
This creates a web.tap file that can be used by twistd. If you specify
no arguments, it will be a demo webserver that has the Test class from
twisted.web.test in it."""
def __init__(self):
usage.Options.__init__(self)
self.opts['indexes'] = []
self.opts['root'] = None
def opt_index(self, indexName):
"""Add the name of a file used to check for directory indexes.
[default: index, index.html]
"""
self.opts['indexes'].append(indexName)
opt_i = opt_index
def opt_user(self):
"""Makes a server with ~/public_html and ~/.twistd-web-pb support for
users.
"""
self.opts['root'] = distrib.UserDirectory()
opt_u = opt_user
def opt_path(self, path):
"""<path> is either a specific file or a directory to
be set as the root of the web server. Use this if you
have a directory full of HTML, cgi, php3, epy, or rpy files or
any other files that you want to be served up raw.
"""
self.opts['root'] = static.File(os.path.abspath(path))
self.opts['root'].processors = {
'.cgi': twcgi.CGIScript,
'.php3': twcgi.PHP3Script,
'.php': twcgi.PHPScript,
'.epy': script.PythonScript,
'.rpy': script.ResourceScript,
'.trp': trp.ResourceUnpickler,
}
def opt_processor(self, proc):
"""`ext=class' where `class' is added as a Processor for files ending
with `ext'.
"""
if not isinstance(self.opts['root'], static.File):
raise usage.UsageError("You can only use --processor after --path.")
ext, klass = proc.split('=', 1)
self.opts['root'].processors[ext] = reflect.namedClass(klass)
def opt_static(self, path):
"""Same as --path, this is deprecated and will be removed in a
future release."""
print ("WARNING: --static is deprecated and will be removed in"
"a future release. Please use --path.")
self.opt_path(path)
opt_s = opt_static
def opt_class(self, className):
"""Create a Resource subclass with a zero-argument constructor.
"""
classObj = reflect.namedClass(className)
self.opts['root'] = classObj()
def opt_resource_script(self, name):
"""An .rpy file to be used as the root resource of the webserver."""
self.opts['root'] = script.ResourceScriptWrapper(name)
def opt_mime_type(self, defaultType):
"""Specify the default mime-type for static files."""
if not isinstance(self.opts['root'], static.File):
raise usage.UsageError("You can only use --mime_type after --path.")
self.opts['root'].defaultType = defaultType
opt_m = opt_mime_type
def opt_allow_ignore_ext(self):
"""Specify wether or not a request for 'foo' should return 'foo.ext'"""
if not isinstance(self.opts['root'], static.File):
raise usage.UsageError("You can only use --allow_ignore_ext "
"after --path.")
self.opts['root'].ignoreExt('*')
def opt_ignore_ext(self, ext):
"""Specify an extension to ignore. These will be processed in order.
"""
if not isinstance(self.opts['root'], static.File):
raise usage.UsageError("You can only use --ignore_ext "
"after --path.")
self.opts['root'].ignoreExt(ext)
def opt_flashconduit(self, port=None):
"""Start a flashconduit on the specified port.
"""
if not port:
port = "4321"
self.opts['flashconduit'] = port
def postOptions(self):
if self['https']:
try:
from twisted.internet.ssl import DefaultOpenSSLContextFactory
except ImportError:
raise usage.UsageError("SSL support not installed")
def updateApplication(app, config):
if config.opts['telnet']:
from twisted.protocols import telnet
factory = telnet.ShellFactory()
app.listenTCP(int(config.opts['telnet']), factory)
if config.opts['root']:
root = config.opts['root']
if config.opts['indexes']:
config.opts['root'].indexNames = config.opts['indexes']
else:
# This really ought to be web.Admin or something
root = test.Test()
if isinstance(root, static.File):
root.registry.setComponent(interfaces.IServiceCollection, app)
if config.opts['logfile']:
site = server.Site(root, logPath=config.opts['logfile'])
else:
site = server.Site(root)
if config.opts['personal']:
import pwd,os
pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell \
= pwd.getpwuid(os.getuid())
app.listenUNIX(os.path.join(pw_dir,
distrib.UserDirectory.userSocketName),
pb.BrokerFactory(distrib.ResourcePublisher(site)))
else:
if config['https']:
from twisted.internet.ssl import DefaultOpenSSLContextFactory
app.listenSSL(int(config['https']), site,
DefaultOpenSSLContextFactory(config['privkey'],
config['certificate']))
app.listenTCP(int(config.opts['port']), site)
flashport = config.opts.get('flashconduit', None)
if flashport:
from twisted.web.woven.flashconduit import FlashConduitFactory
app.listenTCP(int(flashport), FlashConduitFactory(site))
|