test_http.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. # -*- coding: utf-8 -*-
  2. """
  3. :codeauthor: Nicole Thomas <nicole@saltstack.com>
  4. """
  5. # Import Python Libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. import socket
  8. from contextlib import closing
  9. import pytest
  10. # Import Salt Libs
  11. import salt.utils.http as http
  12. from tests.support.helpers import MirrorPostHandler, Webserver
  13. # Import Salt Testing Libs
  14. from tests.support.unit import TestCase
  15. class HTTPTestCase(TestCase):
  16. """
  17. Unit TestCase for the salt.utils.http module.
  18. """
  19. @classmethod
  20. def setUpClass(cls):
  21. cls.post_webserver = Webserver(handler=MirrorPostHandler)
  22. cls.post_webserver.start()
  23. cls.post_web_root = cls.post_webserver.web_root
  24. @classmethod
  25. def tearDownClass(cls):
  26. cls.post_webserver.stop()
  27. del cls.post_webserver
  28. # sanitize_url tests
  29. def test_sanitize_url_hide_fields_none(self):
  30. """
  31. Tests sanitizing a url when the hide_fields kwarg is None.
  32. """
  33. mock_url = "https://api.testing.com/?&foo=bar&test=testing"
  34. ret = http.sanitize_url(mock_url, hide_fields=None)
  35. self.assertEqual(ret, mock_url)
  36. def test_sanitize_url_no_elements(self):
  37. """
  38. Tests sanitizing a url when no elements should be sanitized.
  39. """
  40. mock_url = "https://api.testing.com/?&foo=bar&test=testing"
  41. ret = http.sanitize_url(mock_url, [""])
  42. self.assertEqual(ret, mock_url)
  43. def test_sanitize_url_single_element(self):
  44. """
  45. Tests sanitizing a url with only a single element to be sanitized.
  46. """
  47. mock_url = (
  48. "https://api.testing.com/?&keep_it_secret=abcdefghijklmn"
  49. "&api_action=module.function"
  50. )
  51. mock_ret = (
  52. "https://api.testing.com/?&keep_it_secret=XXXXXXXXXX&"
  53. "api_action=module.function"
  54. )
  55. ret = http.sanitize_url(mock_url, ["keep_it_secret"])
  56. self.assertEqual(ret, mock_ret)
  57. def test_sanitize_url_multiple_elements(self):
  58. """
  59. Tests sanitizing a url with multiple elements to be sanitized.
  60. """
  61. mock_url = (
  62. "https://api.testing.com/?rootPass=badpassword%21"
  63. "&skipChecks=True&api_key=abcdefghijklmn"
  64. "&NodeID=12345&api_action=module.function"
  65. )
  66. mock_ret = (
  67. "https://api.testing.com/?rootPass=XXXXXXXXXX"
  68. "&skipChecks=True&api_key=XXXXXXXXXX"
  69. "&NodeID=12345&api_action=module.function"
  70. )
  71. ret = http.sanitize_url(mock_url, ["api_key", "rootPass"])
  72. self.assertEqual(ret, mock_ret)
  73. # _sanitize_components tests
  74. def test_sanitize_components_no_elements(self):
  75. """
  76. Tests when zero elements need to be sanitized.
  77. """
  78. mock_component_list = ["foo=bar", "bar=baz", "hello=world"]
  79. mock_ret = "foo=bar&bar=baz&hello=world&"
  80. ret = http._sanitize_url_components(mock_component_list, "api_key")
  81. self.assertEqual(ret, mock_ret)
  82. def test_sanitize_components_one_element(self):
  83. """
  84. Tests a single component to be sanitized.
  85. """
  86. mock_component_list = ["foo=bar", "api_key=abcdefghijklmnop"]
  87. mock_ret = "foo=bar&api_key=XXXXXXXXXX&"
  88. ret = http._sanitize_url_components(mock_component_list, "api_key")
  89. self.assertEqual(ret, mock_ret)
  90. def test_sanitize_components_multiple_elements(self):
  91. """
  92. Tests two componenets to be sanitized.
  93. """
  94. mock_component_list = ["foo=bar", "foo=baz", "api_key=testing"]
  95. mock_ret = "foo=XXXXXXXXXX&foo=XXXXXXXXXX&api_key=testing&"
  96. ret = http._sanitize_url_components(mock_component_list, "foo")
  97. self.assertEqual(ret, mock_ret)
  98. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  99. def test_query_null_response(self):
  100. """
  101. This tests that we get a null response when raise_error=False and the
  102. host/port cannot be reached.
  103. """
  104. host = "127.0.0.1"
  105. # Find unused port
  106. with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
  107. sock.bind((host, 0))
  108. port = sock.getsockname()[1]
  109. url = "http://{host}:{port}/".format(host=host, port=port)
  110. result = http.query(url, raise_error=False)
  111. assert result == {"body": None}, result
  112. def test_requests_multipart_formdata_post(self):
  113. """
  114. Test handling of a multipart/form-data POST using the requests backend
  115. """
  116. match_this = '{0}\r\nContent-Disposition: form-data; name="fieldname_here"\r\n\r\nmydatahere\r\n{0}--\r\n'
  117. ret = http.query(
  118. self.post_web_root,
  119. method="POST",
  120. data="mydatahere",
  121. formdata=True,
  122. formdata_fieldname="fieldname_here",
  123. backend="requests",
  124. )
  125. body = ret.get("body", "")
  126. boundary = body[: body.find("\r")]
  127. self.assertEqual(body, match_this.format(boundary))