| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent ec3527d commit 592bacb
1 file changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4672,12 +4672,16 @@ class TestPreHandshakeClose(unittest.TestCase): | |||
| 4672 | 4672 | ||
| 4673 | 4673 | class SingleConnectionTestServerThread(threading.Thread): | |
| 4674 | 4674 | ||
| 4675 | - def __init__(self, *, name, call_after_accept): | ||
| 4675 | + def __init__(self, *, name, call_after_accept, timeout=None): | ||
| 4676 | 4676 | self.call_after_accept = call_after_accept | |
| 4677 | 4677 | self.received_data = b'' # set by .run() | |
| 4678 | 4678 | self.wrap_error = None # set by .run() | |
| 4679 | 4679 | self.listener = None # set by .start() | |
| 4680 | 4680 | self.port = None # set by .start() | |
| 4681 | + if timeout is None: | ||
| 4682 | + self.timeout = support.SHORT_TIMEOUT | ||
| 4683 | + else: | ||
| 4684 | + self.timeout = timeout | ||
| 4681 | 4685 | super().__init__(name=name) | |
| 4682 | 4686 | ||
| 4683 | 4687 | def __enter__(self): | |
@@ -4700,13 +4704,19 @@ def start(self): | |||
| 4700 | 4704 | self.ssl_ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY) | |
| 4701 | 4705 | self.listener = socket.socket() | |
| 4702 | 4706 | self.port = socket_helper.bind_port(self.listener) | |
| 4703 | - self.listener.settimeout(2.0) | ||
| 4707 | + self.listener.settimeout(self.timeout) | ||
| 4704 | 4708 | self.listener.listen(1) | |
| 4705 | 4709 | super().start() | |
| 4706 | 4710 | ||
| 4707 | 4711 | def run(self): | |
| 4708 | - conn, address = self.listener.accept() | ||
| 4709 | - self.listener.close() | ||
| 4712 | + try: | ||
| 4713 | + conn, address = self.listener.accept() | ||
| 4714 | + except TimeoutError: | ||
| 4715 | + # on timeout, just close the listener | ||
| 4716 | + return | ||
| 4717 | + finally: | ||
| 4718 | + self.listener.close() | ||
| 4719 | + | ||
| 4710 | 4720 | with conn: | |
| 4711 | 4721 | if self.call_after_accept(conn): | |
| 4712 | 4722 | return | |
@@ -4734,8 +4744,13 @@ def non_linux_skip_if_other_okay_error(self, err): | |||
| 4734 | 4744 | # we're specifically trying to test. The way this test is written | |
| 4735 | 4745 | # is known to work on Linux. We'll skip it anywhere else that it | |
| 4736 | 4746 | # does not present as doing so. | |
| 4737 | - self.skipTest(f"Could not recreate conditions on {sys.platform}:" | ||
| 4738 | - f" {err=}") | ||
| 4747 | + try: | ||
| 4748 | + self.skipTest(f"Could not recreate conditions on {sys.platform}:" | ||
| 4749 | + f" {err=}") | ||
| 4750 | + finally: | ||
| 4751 | + # gh-108342: Explicitly break the reference cycle | ||
| 4752 | + err = None | ||
| 4753 | + | ||
| 4739 | 4754 | # If maintaining this conditional winds up being a problem. | |
| 4740 | 4755 | # just turn this into an unconditional skip anything but Linux. | |
| 4741 | 4756 | # The important thing is that our CI has the logic covered. | |
@@ -4746,7 +4761,7 @@ def test_preauth_data_to_tls_server(self): | |||
| 4746 | 4761 | ||
| 4747 | 4762 | def call_after_accept(unused): | |
| 4748 | 4763 | server_accept_called.set() | |
| 4749 | - if not ready_for_server_wrap_socket.wait(2.0): | ||
| 4764 | + if not ready_for_server_wrap_socket.wait(support.SHORT_TIMEOUT): | ||
| 4750 | 4765 | raise RuntimeError("wrap_socket event never set, test may fail.") | |
| 4751 | 4766 | return False # Tell the server thread to continue. | |
| 4752 | 4767 | ||
@@ -4767,20 +4782,31 @@ def call_after_accept(unused): | |||
| 4767 | 4782 | ||
| 4768 | 4783 | ready_for_server_wrap_socket.set() | |
| 4769 | 4784 | server.join() | |
| 4785 | + | ||
| 4770 | 4786 | wrap_error = server.wrap_error | |
| 4771 | - self.assertEqual(b"", server.received_data) | ||
| 4772 | - self.assertIsInstance(wrap_error, OSError) # All platforms. | ||
| 4773 | - self.non_linux_skip_if_other_okay_error(wrap_error) | ||
| 4774 | - self.assertIsInstance(wrap_error, ssl.SSLError) | ||
| 4775 | - self.assertIn("before TLS handshake with data", wrap_error.args[1]) | ||
| 4776 | - self.assertIn("before TLS handshake with data", wrap_error.reason) | ||
| 4777 | - self.assertNotEqual(0, wrap_error.args[0]) | ||
| 4778 | - self.assertIsNone(wrap_error.library, msg="attr must exist") | ||
| 4787 | + server.wrap_error = None | ||
| 4788 | + try: | ||
| 4789 | + self.assertEqual(b"", server.received_data) | ||
| 4790 | + self.assertIsInstance(wrap_error, OSError) # All platforms. | ||
| 4791 | + self.non_linux_skip_if_other_okay_error(wrap_error) | ||
| 4792 | + self.assertIsInstance(wrap_error, ssl.SSLError) | ||
| 4793 | + self.assertIn("before TLS handshake with data", wrap_error.args[1]) | ||
| 4794 | + self.assertIn("before TLS handshake with data", wrap_error.reason) | ||
| 4795 | + self.assertNotEqual(0, wrap_error.args[0]) | ||
| 4796 | + self.assertIsNone(wrap_error.library, msg="attr must exist") | ||
| 4797 | + finally: | ||
| 4798 | + # gh-108342: Explicitly break the reference cycle | ||
| 4799 | + wrap_error = None | ||
| 4800 | + server = None | ||
| 4779 | 4801 | ||
| 4780 | 4802 | def test_preauth_data_to_tls_client(self): | |
| 4803 | + server_can_continue_with_wrap_socket = threading.Event() | ||
| 4781 | 4804 | client_can_continue_with_wrap_socket = threading.Event() | |
| 4782 | 4805 | ||
| 4783 | 4806 | def call_after_accept(conn_to_client): | |
| 4807 | + if not server_can_continue_with_wrap_socket.wait(support.SHORT_TIMEOUT): | ||
| 4808 | + print("ERROR: test client took too long") | ||
| 4809 | + | ||
| 4784 | 4810 | # This forces an immediate connection close via RST on .close(). | |
| 4785 | 4811 | set_socket_so_linger_on_with_zero_timeout(conn_to_client) | |
| 4786 | 4812 | conn_to_client.send( | |
@@ -4800,8 +4826,10 @@ def call_after_accept(conn_to_client): | |||
| 4800 | 4826 | ||
| 4801 | 4827 | with socket.socket() as client: | |
| 4802 | 4828 | client.connect(server.listener.getsockname()) | |
| 4803 | - if not client_can_continue_with_wrap_socket.wait(2.0): | ||
| 4804 | - self.fail("test server took too long.") | ||
| 4829 | + server_can_continue_with_wrap_socket.set() | ||
| 4830 | + | ||
| 4831 | + if not client_can_continue_with_wrap_socket.wait(support.SHORT_TIMEOUT): | ||
| 4832 | + self.fail("test server took too long") | ||
| 4805 | 4833 | ssl_ctx = ssl.create_default_context() | |
| 4806 | 4834 | try: | |
| 4807 | 4835 | tls_client = ssl_ctx.wrap_socket( | |
@@ -4815,24 +4843,31 @@ def call_after_accept(conn_to_client): | |||
| 4815 | 4843 | tls_client.close() | |
| 4816 | 4844 | ||
| 4817 | 4845 | server.join() | |
| 4818 | - self.assertEqual(b"", received_data) | ||
| 4819 | - self.assertIsInstance(wrap_error, OSError) # All platforms. | ||
| 4820 | - self.non_linux_skip_if_other_okay_error(wrap_error) | ||
| 4821 | - self.assertIsInstance(wrap_error, ssl.SSLError) | ||
| 4822 | - self.assertIn("before TLS handshake with data", wrap_error.args[1]) | ||
| 4823 | - self.assertIn("before TLS handshake with data", wrap_error.reason) | ||
| 4824 | - self.assertNotEqual(0, wrap_error.args[0]) | ||
| 4825 | - self.assertIsNone(wrap_error.library, msg="attr must exist") | ||
| 4846 | + try: | ||
| 4847 | + self.assertEqual(b"", received_data) | ||
| 4848 | + self.assertIsInstance(wrap_error, OSError) # All platforms. | ||
| 4849 | + self.non_linux_skip_if_other_okay_error(wrap_error) | ||
| 4850 | + self.assertIsInstance(wrap_error, ssl.SSLError) | ||
| 4851 | + self.assertIn("before TLS handshake with data", wrap_error.args[1]) | ||
| 4852 | + self.assertIn("before TLS handshake with data", wrap_error.reason) | ||
| 4853 | + self.assertNotEqual(0, wrap_error.args[0]) | ||
| 4854 | + self.assertIsNone(wrap_error.library, msg="attr must exist") | ||
| 4855 | + finally: | ||
| 4856 | + # gh-108342: Explicitly break the reference cycle | ||
| 4857 | + wrap_error = None | ||
| 4858 | + server = None | ||
| 4826 | 4859 | ||
| 4827 | 4860 | def test_https_client_non_tls_response_ignored(self): | |
| 4828 | - | ||
| 4829 | 4861 | server_responding = threading.Event() | |
| 4830 | 4862 | ||
| 4831 | 4863 | class SynchronizedHTTPSConnection(http.client.HTTPSConnection): | |
| 4832 | 4864 | def connect(self): | |
| 4865 | + # Call clear text HTTP connect(), not the encrypted HTTPS (TLS) | ||
| 4866 | + # connect(): wrap_socket() is called manually below. | ||
| 4833 | 4867 | http.client.HTTPConnection.connect(self) | |
| 4868 | + | ||
| 4834 | 4869 | # Wait for our fault injection server to have done its thing. | |
| 4835 | - if not server_responding.wait(1.0) and support.verbose: | ||
| 4870 | + if not server_responding.wait(support.SHORT_TIMEOUT) and support.verbose: | ||
| 4836 | 4871 | sys.stdout.write("server_responding event never set.") | |
| 4837 | 4872 | self.sock = self._context.wrap_socket( | |
| 4838 | 4873 | self.sock, server_hostname=self.host) | |
@@ -4847,28 +4882,33 @@ def call_after_accept(conn_to_client): | |||
| 4847 | 4882 | server_responding.set() | |
| 4848 | 4883 | return True # Tell the server to stop. | |
| 4849 | 4884 | ||
| 4885 | + timeout = 2.0 | ||
| 4850 | 4886 | server = self.SingleConnectionTestServerThread( | |
| 4851 | 4887 | call_after_accept=call_after_accept, | |
| 4852 | - name="non_tls_http_RST_responder") | ||
| 4888 | + name="non_tls_http_RST_responder", | ||
| 4889 | + timeout=timeout) | ||
| 4853 | 4890 | self.enterContext(server) # starts it & unittest.TestCase stops it. | |
| 4854 | 4891 | # Redundant; call_after_accept sets SO_LINGER on the accepted conn. | |
| 4855 | 4892 | set_socket_so_linger_on_with_zero_timeout(server.listener) | |
| 4856 | 4893 | ||
| 4857 | 4894 | connection = SynchronizedHTTPSConnection( | |
| 4858 | - f"localhost", | ||
| 4895 | + server.listener.getsockname()[0], | ||
| 4859 | 4896 | port=server.port, | |
| 4860 | 4897 | context=ssl.create_default_context(), | |
| 4861 | - timeout=2.0, | ||
| 4898 | + timeout=timeout, | ||
| 4862 | 4899 | ) | |
| 4900 | + | ||
| 4863 | 4901 | # There are lots of reasons this raises as desired, long before this | |
| 4864 | 4902 | # test was added. Sending the request requires a successful TLS wrapped | |
| 4865 | 4903 | # socket; that fails if the connection is broken. It may seem pointless | |
| 4866 | 4904 | # to test this. It serves as an illustration of something that we never | |
| 4867 | 4905 | # want to happen... properly not happening. | |
| 4868 | - with self.assertRaises(OSError) as err_ctx: | ||
| 4906 | + with self.assertRaises(OSError): | ||
| 4869 | 4907 | connection.request("HEAD", "/test", headers={"Host": "localhost"}) | |
| 4870 | 4908 | response = connection.getresponse() | |
| 4871 | 4909 | ||
| 4910 | + server.join() | ||
| 4911 | + | ||
| 4872 | 4912 | ||
| 4873 | 4913 | class TestEnumerations(unittest.TestCase): | |
| 4874 | 4914 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments