auth: AsyncAuthorizedSession.request leaks response across retry attempts

Offen Anfängerfreundlich
#18,315 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Anfängerfreundlichkeit
88/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
python
Bereich
networking

Rechercherichtung

Beginne in packages/google-auth/google/auth/aio/transport/sessions.py bei AsyncAuthorizedSession.request und vergleiche dann dessen Retry-Schleife mit dem Bereinigungsmuster in den Zeilen 501-518. Füge Unit-Testabdeckung für einen wiederholbaren 503 gefolgt von einem 200 hinzu und überprüfe dabei, dass close() der ursprünglichen Response abgewartet wird, bevor der Retry fortgesetzt wird.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

auth priority: p2

In google.auth.aio.transport.sessions.AsyncAuthorizedSession.request (packages/google-auth/google/auth/aio/transport/sessions.py:339-347), the retry loop reassigns response = await with_timeout(...) across retry attempts without closing the previous response.

If the response payload hasn't reached EOF before the next retry fires (e.g., with chunked or streaming responses), aiohttp keeps the socket checked out in connector._acquired. The transport protocol's internal EOF callback holds a bound reference to ClientResponse._response_eof, which prevents Python's garbage collector from cleaning up the orphaned response while the connection is waiting for data. Under concurrency, multiple requests retrying against a degraded endpoint can quickly burn through the connector pool (limit=100) and block other outgoing requests across the session.

Proposed Fix

Close any previous response before kicking off the next retry attempt, matching the pattern already used in sessions.py:L501-L518:

response = None
async for _ in retries:
    if response is not None and hasattr(response, "close"):
        try:
            res = response.close()
            if inspect.isawaitable(res):
                await res
        except Exception:
            pass

    response = await with_timeout(
        self._auth_request(
            url, method, data, request_headers, actual_timeout, **kwargs
        )
    )

    if response.status_code not in transport.DEFAULT_RETRYABLE_STATUS_CODES:
        break

Unit tests should check that when a retryable status code (like a 503) is followed by a 200, close() is awaited on the initial response before the retry runs.

Vorherrschende Sprache
Python
Sterne
5.4k
Forks
1.8k
Ø Merge
1 T. 17 Std.
Gemergte PRs (30 T.)
93

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus googleapis/google-cloud-python

Alle Issues in googleapis/google-cloud-python

Ähnliche Issues

Weitere Issues zu Python

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.