OLD | NEW |
| (Empty) |
1 | |
2 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
3 # See LICENSE for details. | |
4 | |
5 | |
6 """I am a virtual hosts implementation. | |
7 """ | |
8 | |
9 # System Imports | |
10 import string | |
11 | |
12 # Twisted Imports | |
13 from twisted.python import roots | |
14 | |
15 # Sibling Imports | |
16 import resource | |
17 import error | |
18 | |
19 class VirtualHostCollection(roots.Homogenous): | |
20 """Wrapper for virtual hosts collection. | |
21 | |
22 This exists for configuration purposes. | |
23 """ | |
24 entityType = resource.Resource | |
25 | |
26 def __init__(self, nvh): | |
27 self.nvh = nvh | |
28 | |
29 def listStaticEntities(self): | |
30 return self.nvh.hosts.items() | |
31 | |
32 def getStaticEntity(self, name): | |
33 return self.nvh.hosts.get(self) | |
34 | |
35 def reallyPutEntity(self, name, entity): | |
36 self.nvh.addHost(name, entity) | |
37 | |
38 def delEntity(self, name): | |
39 self.nvh.removeHost(name) | |
40 | |
41 | |
42 class NameVirtualHost(resource.Resource): | |
43 """I am a resource which represents named virtual hosts. | |
44 """ | |
45 | |
46 default = None | |
47 | |
48 def __init__(self): | |
49 """Initialize. | |
50 """ | |
51 resource.Resource.__init__(self) | |
52 self.hosts = {} | |
53 | |
54 def listStaticEntities(self): | |
55 return resource.Resource.listStaticEntities(self) + [("Virtual Hosts", V
irtualHostCollection(self))] | |
56 | |
57 def getStaticEntity(self, name): | |
58 if name == "Virtual Hosts": | |
59 return VirtualHostCollection(self) | |
60 else: | |
61 return resource.Resource.getStaticEntity(self, name) | |
62 | |
63 def addHost(self, name, resrc): | |
64 """Add a host to this virtual host. | |
65 | |
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:: | |
68 | |
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) | |
73 """ | |
74 self.hosts[name] = resrc | |
75 | |
76 def removeHost(self, name): | |
77 """Remove a host.""" | |
78 del self.hosts[name] | |
79 | |
80 def _getResourceForRequest(self, request): | |
81 """(Internal) Get the appropriate resource for the given host. | |
82 """ | |
83 hostHeader = request.getHeader('host') | |
84 if hostHeader == None: | |
85 return self.default or error.NoResource() | |
86 else: | |
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))) | |
90 | |
91 def render(self, request): | |
92 """Implementation of resource.Resource's render method. | |
93 """ | |
94 resrc = self._getResourceForRequest(request) | |
95 return resrc.render(request) | |
96 | |
97 def getChild(self, path, request): | |
98 """Implementation of resource.Resource's getChild method. | |
99 """ | |
100 resrc = self._getResourceForRequest(request) | |
101 if resrc.isLeaf: | |
102 request.postpath.insert(0,request.prepath.pop(-1)) | |
103 return resrc | |
104 else: | |
105 return resrc.getChildWithDefault(path, request) | |
106 | |
107 class _HostResource(resource.Resource): | |
108 | |
109 def getChild(self, path, request): | |
110 if ':' in path: | |
111 host, port = path.split(':', 1) | |
112 port = int(port) | |
113 else: | |
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) | |
121 | |
122 | |
123 class VHostMonsterResource(resource.Resource): | |
124 | |
125 """ | |
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 | |
134 """ | |
135 def getChild(self, path, request): | |
136 if path == 'http': | |
137 request.isSecure = lambda: 0 | |
138 elif path == 'https': | |
139 request.isSecure = lambda: 1 | |
140 return _HostResource() | |
141 | |
OLD | NEW |