From: Sophie Brun <sophie@offensive-security.com>
Date: Wed, 28 May 2025 08:57:29 +0200
Subject: Fix a NameError in hook_urllib3_parse_url.py

File "/usr/lib/python3/dist-packages/requests/sessions.py", line 484, in prepare_request
    p.prepare(
    ~~~~~~~~~^
        method=request.method.upper(),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<10 lines>...
        hooks=merge_hooks(request.hooks, self.hooks),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/lib/python3/dist-packages/requests/models.py", line 367, in prepare
    self.prepare_url(url, params)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/requests/models.py", line 433, in prepare_url
    scheme, auth, host, port, path, query, fragment = parse_url(url)
                                                      ~~~~~~~~~^^^^^
  File "/usr/lib/python3/dist-packages/pocsuite3/lib/request/patch/hook_urllib3_parse_url.py", line 191, in patched_parse_url
    url, path_, delim = split_first(url, ['/', '?', '#'])
                        ^^^^^^^^^^^
NameError: name 'split_first' is not defined
---
 .../lib/request/patch/hook_urllib3_parse_url.py    | 65 +++++++++++-----------
 1 file changed, 32 insertions(+), 33 deletions(-)

diff --git a/pocsuite3/lib/request/patch/hook_urllib3_parse_url.py b/pocsuite3/lib/request/patch/hook_urllib3_parse_url.py
index ad35c71..53e3458 100644
--- a/pocsuite3/lib/request/patch/hook_urllib3_parse_url.py
+++ b/pocsuite3/lib/request/patch/hook_urllib3_parse_url.py
@@ -115,39 +115,6 @@ class Url(namedtuple('Url', url_attrs)):
         return self.url
 
 
-def split_first(s, delims):
-    """
-    Given a string and an iterable of delimiters, split on the first found
-    delimiter. Return two split parts and the matched delimiter.
-
-    If not found, then the first part is the full input string.
-
-    Example::
-
-        >>> split_first('foo/bar?baz', '?/=')
-        ('foo', 'bar?baz', '/')
-        >>> split_first('foo/bar?baz', '123')
-        ('foo/bar?baz', '', None)
-
-    Scales linearly with number of delims. Not ideal for large number of delims.
-    """
-    min_idx = None
-    min_delim = None
-    for d in delims:
-        idx = s.find(d)
-        if idx < 0:
-            continue
-
-        if min_idx is None or idx < min_idx:
-            min_idx = idx
-            min_delim = d
-
-    if min_idx is None or min_idx < 0:
-        return s, '', None
-
-    return s[:min_idx], s[min_idx + 1:], min_delim
-
-
 def patched_parse_url(url):
     """
     Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is
@@ -165,6 +132,38 @@ def patched_parse_url(url):
         Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...)
     """
 
+    def split_first(s, delims):
+        """
+        Given a string and an iterable of delimiters, split on the first found
+        delimiter. Return two split parts and the matched delimiter.
+
+        If not found, then the first part is the full input string.
+
+        Example::
+
+            >>> split_first('foo/bar?baz', '?/=')
+            ('foo', 'bar?baz', '/')
+            >>> split_first('foo/bar?baz', '123')
+            ('foo/bar?baz', '', None)
+
+        Scales linearly with number of delims. Not ideal for large number of delims.
+        """
+        min_idx = None
+        min_delim = None
+        for d in delims:
+            idx = s.find(d)
+            if idx < 0:
+                continue
+
+            if min_idx is None or idx < min_idx:
+                min_idx = idx
+                min_delim = d
+
+        if min_idx is None or min_idx < 0:
+            return s, '', None
+
+        return s[:min_idx], s[min_idx + 1:], min_delim
+
     # While this code has overlap with stdlib's urlparse, it is much
     # simplified for our needs and less annoying.
     # Additionally, this implementations does silly things to be optimal
