| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2001-2008 Twisted Matrix Laboratories. | |
| 2 # See LICENSE for details. | |
| 3 | |
| 4 """ | |
| 5 Support for creating a service which runs a web server. | |
| 6 """ | |
| 7 | |
| 8 import os | |
| 9 | |
| 10 # Twisted Imports | |
| 11 from twisted.web import server, static, twcgi, script, demo, distrib, trp | |
| 12 from twisted.internet import interfaces | |
| 13 from twisted.python import usage, reflect | |
| 14 from twisted.spread import pb | |
| 15 from twisted.application import internet, service, strports | |
| 16 | |
| 17 | |
| 18 class Options(usage.Options): | |
| 19 synopsis = "Usage: mktap web [options]" | |
| 20 optParameters = [["port", "p", "8080","Port to start the server on."], | |
| 21 ["logfile", "l", None, "Path to web CLF (Combined Log Forma
t) log file."], | |
| 22 ["https", None, None, "Port to listen on for Secure HTTP."]
, | |
| 23 ["certificate", "c", "server.pem", "SSL certificate to use
for HTTPS. "], | |
| 24 ["privkey", "k", "server.pem", "SSL certificate to use for
HTTPS."], | |
| 25 ] | |
| 26 optFlags = [["personal", "", | |
| 27 "Instead of generating a webserver, generate a " | |
| 28 "ResourcePublisher which listens on " | |
| 29 "~/%s" % distrib.UserDirectory.userSocketName], | |
| 30 ["notracebacks", "n", "Display tracebacks in broken web pages. "
+ | |
| 31 "Displaying tracebacks to users may be security risk!"], | |
| 32 ] | |
| 33 zsh_actions = {"logfile" : "_files -g '*.log'", "certificate" : "_files -g '
*.pem'", | |
| 34 "privkey" : "_files -g '*.pem'"} | |
| 35 | |
| 36 | |
| 37 longdesc = """\ | |
| 38 This creates a web.tap file that can be used by twistd. If you specify | |
| 39 no arguments, it will be a demo webserver that has the Test class from | |
| 40 twisted.web.demo in it.""" | |
| 41 | |
| 42 def __init__(self): | |
| 43 usage.Options.__init__(self) | |
| 44 self['indexes'] = [] | |
| 45 self['root'] = None | |
| 46 | |
| 47 def opt_index(self, indexName): | |
| 48 """Add the name of a file used to check for directory indexes. | |
| 49 [default: index, index.html] | |
| 50 """ | |
| 51 self['indexes'].append(indexName) | |
| 52 | |
| 53 opt_i = opt_index | |
| 54 | |
| 55 def opt_user(self): | |
| 56 """Makes a server with ~/public_html and ~/.twistd-web-pb support for | |
| 57 users. | |
| 58 """ | |
| 59 self['root'] = distrib.UserDirectory() | |
| 60 | |
| 61 opt_u = opt_user | |
| 62 | |
| 63 def opt_path(self, path): | |
| 64 """<path> is either a specific file or a directory to | |
| 65 be set as the root of the web server. Use this if you | |
| 66 have a directory full of HTML, cgi, php3, epy, or rpy files or | |
| 67 any other files that you want to be served up raw. | |
| 68 """ | |
| 69 | |
| 70 self['root'] = static.File(os.path.abspath(path)) | |
| 71 self['root'].processors = { | |
| 72 '.cgi': twcgi.CGIScript, | |
| 73 '.php3': twcgi.PHP3Script, | |
| 74 '.php': twcgi.PHPScript, | |
| 75 '.epy': script.PythonScript, | |
| 76 '.rpy': script.ResourceScript, | |
| 77 '.trp': trp.ResourceUnpickler, | |
| 78 } | |
| 79 | |
| 80 def opt_processor(self, proc): | |
| 81 """`ext=class' where `class' is added as a Processor for files ending | |
| 82 with `ext'. | |
| 83 """ | |
| 84 if not isinstance(self['root'], static.File): | |
| 85 raise usage.UsageError("You can only use --processor after --path.") | |
| 86 ext, klass = proc.split('=', 1) | |
| 87 self['root'].processors[ext] = reflect.namedClass(klass) | |
| 88 | |
| 89 def opt_static(self, path): | |
| 90 """Same as --path, this is deprecated and will be removed in a | |
| 91 future release.""" | |
| 92 print ("WARNING: --static is deprecated and will be removed in" | |
| 93 "a future release. Please use --path.") | |
| 94 self.opt_path(path) | |
| 95 opt_s = opt_static | |
| 96 | |
| 97 def opt_class(self, className): | |
| 98 """Create a Resource subclass with a zero-argument constructor. | |
| 99 """ | |
| 100 classObj = reflect.namedClass(className) | |
| 101 self['root'] = classObj() | |
| 102 | |
| 103 | |
| 104 def opt_resource_script(self, name): | |
| 105 """An .rpy file to be used as the root resource of the webserver.""" | |
| 106 self['root'] = script.ResourceScriptWrapper(name) | |
| 107 | |
| 108 | |
| 109 def opt_mime_type(self, defaultType): | |
| 110 """Specify the default mime-type for static files.""" | |
| 111 if not isinstance(self['root'], static.File): | |
| 112 raise usage.UsageError("You can only use --mime_type after --path.") | |
| 113 self['root'].defaultType = defaultType | |
| 114 opt_m = opt_mime_type | |
| 115 | |
| 116 | |
| 117 def opt_allow_ignore_ext(self): | |
| 118 """Specify whether or not a request for 'foo' should return 'foo.ext'""" | |
| 119 if not isinstance(self['root'], static.File): | |
| 120 raise usage.UsageError("You can only use --allow_ignore_ext " | |
| 121 "after --path.") | |
| 122 self['root'].ignoreExt('*') | |
| 123 | |
| 124 def opt_ignore_ext(self, ext): | |
| 125 """Specify an extension to ignore. These will be processed in order. | |
| 126 """ | |
| 127 if not isinstance(self['root'], static.File): | |
| 128 raise usage.UsageError("You can only use --ignore_ext " | |
| 129 "after --path.") | |
| 130 self['root'].ignoreExt(ext) | |
| 131 | |
| 132 def opt_flashconduit(self, port=None): | |
| 133 """Start a flashconduit on the specified port. | |
| 134 """ | |
| 135 if not port: | |
| 136 port = "4321" | |
| 137 self['flashconduit'] = port | |
| 138 | |
| 139 def postOptions(self): | |
| 140 if self['https']: | |
| 141 try: | |
| 142 from twisted.internet.ssl import DefaultOpenSSLContextFactory | |
| 143 except ImportError: | |
| 144 raise usage.UsageError("SSL support not installed") | |
| 145 | |
| 146 | |
| 147 | |
| 148 def makePersonalServerFactory(site): | |
| 149 """ | |
| 150 Create and return a factory which will respond to I{distrib} requests | |
| 151 against the given site. | |
| 152 | |
| 153 @type site: L{twisted.web.server.Site} | |
| 154 @rtype: L{twisted.internet.protocol.Factory} | |
| 155 """ | |
| 156 return pb.PBServerFactory(distrib.ResourcePublisher(site)) | |
| 157 | |
| 158 | |
| 159 | |
| 160 def makeService(config): | |
| 161 s = service.MultiService() | |
| 162 if config['root']: | |
| 163 root = config['root'] | |
| 164 if config['indexes']: | |
| 165 config['root'].indexNames = config['indexes'] | |
| 166 else: | |
| 167 # This really ought to be web.Admin or something | |
| 168 root = demo.Test() | |
| 169 | |
| 170 if isinstance(root, static.File): | |
| 171 root.registry.setComponent(interfaces.IServiceCollection, s) | |
| 172 | |
| 173 if config['logfile']: | |
| 174 site = server.Site(root, logPath=config['logfile']) | |
| 175 else: | |
| 176 site = server.Site(root) | |
| 177 | |
| 178 site.displayTracebacks = not config["notracebacks"] | |
| 179 | |
| 180 if config['personal']: | |
| 181 import pwd | |
| 182 name, passwd, uid, gid, gecos, dir, shell = pwd.getpwuid(os.getuid()) | |
| 183 personal = internet.UNIXServer( | |
| 184 os.path.join(dir, distrib.UserDirectory.userSocketName), | |
| 185 makePersonalServerFactory(site)) | |
| 186 personal.setServiceParent(s) | |
| 187 else: | |
| 188 if config['https']: | |
| 189 from twisted.internet.ssl import DefaultOpenSSLContextFactory | |
| 190 i = internet.SSLServer(int(config['https']), site, | |
| 191 DefaultOpenSSLContextFactory(config['privkey'], | |
| 192 config['certificate'])) | |
| 193 i.setServiceParent(s) | |
| 194 strports.service(config['port'], site).setServiceParent(s) | |
| 195 | |
| 196 flashport = config.get('flashconduit', None) | |
| 197 if flashport: | |
| 198 from twisted.web.woven.flashconduit import FlashConduitFactory | |
| 199 i = internet.TCPServer(int(flashport), FlashConduitFactory(site)) | |
| 200 i.setServiceParent(s) | |
| 201 return s | |
| OLD | NEW |