test_11_unix.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. import pytest
  32. from testenv import Env, CurlClient
  33. log = logging.getLogger(__name__)
  34. class UDSFaker:
  35. def __init__(self, path):
  36. self._uds_path = path
  37. self._done = False
  38. @property
  39. def path(self):
  40. return self._uds_path
  41. def start(self):
  42. def process(self):
  43. self._socket.listen(1)
  44. self._process()
  45. try:
  46. os.unlink(self._uds_path)
  47. except OSError:
  48. if os.path.exists(self._uds_path):
  49. raise
  50. self._socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  51. self._socket.bind(self._uds_path)
  52. self._thread = Thread(target=process, daemon=True, args=[self])
  53. self._thread.start()
  54. def stop(self):
  55. self._done = True
  56. self._socket.close()
  57. def _process(self):
  58. while self._done is False:
  59. try:
  60. c, client_address = self._socket.accept()
  61. try:
  62. data = c.recv(16)
  63. c.sendall("""HTTP/1.1 200 Ok
  64. Server: UdsFaker
  65. Content-Type: application/json
  66. Content-Length: 19
  67. { "host": "faked" }""".encode())
  68. finally:
  69. c.close()
  70. except ConnectionAbortedError:
  71. self._done = True
  72. except OSError:
  73. self._done = True
  74. class TestUnix:
  75. @pytest.fixture(scope="class")
  76. def uds_faker(self, env: Env) -> UDSFaker:
  77. uds_path = os.path.join(env.gen_dir, 'uds_11.sock')
  78. faker = UDSFaker(path=uds_path)
  79. faker.start()
  80. yield faker
  81. faker.stop()
  82. # download http: via unix socket
  83. def test_11_01_unix_connect_http(self, env: Env, httpd, uds_faker, repeat):
  84. curl = CurlClient(env=env)
  85. url = f'http://{env.domain1}:{env.http_port}/data.json'
  86. r = curl.http_download(urls=[url], with_stats=True,
  87. extra_args=[
  88. '--unix-socket', uds_faker.path,
  89. ])
  90. r.check_response(count=1, http_status=200)
  91. # download https: via unix socket
  92. @pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason=f"curl without SSL")
  93. def test_11_02_unix_connect_http(self, env: Env, httpd, uds_faker, repeat):
  94. curl = CurlClient(env=env)
  95. url = f'https://{env.domain1}:{env.https_port}/data.json'
  96. r = curl.http_download(urls=[url], with_stats=True,
  97. extra_args=[
  98. '--unix-socket', uds_faker.path,
  99. ])
  100. r.check_response(exitcode=35, http_status=None)
  101. # download HTTP/3 via unix socket
  102. @pytest.mark.skipif(condition=not Env.have_h3(), reason='h3 not supported')
  103. def test_11_03_unix_connect_quic(self, env: Env, httpd, uds_faker, repeat):
  104. curl = CurlClient(env=env)
  105. url = f'https://{env.domain1}:{env.https_port}/data.json'
  106. r = curl.http_download(urls=[url], with_stats=True,
  107. alpn_proto='h3',
  108. extra_args=[
  109. '--unix-socket', uds_faker.path,
  110. ])
  111. r.check_response(exitcode=96, http_status=None)