2
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
3
# See LICENSE for details.
6
"""I am a virtual hosts implementation.
13
from twisted.python import roots
19
class VirtualHostCollection(roots.Homogenous):
20
"""Wrapper for virtual hosts collection.
22
This exists for configuration purposes.
24
entityType = resource.Resource
26
def __init__(self, nvh):
29
def listStaticEntities(self):
30
return self.nvh.hosts.items()
32
def getStaticEntity(self, name):
33
return self.nvh.hosts.get(self)
35
def reallyPutEntity(self, name, entity):
36
self.nvh.addHost(name, entity)
38
def delEntity(self, name):
39
self.nvh.removeHost(name)
42
class NameVirtualHost(resource.Resource):
43
"""I am a resource which represents named virtual hosts.
51
resource.Resource.__init__(self)
54
def listStaticEntities(self):
55
return resource.Resource.listStaticEntities(self) + [("Virtual Hosts", VirtualHostCollection(self))]
57
def getStaticEntity(self, name):
58
if name == "Virtual Hosts":
59
return VirtualHostCollection(self)
61
return resource.Resource.getStaticEntity(self, name)
63
def addHost(self, name, resrc):
64
"""Add a host to this virtual host.
66
This will take a host named `name', and map it to a resource
67
`resrc'. For example, a setup for our virtual hosts would be::
69
nvh.addHost('divunal.com', divunalDirectory)
70
nvh.addHost('www.divunal.com', divunalDirectory)
71
nvh.addHost('twistedmatrix.com', twistedMatrixDirectory)
72
nvh.addHost('www.twistedmatrix.com', twistedMatrixDirectory)
74
self.hosts[name] = resrc
76
def removeHost(self, name):
80
def _getResourceForRequest(self, request):
81
"""(Internal) Get the appropriate resource for the given host.
83
hostHeader = request.getHeader('host')
84
if hostHeader == None:
85
return self.default or error.NoResource()
87
host = string.split(string.lower(hostHeader),':')[0]
88
return (self.hosts.get(host, self.default)
89
or error.NoResource("host %s not in vhost map" % repr(host)))
91
def render(self, request):
92
"""Implementation of resource.Resource's render method.
94
resrc = self._getResourceForRequest(request)
95
return resrc.render(request)
97
def getChild(self, path, request):
98
"""Implementation of resource.Resource's getChild method.
100
resrc = self._getResourceForRequest(request)
102
request.postpath.insert(0,request.prepath.pop(-1))
105
return resrc.getChildWithDefault(path, request)
107
class _HostResource(resource.Resource):
109
def getChild(self, path, request):
111
host, port = path.split(':', 1)
114
host, port = path, 80
115
request.setHost(host, port)
116
prefixLen = 3+request.isSecure()+4+len(path)+len(request.prepath[-3])
117
request.path = '/'+'/'.join(request.postpath)
118
request.uri = request.uri[prefixLen:]
119
del request.prepath[:3]
120
return request.site.getResourceFor(request)
123
class VHostMonsterResource(resource.Resource):
126
Use this to be able to record the hostname and method (http vs. https)
127
in the URL without disturbing your web site. If you put this resource
128
in a URL http://foo.com/bar then requests to
129
http://foo.com/bar/http/baz.com/something will be equivalent to
130
http://foo.com/something, except that the hostname the request will
131
appear to be accessing will be "baz.com". So if "baz.com" is redirecting
132
all requests for to foo.com, while foo.com is inaccessible from the outside,
133
then redirect and url generation will work correctly
135
def getChild(self, path, request):
137
request.isSecure = lambda: 0
138
elif path == 'https':
139
request.isSecure = lambda: 1
140
return _HostResource()