What can happen if you directly initialize http.Request

minherz
2 min readJun 8, 2022
Photo by Cookie the Pom on Unsplash

What happens when you want to write a test that requires an instance of the http.Request structure? You create one.

req := http.Request {
URL: "https://example.com/test",
Header: http.Header{"my-header": {"some value"}},
}

Then what you expect to happen if your test will execute the code that tries to read the header? I expected that the following code will succed:

if req.Header.Get("my-header") != "some value" {
t.Fatal("header validation failed")
}

Because the documentation clearly states that Header.Get is case insensitive. However, I was surprised with the failed test. I debugged the code and saw that the header’s map indeed has “my-header” key. I read the documentation a couple of times and it did not help.

After debugging the Get function in the http package two times I understood that it expects to match “My-Header” key and fails. Reading the documentation once again I saw that there are three places in the http package documentation that partially explain the behavior that I was witnessing:

The doc about http.Header says:

The keys should be in canonical form, as returned by CanonicalHeaderKey.

And the doc about Get says:

To use non-canonical keys, access the map directly.

So, in theory this documentation explains the observed behavior. Unfortunately, initializing headers directly in the http.Request object happens without implicit conversion into the MIME canonical format.

So, if you need to implement tests for code that reads header keys and you provide test data by initializing http.Request instance directly, remember to set header keys into canonical MIME format where first letter and any letter following a hyphen are in upper case and the rest are in lowercase.

--

--

minherz

DevRel Engineer at Google Cloud. The opinions posted here are my own, and not those of my company.