test_http.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import platform
  2. from unittest.mock import patch
  3. import brotli
  4. import pytest
  5. import responses
  6. from django.core.exceptions import SuspiciousOperation
  7. from urllib3.util.connection import HAS_IPV6
  8. from sentry import http
  9. from sentry.testutils.helpers import override_blocklist
  10. @responses.activate
  11. @patch("socket.getaddrinfo")
  12. def test_simple(mock_getaddrinfo):
  13. mock_getaddrinfo.return_value = [(2, 1, 6, "", ("81.0.0.1", 0))]
  14. responses.add(responses.GET, "http://example.com", body="foo bar")
  15. resp = http.safe_urlopen("http://example.com")
  16. data = http.safe_urlread(resp)
  17. assert data.decode("utf-8") == "foo bar"
  18. request = responses.calls[0].request
  19. assert "User-Agent" in request.headers
  20. assert "gzip" in request.headers.get("Accept-Encoding", "")
  21. @override_blocklist("127.0.0.1", "::1", "10.0.0.0/8")
  22. # XXX(dcramer): we can't use responses here as it hooks Session.send
  23. # @responses.activate
  24. def test_ip_blacklist_ipv4():
  25. with pytest.raises(SuspiciousOperation):
  26. http.safe_urlopen("http://127.0.0.1")
  27. with pytest.raises(SuspiciousOperation):
  28. http.safe_urlopen("http://10.0.0.10")
  29. with pytest.raises(SuspiciousOperation):
  30. # '2130706433' is dword for '127.0.0.1'
  31. http.safe_urlopen("http://2130706433")
  32. @pytest.mark.skipif(not HAS_IPV6, reason="needs ipv6")
  33. @override_blocklist("::1")
  34. def test_ip_blacklist_ipv6():
  35. with pytest.raises(SuspiciousOperation):
  36. http.safe_urlopen("http://[::1]")
  37. @pytest.mark.skipif(HAS_IPV6, reason="stub for non-ipv6 systems")
  38. @override_blocklist("::1")
  39. @patch("socket.getaddrinfo")
  40. def test_ip_blacklist_ipv6_fallback(mock_getaddrinfo):
  41. mock_getaddrinfo.return_value = [(10, 1, 6, "", ("::1", 0, 0, 0))]
  42. with pytest.raises(SuspiciousOperation):
  43. http.safe_urlopen("http://[::1]")
  44. @pytest.mark.skipif(
  45. platform.system() == "Darwin", reason="macOS is always broken, see comment in sentry/http.py"
  46. )
  47. @override_blocklist("127.0.0.1")
  48. def test_garbage_ip():
  49. with pytest.raises(SuspiciousOperation):
  50. # '0177.0000.0000.0001' is an octal for '127.0.0.1'
  51. http.safe_urlopen("http://0177.0000.0000.0001")
  52. @responses.activate
  53. def test_fetch_file():
  54. responses.add(
  55. responses.GET, "http://example.com", body="foo bar", content_type="application/json"
  56. )
  57. result = http.fetch_file(url="http://example.com", domain_lock_enabled=False)
  58. assert result.body == b"foo bar"
  59. @responses.activate
  60. def test_fetch_file_brotli():
  61. body = brotli.compress(b"foo bar")
  62. responses.add(
  63. responses.GET,
  64. "http://example.com",
  65. body=body,
  66. content_type="application/json",
  67. adding_headers={"Content-Encoding": "br"},
  68. )
  69. result = http.fetch_file(url="http://example.com", domain_lock_enabled=False)
  70. assert result.body == b"foo bar"