A pitfall that needs to be paid attention to when setting headers in the go gin framework

Let’s talk about the problem first. When using the set key value go ginin the framework , the set key will become ! ! !c.Header("new-token", "123")http headernew-tokenNew-Token

Insert image description here

incident settlement

Recently I have been working on server authentication, a relatively simple logic:

tokenAfter receiving the client's request, the server verifies whether the verification parameters brought by the client have expired. tokenWhen the expiration time is less than one day, it will generate a new tokenand notify the client to update the local cache by http headersetting the .new-tokentoken

Insert image description here

The function is ready, the sample code is as follows:

The server omits tokenthe logic of verifying the time and only provides tokenthe 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 tokenabout to expire, I will tell you that it has been updated by setting http headerthe value. You can just replace new-tokenthe 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, tokenthe 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-tokennot all lowercase letters, but New-Token! ! !

Insert image description here

Positioning problem

Shame on you! ! ! !

In order to regain a little face, I checked the source code and found out that ginthe framework will headerset it.

You will eventually reach gothe source code go\src\net\textprotomethod 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 headerthe key we assigned new-tokento 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.

Guess you like

Origin blog.csdn.net/DisMisPres/article/details/129735349