@@ -3675,6 +3675,59 @@ def call_after_accept(conn_to_client):
36753675 self .assertNotEqual (0 , wrap_error .args [0 ])
36763676 self .assertIsNone (wrap_error .library , msg = "attr must exist" )
36773677
3678+ def test_https_client_non_tls_response_ignored (self ):
3679+ server_responding = threading .Event ()
3680+
3681+ class SynchronizedHTTPSConnection (http .client .HTTPSConnection ):
3682+ def connect (self ):
3683+ # Call clear text HTTP connect(), not the encrypted HTTPS (TLS)
3684+ # connect(): wrap_socket() is called manually below.
3685+ http .client .HTTPConnection .connect (self )
3686+
3687+ # Wait for our fault injection server to have done its thing.
3688+ if not server_responding .wait (support .SHORT_TIMEOUT ) and support .verbose :
3689+ sys .stdout .write ("server_responding event never set." )
3690+ self .sock = self ._context .wrap_socket (
3691+ self .sock , server_hostname = self .host )
3692+
3693+ def call_after_accept (conn_to_client ):
3694+ # This forces an immediate connection close via RST on .close().
3695+ set_socket_so_linger_on_with_zero_timeout (conn_to_client )
3696+ conn_to_client .send (
3697+ b"HTTP/1.0 402 Payment Required\r \n "
3698+ b"\r \n " )
3699+ conn_to_client .close () # RST
3700+ server_responding .set ()
3701+ return True # Tell the server to stop.
3702+
3703+ timeout = 2.0
3704+ server = self .SingleConnectionTestServerThread (
3705+ call_after_accept = call_after_accept ,
3706+ name = "non_tls_http_RST_responder" ,
3707+ timeout = timeout )
3708+ server .__enter__ () # starts it
3709+ self .addCleanup (server .__exit__ ) # ... & unittest.TestCase stops it.
3710+ # Redundant; call_after_accept sets SO_LINGER on the accepted conn.
3711+ set_socket_so_linger_on_with_zero_timeout (server .listener )
3712+
3713+ connection = SynchronizedHTTPSConnection (
3714+ server .listener .getsockname ()[0 ],
3715+ port = server .port ,
3716+ context = ssl .create_default_context (),
3717+ timeout = timeout ,
3718+ )
3719+
3720+ # There are lots of reasons this raises as desired, long before this
3721+ # test was added. Sending the request requires a successful TLS wrapped
3722+ # socket; that fails if the connection is broken. It may seem pointless
3723+ # to test this. It serves as an illustration of something that we never
3724+ # want to happen... properly not happening.
3725+ with self .assertRaises (OSError ):
3726+ connection .request ("HEAD" , "/test" , headers = {"Host" : "localhost" })
3727+ response = connection .getresponse ()
3728+
3729+ server .join ()
3730+
36783731
36793732def test_main (verbose = False ):
36803733 if support .verbose :
0 commit comments