Repository: urllib3/urllib3

Issue:
Investigate HTTPConnection.auto_open
urllib3 makes multiple mentions to a property on `http.client.HTTPConnection` called `auto_open`. The property isn't used much in the current stdlib `http.client` module, but has some implications for urllib3: mainly that connections may not be re-used based on this value?

In `urllib3.connection.py`:

```python
# Calls self._set_hostport(), so self.host is
# self._tunnel_host below.
self._tunnel()  # type: ignore[attr-defined]
# Mark this connection as not reusable
self.auto_open = 0
```

In `urllib3.connectionpool.py`:

```python
conn.close()
if getattr(conn, "auto_open", 1) == 0:
    # This is a proxied connection that has been mutated by
    # http.client._tunnel() and cannot be reused (since it would
    # attempt to bypass the proxy)
    conn = None
```

I suspect that `http.client.HTTPConnection._tunnel()` in the past may have rewritten `.host` and `.port` properties or something like this and this was our method of "guarding" against that? Currently `host` and `port` properties on a connection point to the first origin (read: proxy) on a requests' journey to the destination origin.

- What is the intent of this property and it's values?
- Has that intent changed since the original code in urllib3 using the value was written (git blame!)?
- Can we remove our use/dependence on this value?
- Should we write some tests for this value? (We currently have none!!! :scream:)
- Can any of these fixes land in 1.26.x?


Discussion:

Resolving patch:
diff --git a/src/urllib3/connection.py b/src/urllib3/connection.py
--- a/src/urllib3/connection.py
+++ b/src/urllib3/connection.py
@@ -255,8 +255,6 @@ def _prepare_conn(self, conn: socket.socket) -> None:
             # TODO: Fix tunnel so it doesn't depend on self.sock state.
             self._tunnel()
             self._connecting_to_proxy = False
-            # Mark this connection as not reusable
-            self.auto_open = 0
 
     def connect(self) -> None:
         self._connecting_to_proxy = bool(self.proxy)
@@ -554,28 +552,22 @@ def connect(self) -> None:
 
         sock: Union[socket.socket, "ssl.SSLSocket"]
         self.sock = sock = self._new_conn()
-        hostname: str = self.host
+        server_hostname: str = self.host
         tls_in_tls = False
 
         if self._is_using_tunnel():
             if self.tls_in_tls_required:
-                self.sock = sock = self._connect_tls_proxy(hostname, sock)
+                self.sock = sock = self._connect_tls_proxy(self.host, sock)
                 tls_in_tls = True
 
             self._connecting_to_proxy = False
 
-            # Calls self._set_hostport(), so self.host is
-            # self._tunnel_host below.
             self._tunnel()
-            # Mark this connection as not reusable
-            self.auto_open = 0
-
             # Override the host with the one we're requesting data from.
-            hostname = cast(
+            server_hostname = cast(
                 str, self._tunnel_host
             )  # self._tunnel_host is not None, because self._is_using_tunnel() returned a truthy value.
 
-        server_hostname = hostname
         if self.server_hostname is not None:
             server_hostname = self.server_hostname
 
diff --git a/src/urllib3/connectionpool.py b/src/urllib3/connectionpool.py
--- a/src/urllib3/connectionpool.py
+++ b/src/urllib3/connectionpool.py
@@ -283,11 +283,6 @@ def _get_conn(self, timeout: Optional[float] = None) -> HTTPConnection:
         if conn and is_connection_dropped(conn):
             log.debug("Resetting dropped connection: %s", self.host)
             conn.close()
-            if getattr(conn, "auto_open", 1) == 0:
-                # This is a proxied connection that has been mutated by
-                # http.client._tunnel() and cannot be reused (since it would
-                # attempt to bypass the proxy)
-                conn = None
 
         return conn or self._new_conn()
 


Test patch: