Opened 13 months ago

Closed 13 months ago

Last modified 13 months ago

#32159 closed Bug (fixed)

AsyncTestClient does not respect extra headers.

Reported by: Ryan Vinzent Owned by: Carlton Gibson
Component: Testing framework Version: 3.1
Severity: Release blocker Keywords: AsyncTestClient, AsyncRequestFactory
Cc: Andrew Godwin, Carlton Gibson Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

In the test client documentation, it states

CGI specification

The headers sent via **extra should follow CGI specification. For example, emulating a different “Host” header as sent in the HTTP request from the browser to the server should be passed as HTTP_HOST.

This simply does not work for AsyncTestClient, even though the documentation states the async client should behave the same as the regular test client.

This somehow works to assign a request header:

client = AsyncTestClient(HTTP_AUTHORIZATION="Bearer faketoken")
await client.get("/api/my-endpoint")

but this does not work:

client = AsyncTestClient()
await client.get("/api/my-endpoint", HTTP_AUTHORIZATION="Bearer faketoken")

Both of these examples work with the normal Client so they should also work with the AsyncClient as is documented.

Change History (7)

comment:1 Changed 13 months ago by Mariusz Felisiak

Cc: Andrew Godwin Carlton Gibson added
Severity: NormalRelease blocker
Summary: AsyncTestClient does not allow setting request headers as documented for TestClient via HTTP_* kwargsAsyncTestClient does not respect extra headers.
Triage Stage: UnreviewedAccepted

Thanks for this report. It looks that we should update the scope headers not the main scope with extra, see AsyncRequestFactory.generic(). Andrew, Can you confirm?

comment:2 Changed 13 months ago by Carlton Gibson

Owner: changed from nobody to Carlton Gibson
Status: newassigned

comment:3 Changed 13 months ago by Carlton Gibson

Has patch: set

comment:4 Changed 13 months ago by Carlton Gibson

So the PR adds corrects the extra handling to set the header, according to the ASGI spec, in scope['headers'], and ASGIRequest then populates request.headers and request.META as normal.

The one difference, that I don't think is worth trying to make the same, is that you don't use the HTTP_ prefix when passing the headers. So the example from the description would be:

client = AsyncTestClient()
await client.get("/api/my-endpoint", AUTHORIZATION="Bearer faketoken")

I've updated the Testing asynchronous code docs (in the PR) to draw out this difference.

...I don't think is worth trying to make the same...

Due to the fact that the HTTP_ into request.META mapping is inside ASGIRequest we'd need to map from HTTP_ to lowercased format as expected in the ASGI scope to map back again in ASGIRequest. (Contrast this with Client which just provides the WSGI environ…) — It would be a lot of complexity, for a worse API, just to be consistent with a hangover from CGI...

In that case, simply saying Don't use the HTTP_ prefix with `AsyncClient seems a much cleaner approach.

comment:5 Changed 13 months ago by Mariusz Felisiak

Triage Stage: AcceptedReady for checkin

comment:6 Changed 13 months ago by GitHub <noreply@…>

Resolution: fixed
Status: assignedclosed

In ebb08d19:

Fixed #32159 -- Ensured AsyncRequestFactory correctly sets headers.

comment:7 Changed 13 months ago by Carlton Gibson <carlton.gibson@…>

In 8b3010a2:

[3.1.x] Fixed #32159 -- Ensured AsyncRequestFactory correctly sets headers.

Backport of ebb08d19424c314c75908bc6048ff57c2f872269 from master

Note: See TracTickets for help on using tickets.
Back to Top