-1

我正在尝试在我的网络服务器上记录一些数据,所以我创建了一个loggingMiddleware为下一个请求提供服务然后记录数据,我认为这样我将在r *http.Request指针中包含所有必要的数据

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // call next handler
        next.ServeHTTP(o, r)

        // get requestID
        reqID := middleware.GetReqID(r.Context())

        log.WithFields(
            log.Fields{
                "request_id":     reqID,           // drops requestID
                "method":         r.Method,        // http method
                "remote_address": r.RemoteAddr,    // remote address
                "url":            r.URL.String(),  // url used by the client to access the service
                "referer":        r.Referer(),     // Referer header if present
                "user_agent":     r.UserAgent(),   // User-Agent header
                "content_length": r.ContentLength, // Content-Length header if present"
            },
        ).Info()
    })

但是,对于 RequestID,仅当RequestID中间件在 loggingMiddleware 之前安装时才适用

非工作

...
    // get a new chi rotuter
    router = chi.NewRouter()

    // MIDDLEWARES

    // log
    // use logrus to log requests
    router.Use(LoggingMiddleware)

    // requestID
    // Generate a unique id for every request
    // ids are grouped based on client hostname
    router.Use(middleware.RequestID)
...

在职的

...
    // get a new chi rotuter
    router = chi.NewRouter()

    // MIDDLEWARES

    // requestID
    // Generate a unique id for every request
    // ids are grouped based on client hostname
    router.Use(middleware.RequestID)

    // log
    // use logrus to log requests
    router.Use(LoggingMiddleware)
...

这是预期的行为吗?指针是否应该r *http.Request指向请求的“更新”版本?有没有办法解决这个问题?因为如果我想,例如,从 JWT 令牌中提取用户名并将其放入r.Context()以便稍后记录它,这将需要在loggingMiddleware.

对不起我的英语,如果有不清楚的地方,请询问。

谢谢

4

1 回答 1

1

middleware.RequestID使用以下命令将请求 ID 添加到请求上下文http.Request.WithContext

ctx = context.WithValue(ctx, RequestIDKey, requestID)
next.ServeHTTP(w, r.WithContext(ctx))

根据文档:

WithContext 返回 r 的浅表副本,其上下文更改为 ctx。提供的 ctx 必须为非零。

因此,因为它“返回 r 的浅表副本”,并且它是(指向)它传递给的浅表副本next.ServeHTTP,如果middleware.RequestID是第二个挂载的,那么rinLoggingMiddleware指向的*http.Request不是包含修改的上下文的那个,因此其上下文将不包含请求 ID。另一方面,如果middleware.RequestID先挂载,那么LoggingMiddleware将收到一个指向r.WithContext返回的浅拷贝的指针,一切都会按预期工作。

于 2021-05-13T12:23:13.977 回答