1
# -*- test-case-name: twisted.web.
2
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
3
# See LICENSE for details.
6
I am a virtual hosts implementation.
10
from twisted.python import roots
11
from twisted.web import resource
14
class VirtualHostCollection(roots.Homogenous):
15
"""Wrapper for virtual hosts collection.
17
This exists for configuration purposes.
19
entityType = resource.Resource
21
def __init__(self, nvh):
24
def listStaticEntities(self):
25
return self.nvh.hosts.items()
27
def getStaticEntity(self, name):
28
return self.nvh.hosts.get(self)
30
def reallyPutEntity(self, name, entity):
31
self.nvh.addHost(name, entity)
33
def delEntity(self, name):
34
self.nvh.removeHost(name)
37
class NameVirtualHost(resource.Resource):
38
"""I am a resource which represents named virtual hosts.
46
resource.Resource.__init__(self)
49
def listStaticEntities(self):
50
return resource.Resource.listStaticEntities(self) + [("Virtual Hosts", VirtualHostCollection(self))]
52
def getStaticEntity(self, name):
53
if name == "Virtual Hosts":
54
return VirtualHostCollection(self)
56
return resource.Resource.getStaticEntity(self, name)
58
def addHost(self, name, resrc):
59
"""Add a host to this virtual host.
61
This will take a host named `name', and map it to a resource
62
`resrc'. For example, a setup for our virtual hosts would be::
64
nvh.addHost('divunal.com', divunalDirectory)
65
nvh.addHost('www.divunal.com', divunalDirectory)
66
nvh.addHost('twistedmatrix.com', twistedMatrixDirectory)
67
nvh.addHost('www.twistedmatrix.com', twistedMatrixDirectory)
69
self.hosts[name] = resrc
71
def removeHost(self, name):
75
def _getResourceForRequest(self, request):
76
"""(Internal) Get the appropriate resource for the given host.
78
hostHeader = request.getHeader('host')
79
if hostHeader == None:
80
return self.default or resource.NoResource()
82
host = hostHeader.lower().split(':', 1)[0]
83
return (self.hosts.get(host, self.default)
84
or resource.NoResource("host %s not in vhost map" % repr(host)))
86
def render(self, request):
87
"""Implementation of resource.Resource's render method.
89
resrc = self._getResourceForRequest(request)
90
return resrc.render(request)
92
def getChild(self, path, request):
93
"""Implementation of resource.Resource's getChild method.
95
resrc = self._getResourceForRequest(request)
97
request.postpath.insert(0,request.prepath.pop(-1))
100
return resrc.getChildWithDefault(path, request)
102
class _HostResource(resource.Resource):
104
def getChild(self, path, request):
106
host, port = path.split(':', 1)
109
host, port = path, 80
110
request.setHost(host, port)
111
prefixLen = 3+request.isSecure()+4+len(path)+len(request.prepath[-3])
112
request.path = '/'+'/'.join(request.postpath)
113
request.uri = request.uri[prefixLen:]
114
del request.prepath[:3]
115
return request.site.getResourceFor(request)
118
class VHostMonsterResource(resource.Resource):
121
Use this to be able to record the hostname and method (http vs. https)
122
in the URL without disturbing your web site. If you put this resource
123
in a URL http://foo.com/bar then requests to
124
http://foo.com/bar/http/baz.com/something will be equivalent to
125
http://foo.com/something, except that the hostname the request will
126
appear to be accessing will be "baz.com". So if "baz.com" is redirecting
127
all requests for to foo.com, while foo.com is inaccessible from the outside,
128
then redirect and url generation will work correctly
130
def getChild(self, path, request):
132
request.isSecure = lambda: 0
133
elif path == 'https':
134
request.isSecure = lambda: 1
135
return _HostResource()