test_11_unix.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. #***************************************************************************
  4. # _ _ ____ _
  5. # Project ___| | | | _ \| |
  6. # / __| | | | |_) | |
  7. # | (__| |_| | _ <| |___
  8. # \___|\___/|_| \_\_____|
  9. #
  10. # Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
  11. #
  12. # This software is licensed as described in the file COPYING, which
  13. # you should have received as part of this distribution. The terms
  14. # are also available at https://curl.se/docs/copyright.html.
  15. #
  16. # You may opt to use, copy, modify, merge, publish, distribute and/or sell
  17. # copies of the Software, and permit persons to whom the Software is
  18. # furnished to do so, under the terms of the COPYING file.
  19. #
  20. # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  21. # KIND, either express or implied.
  22. #
  23. # SPDX-License-Identifier: curl
  24. #
  25. ###########################################################################
  26. #
  27. import logging
  28. import os
  29. import socket
  30. from threading import Thread
  31. from typing import Generator
  32. import pytest
  33. from testenv import Env, CurlClient
  34. log = logging.getLogger(__name__)
  35. class UDSFaker:
  36. def __init__(self, path):
  37. self._uds_path = path
  38. self._done = False
  39. self._socket = None
  40. @property
  41. def path(self):
  42. return self._uds_path
  43. def start(self):
  44. def process(self):
  45. self._socket.listen(1)
  46. self._process()
  47. try:
  48. os.unlink(self._uds_path)
  49. except OSError:
  50. if os.path.exists(self._uds_path):
  51. raise
  52. self._socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  53. self._socket.bind(self._uds_path)
  54. self._thread = Thread(target=process, daemon=True, args=[self])
  55. self._thread.start()
  56. def stop(self):
  57. self._done = True
  58. self._socket.close()
  59. def _process(self):
  60. while self._done is False:
  61. try:
  62. c, client_address = self._socket.accept()
  63. try:
  64. c.recv(16)
  65. c.sendall("""HTTP/1.1 200 Ok
  66. Server: UdsFaker
  67. Content-Type: application/json
  68. Content-Length: 19
  69. { "host": "faked" }""".encode())
  70. finally:
  71. c.close()
  72. except ConnectionAbortedError:
  73. self._done = True
  74. except OSError:
  75. self._done = True
  76. class TestUnix:
  77. @pytest.fixture(scope="class")
  78. def uds_faker(self, env: Env) -> Generator[UDSFaker, None, None]:
  79. uds_path = os.path.join(env.gen_dir, 'uds_11.sock')
  80. faker = UDSFaker(path=uds_path)
  81. faker.start()
  82. yield faker
  83. faker.stop()
  84. # download http: via Unix socket
  85. def test_11_01_unix_connect_http(self, env: Env, httpd, uds_faker, repeat):
  86. curl = CurlClient(env=env)
  87. url = f'http://{env.domain1}:{env.http_port}/data.json'
  88. r = curl.http_download(urls=[url], with_stats=True,
  89. extra_args=[
  90. '--unix-socket', uds_faker.path,
  91. ])
  92. r.check_response(count=1, http_status=200)
  93. # download https: via Unix socket
  94. @pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason="curl without SSL")
  95. def test_11_02_unix_connect_http(self, env: Env, httpd, uds_faker, repeat):
  96. curl = CurlClient(env=env)
  97. url = f'https://{env.domain1}:{env.https_port}/data.json'
  98. r = curl.http_download(urls=[url], with_stats=True,
  99. extra_args=[
  100. '--unix-socket', uds_faker.path,
  101. ])
  102. r.check_response(exitcode=35, http_status=None)
  103. # download HTTP/3 via Unix socket
  104. @pytest.mark.skipif(condition=not Env.have_h3(), reason='h3 not supported')
  105. def test_11_03_unix_connect_quic(self, env: Env, httpd, uds_faker, repeat):
  106. curl = CurlClient(env=env)
  107. url = f'https://{env.domain1}:{env.https_port}/data.json'
  108. r = curl.http_download(urls=[url], with_stats=True,
  109. alpn_proto='h3',
  110. extra_args=[
  111. '--unix-socket', uds_faker.path,
  112. ])
  113. r.check_response(exitcode=96, http_status=None)