root / trunk / twisted / web2 / tap.py

Revision 22836, 8.0 kB (checked in by dreid, 1 year ago)

Delete twisted.web2.dav and all references to it except in the autogenerated zsh completion files.

Author: dreid
Reviewer: exarkun

Refs #3078
Fixes #3072

Line 
1 import os
2 from zope.interface import implements
3
4 from twisted.python import usage, reflect
5 from twisted.application import internet, service, strports
6 from twisted.scripts.mktap import IServiceMaker
7 from twisted.plugin import IPlugin
8
9 from twisted.web2 import static, iweb, log, server, channel, vhost
10
11 class Options(usage.Options):
12     optParameters = [["port", "p", "8080",
13                       "Port to start the server on."],
14                      ["logfile", "l", None,
15                       ("Common Access Logging Format file to write to "
16                        "if unspecified access log information will be "
17                        "written to the standard twisted log file.")],
18                      ["https", None, None,
19                       "Port to listen on for Secure HTTP."],
20                      ["certificate", "c", "server.pem",
21                       "SSL certificate to use for HTTPS."],
22                      ["privkey", "k", "server.pem",
23                       "SSL certificate to use for HTTPS."]]
24    
25     zsh_actions = {"certificate" : "_files -g '*.pem'",
26                    "privkey" : "_files -g '*.pem'"}
27    
28     longdesc = """\
29 This creates a web2.tap file that can be used by twistd.
30
31 Basic Examples:
32
33 To serve a static directory or file:
34
35     mktap web2 --path=/tmp/
36
37 To serve a dynamic resource:
38
39     mktap web2 --class=fully.qualified.ClassName
40
41 To serve a directory of the form:
42
43     /var/www/domain1/
44     /var/www/domain2/
45
46     mktap web2 --vhost-path=/var/www/
47
48 All the above options are incompatible as they all specify the
49 root resource.  However you can use the following options in
50 conjunction with --vhost-path
51
52 To serve a specific host name as a static file:
53
54     mktap web2 --vhost-static=domain3=/some/other/root/domain3
55
56 Or to serve a specific host name as a dynamic resource:
57
58     mktap web2 --vhost-class=domain4=fully.qualified.ClassName
59
60 """
61
62     def __init__(self):
63         usage.Options.__init__(self)
64         self['indexes'] = []
65         self['root'] = None
66        
67     def opt_index(self, indexName):
68         """Add the name of a file used to check for directory indexes.
69         [default: index, index.html]
70         """
71         self['indexes'].append(indexName)
72    
73     opt_i = opt_index
74
75     def opt_path(self, path):
76         """A path that will be used to serve the root resource as a raw file
77         or directory.
78         """
79
80         if self['root']:
81             raise usage.UsageError("You may only have one root resource.")
82
83         self['root'] = static.File(os.path.abspath(path))
84
85     def opt_processor(self, proc):
86         """`ext=class' where `class' is added as a Processor for files ending
87         with `ext'.
88         """
89         if not isinstance(self['root'], static.File):
90             raise usage.UsageError("You can only use --processor after --path.")
91         ext, klass = proc.split('=', 1)
92         self['root'].processors[ext] = reflect.namedClass(klass)
93
94     def opt_class(self, className):
95         """A class that will be used to serve the root resource.  Must implement twisted.web2.iweb.IResource and take no arguments.
96         """
97         if self['root']:
98             raise usage.UsageError("You may only have one root resource.")
99        
100         classObj = reflect.namedClass(className)
101         self['root'] = iweb.IResource(classObj())
102
103     def opt_allow_ignore_ext(self):
104         """Specify whether or not a request for 'foo' should return 'foo.ext'"""
105         if not isinstance(self['root'], static.File):
106             raise usage.UsageError("You can only use --allow_ignore_ext "
107                                    "after --path.")
108         self['root'].ignoreExt('*')
109
110     def opt_ignore_ext(self, ext):
111         """Specify an extension to ignore.  These will be processed in order.
112         """
113         if not isinstance(self['root'], static.File):
114             raise usage.UsageError("You can only use --ignore_ext "
115                                    "after --path.")
116         self['root'].ignoreExt(ext)
117
118     def opt_mimetype(self, mimetype):
119         """Mapping from file extension to MIME Type in the form of 'ext=type'.
120         Example: html=text/html
121         """
122
123         if not isinstance(self['root'], static.File):
124             raise usage.UsageError("You can only use --mimetype "
125                                    "after --path.")
126
127         ext, mimetype = mimetype.split('=', 1)
128
129         # this is really gross, there should be a public api for this.
130         
131         self['root']._sharedContentTypes.update({ext: mimetype})
132
133     def opt_vhost_path(self, path):
134         """Specify a directory to use for automatic named virtual hosts.
135         It is assumed that this directory contains a series of
136         subdirectories each representing a virtual host domain name
137         and containing the files to be served at that domain.
138         """
139        
140         if self['root']:
141             if not isintance(self['root'], vhost.NameVirtualHost):
142                 raise usage.UsageError("You may only have one root resource")
143         else:
144             self['root'] = vhost.NameVirtualHost()
145
146         path = os.path.abspath(path)
147        
148         for name in os.listdir(path):
149             fullname = os.path.join(path, name)
150             self['root'].addHost(name,
151                                  static.File(fullname))
152
153     def opt_vhost_static(self, virtualHost):
154         """Specify a virtual host in the form of domain=path to be served as
155         raw directory or file.
156         """
157         if (self['root'] and not \
158             isinstance(self['root'], vhost.NameVirtualHost)):
159
160             raise usage.UsageError("You can only use --vhost-static alone "
161                                    "or with --vhost-class and --vhost-path")
162
163         domain, path = virtualHost.split('=', 1)
164
165         if not self['root']:
166             self['root'] = vhost.NameVirtualHost()
167
168         self['root'].addHost(domain, static.File(os.path.abspath(path)))
169    
170     def opt_vhost_class(self, virtualHost):
171         """Specify a virtual host in the form of domain=class,
172         where class can be adapted to an iweb.IResource and has a
173         zero-argument constructor.
174         """
175         if (self['root'] and not \
176             isinstance(self['root'], vhost.NameVirtualHost)):
177
178             raise usage.UsageError("You can not use --vhost-class with "
179                                    "--path or --class.")
180
181         domain, className = virtualHost.split('=', 1)
182
183         if not self['root']:
184             self['root'] = vhost.NameVirtualHost()
185
186         classObj = reflect.namedClass(className)
187         self['root'].addHost(domain, iweb.IResource(classObj()))
188
189     def postOptions(self):
190         if self['https']:
191             try:
192                 from twisted.internet.ssl import DefaultOpenSSLContextFactory
193             except ImportError:
194                 raise usage.UsageError("SSL support not installed")
195
196
197 class Web2Service(service.MultiService):
198     def __init__(self, logObserver):
199         self.logObserver = logObserver
200         service.MultiService.__init__(self)
201
202     def startService(self):
203         service.MultiService.startService(self)
204         self.logObserver.start()
205
206     def stopService(self):
207         service.MultiService.stopService(self)
208         self.logObserver.stop()
209
210
211 def makeService(config):
212     if config['logfile']:
213         logObserver = log.FileAccessLoggingObserver(config['logfile'])
214     else:
215         logObserver = log.DefaultCommonAccessLoggingObserver()
216
217     if config['root']:
218         if config['indexes']:
219             config['root'].indexNames = config['indexes']
220            
221         root = log.LogWrapperResource(config['root'])
222
223
224     s = Web2Service(logObserver)
225
226     site = server.Site(root)
227     chan = channel.HTTPFactory(site)
228    
229     if config['https']:
230         from twisted.internet.ssl import DefaultOpenSSLContextFactory
231         i = internet.SSLServer(int(config['https']), chan,
232                                DefaultOpenSSLContextFactory(config['privkey'],
233                                                             config['certificate']))
234         i.setServiceParent(s)
235        
236     strports.service(config['port'], chan
237                      ).setServiceParent(s)
238
239     return s
Note: See TracBrowser for help on using the browser.