使用 http.NewRequestWithContext() 创建的请求在传递给中间件时会丢失

在下面的程序中,我有两个路由器。一个在公共接入点工作localhost:3000并充当公共接入点。它还可以将带有数据的请求发送到另一个localhost:8000正在处理数据的本地地址。第二个路由器正在localhost:8000处理第一个路由器的处理请求。

问题

http.NewRequestWithContext()第一个路由器向第二个使用函数发送带有上下文的请求。该值被添加到上下文中,并且上下文被添加到请求中。当请求到达第二个路由器时,它没有先前添加的值。

诸如错误处理之类的某些内容并未被编写为不要在此处发布代码墙。

package main

import (

    "bytes"

    "context"

    "net/http"

    "github.com/go-chi/chi"

    "github.com/go-chi/chi/middleware"

)


func main() {

    go func() {

        err := http.ListenAndServe(

            "localhost:3000",

            GetDataAndSolve(),

        )

        if err != nil {

            panic(err)

        }

    }()


    go func() {

        err := http.ListenAndServe( // in GetDataAndSolve() we send requests

            "localhost:8000", // with data for processing

            InternalService(),

        )

        if err != nil {

            panic(err)

        }

    }()


    // interrupt := make(chan os.Signal, 1) 

    // signal.Notify(interrupt, syscall.SIGTERM, syscall.SIGINT)

    // <-interrupt // just a cool way to close the program, uncomment if you need it

}

func GetDataAndSolve() http.Handler {

    r := chi.NewRouter()

    r.Use(middleware.Logger)


    r.Get("/tasks/str", func(rw http.ResponseWriter, r *http.Request) {

        // receiving data for processing...

        taskCtx := context.WithValue(r.Context(), "str", "strVar") // the value is being

        postReq, err := http.NewRequestWithContext(                // stored to context

            taskCtx, // context is being given to request

            "POST",

            "http://localhost:8000/tasks/solution",

            bytes.NewBuffer([]byte("something")),

        )

        postReq.Header.Set("Content-Type", "application/json") // specifying for endpoint

        if err != nil {                                        // what we are sending

            return

        }


}


冉冉说
浏览 333回答 1
1回答

素胚勾勒不出你

您对上下文的理解不正确。上下文(在某种程度上简化并参考NewRequestWithContextAPI)只是一个内存中的对象,您可以使用它来控制请求的生命周期(处理/触发取消)。但是,您的代码正在进行 HTTP 调用,该调用使用 HTTP 协议通过线路(编组)。该协议不理解 golang 的上下文或其值。在您的场景中,两者/tasks/str都/tasks/solution在同一台服务器上运行。如果它们位于不同的服务器上怎么办,可能还有不同的语言和应用程序服务器,所以上下文不能被发送。由于 API 在同一台服务器中,也许您可以避免进行完整的 HTTP 调用,而直接调用 API/方法。它也可能会变得更快。如果您仍想从上下文发送附加值,那么您将不得不利用其他属性(如 HTTP 标头、参数、正文)来发送所需的信息。这可以提供有关如何通过 HTTP 从上下文序列化数据的更多信息。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go