【问题标题】:Go and Pointers in http middlewarehttp中间件中的Go和指针
【发布时间】:2021-08-03 17:01:34
【问题描述】:

我正在尝试在我的网络服务器上记录一些数据,所以我创建了一个 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 之前安装单独的中间件。

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

谢谢

【问题讨论】:

    标签: go pointers go-chi


    【解决方案1】:

    middleware.RequestID 使用 http.Request.WithContext 将请求 ID 添加到请求上下文中:

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

    根据文档:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-23
      • 1970-01-01
      • 2015-12-18
      • 2016-03-20
      • 2016-07-12
      • 2021-11-02
      • 1970-01-01
      • 2016-08-15
      相关资源
      最近更新 更多