8000 Merge pull request #493 from kevinburke/raise-timeout · python-telegram-bot/urllib3@fbfc9d9 · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on May 21, 2023. It is now read-only.

Commit fbfc9d9

Browse files
committed
Merge pull request urllib3#493 from kevinburke/raise-timeout
Raise timeout error instead of SSLError on handshake timeout.
2 parents df4ec5c + c385177 commit fbfc9d9

File tree

2 files changed

+43
-23
lines changed

2 files changed

+43
-23
lines changed

test/with_dummyserver/test_socketlevel.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,24 @@ def socket_handler(listener):
137137
finally:
138138
timed_out.set()
139139

140+
def test_https_connection_read_timeout(self):
141+
""" Handshake timeouts should fail with a Timeout"""
142+
timed_out = Event()
143+
def socket_handler(listener):
144+
sock = listener.accept()[0]
145+
while not sock.recv(65536):
146+
pass
147+
148+
timed_out.wait()
149+
sock.close()
150+
151+
self._start_server(socket_handler)
152+
pool = HTTPSConnectionPool(self.host, self.port, timeout=0.001, retries=False)
153+
try:
154+
self.assertRaises(ReadTimeoutError, pool.request, 'GET', '/')
155+
finally:
156+
timed_out.set()
157+
140158
def test_timeout_errors_cause_retries(self):
141159
def socket_handler(listener):
142160
sock_timeout = listener.accept()[0]

urllib3/connectionpool.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,23 @@ def _get_timeout(self, timeout):
278278
# can be removed later
279279
return Timeout.from_float(timeout)
280280

281+
def _raise_timeout(self, err, url, timeout_value):
282+
"""Is the error actually a timeout? Will raise a ReadTimeout or pass"""
283+
284+
if isinstance(err, SocketTimeout):
285+
raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
286+
287+
# See the above comment about EAGAIN in Python 3. In Python 2 we have
288+
# to specifically catch it and throw the timeout error
289+
if hasattr(err, 'errno') and err.errno in _blocking_errnos:
290+
raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
291+
292+
# Catch possible read timeouts thrown as SSL errors. If not the
293+
# case, rethrow the original. We need to do this because of:
294+
# http://bugs.python.org/issue10272
295+
if 'timed out' in str(err) or 'did not complete (read)' in str(err): # Python 2.6
296+
raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
297+
281298
def _make_request(self, conn, method, url, timeout=_Default,
282299
**httplib_request_kw):
283300
"""
@@ -301,7 +318,12 @@ def _make_request(self, conn, method, url, timeout=_Default,
301318
conn.timeout = timeout_obj.connect_timeout
302319

303320
# Trigger any extra validation we need to do.
304-
self._validate_conn(conn)
321+
try:
322+
self._validate_conn(conn)
323+
except (SocketTimeout, BaseSSLError) as e:
324+
# Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout.
325+
self._raise_timeout(err=e, url=url, timeout_value=conn.timeout)
326+
raise
305327

306328
# conn.request() calls httplib.*.request, not the method in
307329
# urllib3.request. It also calls makefile (recv) on the socket.
@@ -331,28 +353,8 @@ def _make_request(self, conn, method, url, timeout=_Default,
331353
httplib_response = conn.getresponse(buffering=True)
332354
except TypeError: # Python 2.6 and older
333355
httplib_response = conn.getresponse()
334-
except SocketTimeout:
335-
raise ReadTimeoutError(
336-
self, url, "Read timed out. (read timeout=%s)" % read_timeout)
337-
338-
except BaseSSLError as e:
339-
# Catch possible read timeouts thrown as SSL errors. If not the
340-
# case, rethrow the original. We need to do this because of:
341-
# http://bugs.python.org/issue10272
342-
if 'timed out' in str(e) or \
343-
'did not complete (read)' in str(e): # Python 2.6
344-
raise ReadTimeoutError(
345-
self, url, "Read timed out. (read timeout=%s)" % read_timeout)
346-
347-
raise
348-
349-
except SocketError as e: # Platform-specific: Python 2
350-
# See the above comment about EAGAIN in Python 3. In Python 2 we
351-
# have to specifically catch it and throw the timeout error
352-
if e.errno in _blocking_errnos:
353-
raise ReadTimeoutError(
354-
self, url, "Read timed out. (read timeout=%s)" % read_timeout)
355-
356+
except (SocketTimeout, BaseSSLError, SocketError) as e:
357+
self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
356358
raise
357359

358360
# AppEngine doesn't have a version attr.

0 commit comments

Comments
 (0)
0