Skip to content

Preserve header casing - #1338

Merged
lovelydinosaur merged 2 commits into
masterfrom
preserve_header_casing
Oct 6, 2020
Merged

Preserve header casing#1338
lovelydinosaur merged 2 commits into
masterfrom
preserve_header_casing

Conversation

@lovelydinosaur

@lovelydinosaurlovelydinosaur commented Oct 2, 2020

Copy link
Copy Markdown
Contributor

So, it's looking like h11 is about to get support for preserving header casing, which is pretty fantastic.

Turns out we need to do some work on our side as well in order to take advantage of that, as the test case in this PR demonstrates...

defecho_raw_headers(request: httpx.Request) ->httpx.Response:
data= [
(name.decode("ascii"), value.decode("ascii"))
forname, valueinrequest.headers.raw
]
returnhttpx.Response(200, json=data)
deftest_raw_client_header():
""" Set a header in the Client. """url="http://example.org/echo_headers"headers= {"Example-Header": "example-value"}
client=httpx.Client(transport=MockTransport(echo_raw_headers), headers=headers)
response=client.get(url)
assertresponse.status_code==200assertresponse.json() == [
["Host", "example.org"],
["Accept", "*/*"],
["Accept-Encoding", "gzip, deflate, br"],
["Connection", "keep-alive"],
["User-Agent", f"python-httpx/{httpx.__version__}"],
["Example-Header", "example-value"],
]

In the test case we're mirroring back whatever headers the transport layer is passed, so that we can check that we're receiving them with the correct casing at that point.

Without this pull request, the headers are all lowercased. After this pull request, the header casing is preserved, although Headers is still a case-insensitive dict.

In order to support this I've made some internal changes to the Headers class, while trying not to otherwise alter the behaviour.

We now store header information as a three-tuple of (raw_key, lowercase_key, value).

We always compare against and expose lowercase_key, so that Headers is always case-insensitive.

The only provisos to that are:

  • We store the raw key that's used when setting header values.
  • The headers.raw interface does expose headers a byte pairs, including the full original casing on the key.

I'm aware that we've got a bunch of refinements on Headers that we could make, in the same way that we've recently polished up the edges of the URL interface, but I'd like us to treat those separately to this PR.

@lovelydinosaurlovelydinosaur added the enhancement New feature or request label Oct 2, 2020

@florimondmancaflorimondmanca left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome news!

How come tests are passing already? Has there been a release to h11 with support for preserved header casing already?

@lovelydinosaur

Copy link
Copy Markdown
ContributorAuthor

@florimondmanca Because the test is at the transport level.

It's making a request to the mock transport, which is echo'ing back what's passed to .request(method, url, headers, stream, ext).

If we actually made the request onto the wire, with httpcore, then right now we'd see it still getting lowercased, by h11.

But, not for long! ✨

@florimondmanca

Copy link
Copy Markdown
Contributor

Got it! Smart :-)

@lovelydinosaurlovelydinosaur added this to the v0.16 milestone Oct 2, 2020
@lovelydinosaurlovelydinosaur mentioned this pull request Oct 6, 2020
@lovelydinosaur
lovelydinosaur merged commit c725387 into masterOct 6, 2020
@lovelydinosaur
lovelydinosaur deleted the preserve_header_casing branch October 6, 2020 13:57
@dhofstetter

Copy link
Copy Markdown

Hello everybody,
this changes will break functionality related to asgi. The asgi spec requires headers to be lower cased (see ASGI Spec). Changes made in this Pull Request break this requirement. So there are changes in 'ASGITransport' necessary (or revert this changes).

A longer description what the problems are with this changes can be found here.

BR Daniel

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Development

Successfully merging this pull request may close these issues.

3 participants

@lovelydinosaur@florimondmanca@dhofstetter