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.