test_v1parser.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Test cases for L{twisted.protocols.haproxy.V1Parser}.
  5. """
  6. from twisted.trial import unittest
  7. from twisted.internet import address
  8. from .._exceptions import (
  9. InvalidProxyHeader, InvalidNetworkProtocol, MissingAddressData
  10. )
  11. from .. import _v1parser
  12. class V1ParserTests(unittest.TestCase):
  13. """
  14. Test L{twisted.protocols.haproxy.V1Parser} behaviour.
  15. """
  16. def test_missingPROXYHeaderValue(self):
  17. """
  18. Test that an exception is raised when the PROXY header is missing.
  19. """
  20. self.assertRaises(
  21. InvalidProxyHeader,
  22. _v1parser.V1Parser.parse,
  23. b'NOTPROXY ',
  24. )
  25. def test_invalidNetworkProtocol(self):
  26. """
  27. Test that an exception is raised when the proto is not TCP or UNKNOWN.
  28. """
  29. self.assertRaises(
  30. InvalidNetworkProtocol,
  31. _v1parser.V1Parser.parse,
  32. b'PROXY WUTPROTO ',
  33. )
  34. def test_missingSourceData(self):
  35. """
  36. Test that an exception is raised when the proto has no source data.
  37. """
  38. self.assertRaises(
  39. MissingAddressData,
  40. _v1parser.V1Parser.parse,
  41. b'PROXY TCP4 ',
  42. )
  43. def test_missingDestData(self):
  44. """
  45. Test that an exception is raised when the proto has no destination.
  46. """
  47. self.assertRaises(
  48. MissingAddressData,
  49. _v1parser.V1Parser.parse,
  50. b'PROXY TCP4 127.0.0.1 8080 8888',
  51. )
  52. def test_fullParsingSuccess(self):
  53. """
  54. Test that parsing is successful for a PROXY header.
  55. """
  56. info = _v1parser.V1Parser.parse(
  57. b'PROXY TCP4 127.0.0.1 127.0.0.1 8080 8888',
  58. )
  59. self.assertIsInstance(info.source, address.IPv4Address)
  60. self.assertEqual(info.source.host, b'127.0.0.1')
  61. self.assertEqual(info.source.port, 8080)
  62. self.assertEqual(info.destination.host, b'127.0.0.1')
  63. self.assertEqual(info.destination.port, 8888)
  64. def test_fullParsingSuccess_IPv6(self):
  65. """
  66. Test that parsing is successful for an IPv6 PROXY header.
  67. """
  68. info = _v1parser.V1Parser.parse(
  69. b'PROXY TCP6 ::1 ::1 8080 8888',
  70. )
  71. self.assertIsInstance(info.source, address.IPv6Address)
  72. self.assertEqual(info.source.host, b'::1')
  73. self.assertEqual(info.source.port, 8080)
  74. self.assertEqual(info.destination.host, b'::1')
  75. self.assertEqual(info.destination.port, 8888)
  76. def test_fullParsingSuccess_UNKNOWN(self):
  77. """
  78. Test that parsing is successful for a UNKNOWN PROXY header.
  79. """
  80. info = _v1parser.V1Parser.parse(
  81. b'PROXY UNKNOWN anything could go here',
  82. )
  83. self.assertIsNone(info.source)
  84. self.assertIsNone(info.destination)
  85. def test_feedParsing(self):
  86. """
  87. Test that parsing happens when fed a complete line.
  88. """
  89. parser = _v1parser.V1Parser()
  90. info, remaining = parser.feed(b'PROXY TCP4 127.0.0.1 127.0.0.1 ')
  91. self.assertFalse(info)
  92. self.assertFalse(remaining)
  93. info, remaining = parser.feed(b'8080 8888')
  94. self.assertFalse(info)
  95. self.assertFalse(remaining)
  96. info, remaining = parser.feed(b'\r\n')
  97. self.assertFalse(remaining)
  98. self.assertIsInstance(info.source, address.IPv4Address)
  99. self.assertEqual(info.source.host, b'127.0.0.1')
  100. self.assertEqual(info.source.port, 8080)
  101. self.assertEqual(info.destination.host, b'127.0.0.1')
  102. self.assertEqual(info.destination.port, 8888)
  103. def test_feedParsingTooLong(self):
  104. """
  105. Test that parsing fails if no newline is found in 108 bytes.
  106. """
  107. parser = _v1parser.V1Parser()
  108. info, remaining = parser.feed(b'PROXY TCP4 127.0.0.1 127.0.0.1 ')
  109. self.assertFalse(info)
  110. self.assertFalse(remaining)
  111. info, remaining = parser.feed(b'8080 8888')
  112. self.assertFalse(info)
  113. self.assertFalse(remaining)
  114. self.assertRaises(
  115. InvalidProxyHeader,
  116. parser.feed,
  117. b' ' * 100,
  118. )
  119. def test_feedParsingOverflow(self):
  120. """
  121. Test that parsing leaves overflow bytes in the buffer.
  122. """
  123. parser = _v1parser.V1Parser()
  124. info, remaining = parser.feed(
  125. b'PROXY TCP4 127.0.0.1 127.0.0.1 8080 8888\r\nHTTP/1.1 GET /\r\n',
  126. )
  127. self.assertTrue(info)
  128. self.assertEqual(remaining, b'HTTP/1.1 GET /\r\n')
  129. self.assertFalse(parser.buffer)