Open QueryHeaven opened 4 years ago
gin: v1.4.0 golang: 1.14.2 @QueryHeaven I tested it and it seemed to work well.
func SetupRouter() *gin.Engine {
router := gin.Default()
v1 := router.Group("/v1", func(c *gin.Context) {
c.Next()
c.Header("X-TIME", "time")
})
{
v1.Any("/log", services.Get)
}
return router
}
go 1.12 gin v1.6.3 @sanxun0325 I don't know how it is written in your services.Get, I tested again and found the following:
Kind of necroing, but since this is still open, the reason headers don't get written is due to the way Go internals handles response buffering. As soon as a status header (aka status code) is written, the response starts getting written to a buffer, and extra headers cannot be written.
In most cases, you can just add the header before the c.Next()
call and it will work. If you need to write the header after the status code is written, you'll need to hijack the writer and override the WriteHeader
function:
type afterMiddlewareWriter struct {
gin.ResponseWriter
}
func (w *afterMiddlewareWriter) WriteHeader(statusCode int) {
w.Header().Add("X-TIME", "time")
w.ResponseWriter.WriteHeader(statusCode)
}
func AfterMiddleware(c *gin.Context) {
c.Writer = &afterMiddlewareWriter{c.Writer}
c.Next()
}
func main() {
r := gin.Default()
r.Use(AfterMiddleware)
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"key": "value",
})
})
}
For a real X-Time
implementation, you can store the initial time on your struct and calculate how many seconds have passed in the hijacked WriteHeader
.
For my case, it's simple to add customize header in response:
router := gin.New()
router.Use(func(c *gin.Context) {
c.Header("X-Your-Header-Name", "your-header-value")
})
// some other middleware...
// add router
router.GET("/some/api", apiHandler)
... // more
here is a more complete version of @joaohaas 's suggestion:
type timingMiddlewareWriter struct {
gin.ResponseWriter
start time.Time
}
func (w *timingMiddlewareWriter) WriteHeader(statusCode int) {
elapsed := time.Since(w.start)
log.Debug().Msg("timer ended after writing statusCode: " + elapsed.String())
w.Header().Add("x-time", elapsed.String())
w.ResponseWriter.WriteHeader(statusCode)
}
func timingMiddleware(c *gin.Context) {
log.Debug().Msg("timer starting...")
c.Writer = &timingMiddlewareWriter{ c.Writer, time.Now()}
c.Next()
log.Debug().Msg("timer ended after next()")
}
I want to add a uniform response header to all the processing functions, but it does not work
As shown in the figure below, I want to add a custom header "X-TIME" after the processing is completed, but it does not work.