Let’s talk about the problem first. When using the set key value go gin
in the framework , the set key will become ! ! !c.Header("new-token", "123")
http header
new-token
New-Token
incident settlement
Recently I have been working on server authentication, a relatively simple logic:
token
After receiving the client's request, the server verifies whether the verification parameters brought by the client have expired. token
When the expiration time is less than one day, it will generate a new token
and notify the client to update the local cache by http header
setting the .new-token
token
The function is ready, the sample code is as follows:
The server omits token
the logic of verifying the time and only provides token
the logic of setting:
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
engine := gin.Default()
engine.GET("/header", func(c *gin.Context) {
c.Header("new-token", "123")
c.String(200, "ok")
})
engine.Run(":4780")
}
At this time, I directly told the client connection guy: When the client cache is token
about to expire, I will tell you that it has been updated by setting http header
the value. You can just replace new-token
the client cache .token
The code of the front-end guy is as follows:
if (response.headers && response.headers['new-token']) {
store.upadteToken(response.headers['new-token'])
}
Because the function is not complicated, I didn’t test it (the front-end guy didn’t test it either) and submitted it directly for testing. In addition, token
the expiration time of is also set relatively long, and there has not been such a need to update in the past few days token
.
But suddenly one day the test guy said there was a problem and needed to be looked at. I looked at the code and directly denied that it was not my problem. The front-end guy also directly denied it.
There was no other way, so the two went to the crime scene to compare, and found out that the problem was that the backend returned new-token
not all lowercase letters, but New-Token
! ! !
Positioning problem
Shame on you! ! ! !
In order to regain a little face, I checked the source code and found out that gin
the framework will header
set it.
You will eventually reach go
the source code go\src\net\textproto
method CanonicalMIMEHeaderKey(s string) string
, as follows:
// CanonicalMIMEHeaderKey returns the canonical format of the
// MIME header key s. The canonicalization converts the first
// letter and any letter following a hyphen to upper case;
// the rest are converted to lowercase. For example, the
// canonical key for "accept-encoding" is "Accept-Encoding".
// MIME header keys are assumed to be ASCII only.
// If s contains a space or invalid header field bytes, it is
// returned without modifications.
func CanonicalMIMEHeaderKey(s string) string {
commonHeaderOnce.Do(initCommonHeader)
// Quick check for canonical encoding.
upper := true
for i := 0; i < len(s); i++ {
c := s[i]
if !validHeaderFieldByte(c) {
return s
}
if upper && 'a' <= c && c <= 'z' {
return canonicalMIMEHeaderKey([]byte(s))
}
if !upper && 'A' <= c && c <= 'Z' {
return canonicalMIMEHeaderKey([]byte(s))
}
upper = c == '-'
}
return s
}
As you can see, it is here that header
the key we assigned new-token
to is changed to uppercase New-Token
.
Closing advice
Dear, you don’t want your colleagues to know that you are such a good person, right? xxxx
The use of the framework can indeed save us a lot of time, but when using the framework, no matter how small the function is, it must be tested, otherwise it may cause problems similar to the ones described in this article.