test_vhost.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Tests for L{twisted.web.vhost}.
  5. """
  6. from __future__ import absolute_import, division
  7. from twisted.internet.defer import gatherResults
  8. from twisted.trial.unittest import TestCase
  9. from twisted.web.http import NOT_FOUND
  10. from twisted.web.resource import NoResource
  11. from twisted.web.static import Data
  12. from twisted.web.server import Site
  13. from twisted.web.vhost import (_HostResource,
  14. NameVirtualHost,
  15. VHostMonsterResource)
  16. from twisted.web.test.test_web import DummyRequest
  17. from twisted.web.test._util import _render
  18. class HostResourceTests(TestCase):
  19. """
  20. Tests for L{_HostResource}.
  21. """
  22. def test_getChild(self):
  23. """
  24. L{_HostResource.getChild} returns the proper I{Resource} for the vhost
  25. embedded in the URL. Verify that returning the proper I{Resource}
  26. required changing the I{Host} in the header.
  27. """
  28. bazroot = Data(b'root data', "")
  29. bazuri = Data(b'uri data', "")
  30. baztest = Data(b'test data', "")
  31. bazuri.putChild(b'test', baztest)
  32. bazroot.putChild(b'uri', bazuri)
  33. hr = _HostResource()
  34. root = NameVirtualHost()
  35. root.default = Data(b'default data', "")
  36. root.addHost(b'baz.com', bazroot)
  37. request = DummyRequest([b'uri', b'test'])
  38. request.prepath = [b'bar', b'http', b'baz.com']
  39. request.site = Site(root)
  40. request.isSecure = lambda: False
  41. request.host = b''
  42. step = hr.getChild(b'baz.com', request) # Consumes rest of path
  43. self.assertIsInstance(step, Data)
  44. request = DummyRequest([b'uri', b'test'])
  45. step = root.getChild(b'uri', request)
  46. self.assertIsInstance(step, NoResource)
  47. class NameVirtualHostTests(TestCase):
  48. """
  49. Tests for L{NameVirtualHost}.
  50. """
  51. def test_renderWithoutHost(self):
  52. """
  53. L{NameVirtualHost.render} returns the result of rendering the
  54. instance's C{default} if it is not L{None} and there is no I{Host}
  55. header in the request.
  56. """
  57. virtualHostResource = NameVirtualHost()
  58. virtualHostResource.default = Data(b"correct result", "")
  59. request = DummyRequest([''])
  60. self.assertEqual(
  61. virtualHostResource.render(request), b"correct result")
  62. def test_renderWithoutHostNoDefault(self):
  63. """
  64. L{NameVirtualHost.render} returns a response with a status of I{NOT
  65. FOUND} if the instance's C{default} is L{None} and there is no I{Host}
  66. header in the request.
  67. """
  68. virtualHostResource = NameVirtualHost()
  69. request = DummyRequest([''])
  70. d = _render(virtualHostResource, request)
  71. def cbRendered(ignored):
  72. self.assertEqual(request.responseCode, NOT_FOUND)
  73. d.addCallback(cbRendered)
  74. return d
  75. def test_renderWithHost(self):
  76. """
  77. L{NameVirtualHost.render} returns the result of rendering the resource
  78. which is the value in the instance's C{host} dictionary corresponding
  79. to the key indicated by the value of the I{Host} header in the request.
  80. """
  81. virtualHostResource = NameVirtualHost()
  82. virtualHostResource.addHost(b'example.org', Data(b"winner", ""))
  83. request = DummyRequest([b''])
  84. request.requestHeaders.addRawHeader(b'host', b'example.org')
  85. d = _render(virtualHostResource, request)
  86. def cbRendered(ignored, request):
  87. self.assertEqual(b''.join(request.written), b"winner")
  88. d.addCallback(cbRendered, request)
  89. # The port portion of the Host header should not be considered.
  90. requestWithPort = DummyRequest([b''])
  91. requestWithPort.requestHeaders.addRawHeader(b'host', b'example.org:8000')
  92. dWithPort = _render(virtualHostResource, requestWithPort)
  93. def cbRendered(ignored, requestWithPort):
  94. self.assertEqual(b''.join(requestWithPort.written), b"winner")
  95. dWithPort.addCallback(cbRendered, requestWithPort)
  96. return gatherResults([d, dWithPort])
  97. def test_renderWithUnknownHost(self):
  98. """
  99. L{NameVirtualHost.render} returns the result of rendering the
  100. instance's C{default} if it is not L{None} and there is no host
  101. matching the value of the I{Host} header in the request.
  102. """
  103. virtualHostResource = NameVirtualHost()
  104. virtualHostResource.default = Data(b"correct data", "")
  105. request = DummyRequest([b''])
  106. request.requestHeaders.addRawHeader(b'host', b'example.com')
  107. d = _render(virtualHostResource, request)
  108. def cbRendered(ignored):
  109. self.assertEqual(b''.join(request.written), b"correct data")
  110. d.addCallback(cbRendered)
  111. return d
  112. def test_renderWithUnknownHostNoDefault(self):
  113. """
  114. L{NameVirtualHost.render} returns a response with a status of I{NOT
  115. FOUND} if the instance's C{default} is L{None} and there is no host
  116. matching the value of the I{Host} header in the request.
  117. """
  118. virtualHostResource = NameVirtualHost()
  119. request = DummyRequest([''])
  120. request.requestHeaders.addRawHeader(b'host', b'example.com')
  121. d = _render(virtualHostResource, request)
  122. def cbRendered(ignored):
  123. self.assertEqual(request.responseCode, NOT_FOUND)
  124. d.addCallback(cbRendered)
  125. return d
  126. def test_getChild(self):
  127. """
  128. L{NameVirtualHost.getChild} returns correct I{Resource} based off
  129. the header and modifies I{Request} to ensure proper prepath and
  130. postpath are set.
  131. """
  132. virtualHostResource = NameVirtualHost()
  133. leafResource = Data(b"leaf data", "")
  134. leafResource.isLeaf = True
  135. normResource = Data(b"norm data", "")
  136. virtualHostResource.addHost(b'leaf.example.org', leafResource)
  137. virtualHostResource.addHost(b'norm.example.org', normResource)
  138. request = DummyRequest([])
  139. request.requestHeaders.addRawHeader(b'host', b'norm.example.org')
  140. request.prepath = [b'']
  141. self.assertIsInstance(virtualHostResource.getChild(b'', request),
  142. NoResource)
  143. self.assertEqual(request.prepath, [b''])
  144. self.assertEqual(request.postpath, [])
  145. request = DummyRequest([])
  146. request.requestHeaders.addRawHeader(b'host', b'leaf.example.org')
  147. request.prepath = [b'']
  148. self.assertIsInstance(virtualHostResource.getChild(b'', request),
  149. Data)
  150. self.assertEqual(request.prepath, [])
  151. self.assertEqual(request.postpath, [b''])
  152. class VHostMonsterResourceTests(TestCase):
  153. """
  154. Tests for L{VHostMonsterResource}.
  155. """
  156. def test_getChild(self):
  157. """
  158. L{VHostMonsterResource.getChild} returns I{_HostResource} and modifies
  159. I{Request} with correct L{Request.isSecure}.
  160. """
  161. vhm = VHostMonsterResource()
  162. request = DummyRequest([])
  163. self.assertIsInstance(vhm.getChild(b'http', request), _HostResource)
  164. self.assertFalse(request.isSecure())
  165. request = DummyRequest([])
  166. self.assertIsInstance(vhm.getChild(b'https', request), _HostResource)
  167. self.assertTrue(request.isSecure())