Skip to content

Commit fd550df

Browse files
authored
instrumentation/urllib3: fix urllib3 2.0.1+ crash with many args (#2002)
In c1dd69e we changed the logic of update_headers taking into account a new body arg before the one for headers. The problem is that HTTPConnectionPool.urlopen did not change at all, only HTTPConnectionPool.request did so the old login update_headers was fine. Fix #1928
1 parent bab896d commit fd550df

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

elasticapm/instrumentation/packages/urllib3.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,7 @@ def update_headers(args, kwargs, instance, transaction, trace_parent):
6161
:param trace_parent: the TraceParent object
6262
:return: an (args, kwargs) tuple
6363
"""
64-
from urllib3._version import __version__ as urllib3_version
65-
66-
if urllib3_version.startswith("2") and len(args) >= 5 and args[4]:
67-
headers = args[4].copy()
68-
args = tuple(itertools.chain((args[:4]), (headers,), args[5:]))
69-
elif len(args) >= 4 and args[3]:
64+
if len(args) >= 4 and args[3]:
7065
headers = args[3].copy()
7166
args = tuple(itertools.chain((args[:3]), (headers,), args[4:]))
7267
elif "headers" in kwargs and kwargs["headers"]:

tests/instrumentation/urllib3_tests.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,3 +294,20 @@ def test_instance_headers_are_respected(
294294
assert "kwargs" in request_headers
295295
if instance_headers and not (header_arg or header_kwarg):
296296
assert "instance" in request_headers
297+
298+
299+
def test_connection_pool_urlopen_does_not_crash_with_many_args(instrument, elasticapm_client, waiting_httpserver):
300+
"""Mimics ConnectionPool.urlopen error path with broken connection, see #1928"""
301+
waiting_httpserver.serve_content("")
302+
url = waiting_httpserver.url + "/hello_world"
303+
parsed_url = urllib.parse.urlparse(url)
304+
pool = urllib3.HTTPConnectionPool(
305+
parsed_url.hostname,
306+
parsed_url.port,
307+
maxsize=1,
308+
block=True,
309+
)
310+
retry = urllib3.util.Retry(10)
311+
elasticapm_client.begin_transaction("transaction")
312+
r = pool.urlopen("GET", url, None, {"args": "true"}, retry, False, False)
313+
assert r.status == 200

0 commit comments

Comments
 (0)