@@ -151,6 +151,11 @@ def __get_challenge():
151151
152152 def __get_authorization_code (self , client , auth_url , scope , state , challenge ):
153153 handler = OAuthHttpSingleRequestHandler ("Databricks Sql Connector" )
154+ # Bound the read of the accepted connection too (not just the accept
155+ # wait below). StreamRequestHandler.setup() applies this to the accepted
156+ # socket via settimeout(), so a client that connects but never completes
157+ # the request line can no longer block indefinitely.
158+ handler .timeout = self ._redirect_callback_timeout_seconds
154159
155160 last_error = None
156161 callback_timed_out = False
@@ -162,12 +167,13 @@ def __get_authorization_code(self, client, auth_url, scope, state, challenge):
162167 # flow) fails with a clear error instead of hanging forever.
163168 # NOTE: httpd.timeout bounds only the wait to ACCEPT an
164169 # incoming connection (it is the select() timeout used by
165- # handle_request). It does not bound the subsequent read of
166- # the HTTP request by the handler, so a client that connects
167- # but never completes the request line could still block. On
168- # this short-lived loopback server that residual gap is
169- # acceptable; the headless "no connection ever arrives" case
170- # (issue #458) is fully covered.
170+ # handle_request). The subsequent read of the HTTP request
171+ # line is bounded separately by the handler.timeout set
172+ # above (applied to the accepted socket by
173+ # StreamRequestHandler.setup()), so a client that connects
174+ # but never completes the request can no longer block. The
175+ # headless "no connection ever arrives" case (issue #458) is
176+ # covered by this accept-wait timeout.
171177 httpd .timeout = self ._redirect_callback_timeout_seconds
172178
173179 # HTTPServer.handle_request() returns normally (via
0 commit comments