英文:
Getting *http.Request from Context on AppEngine
问题
我正在使用应用引擎,并从*http.Request创建context.Context(golang.org/x/net/context)变量。
c := appengine.NewContext(r)
我正在传递这个上下文,并且我正在尝试找到一种方法从context.Context中获取*http.Request,以便记录http.Request。
我在文档中搜索了很多地方,但是没有找到任何解决方案。
英文:
I'm using app engine, and creating context.Context (golang.org/x/net/context) variable from the *http.Request.
c := appengine.NewContext(r)
I'm passing the context around and I'm trying to figure out a way to get the *http.Request from the context.Context in order to log the http.Request.
I search all over the doc but I couldn't find any solution.
答案1
得分: 3
appengine.NewContext(r) 返回一个类型为 appengine.Context 的值。这与 golang.org/x/net/context 包中的 Context 类型不同!
拥有类型为 appengine.Context 的值,你无法获取用于创建它的 *http.Request。如果你需要 *http.Request,你必须自己负责传递它(因为你使用它来创建上下文)。
请注意,appengine.Context(它是一个接口类型)有一个方法 Context.Request(),但这仅供内部使用,不会导出供任何人调用。而且它返回的是一个 interface{} 而不是 *http.Request。即使它返回一个持有 *http.Request 的值,你也不能依赖它,因为该方法可能在未来的版本中被更改或删除。
将 *http.Request 与 appengine.Context 一起传递是最好的方法。试图从上下文中获取它只是一种“巫术”,并且可能在新的 SDK 版本中出现问题。如果你想简化它,可以创建一个包装结构体,并传递该包装结构体而不是两个值,例如:
type Wrapper struct {
C appengine.Context
R *http.Request
}
还有一个辅助函数:
func CreateCtx(r *http.Request) Wrapper {
return Wrapper{appengine.NewContext(r), r}
}
英文:
appengine.NewContext(r) returns a value of type appengine.Context. This is not the same as the Context type of the golang.org/x/net/context package!
Having a value of type appengine.Context, you can't get the *http.Request you used to create it. If you will need the *http.Request, you have to take care of passing that around yourself (you have it, since you use that to create the context).
Note that appengine.Context (which is an interface type) has a method Context.Request(), but that is for internal use only, it is not exported for anyone to call it. And also it returns an interface{} and not a *http.Request. Even if it returns a value holding a *http.Request, you can't rely on it as this method may be changed or removed in future versions.
Passing the *http.Request along with the appengine.Context is the best way. Trying to get it from the context is just "wizardry" and might break with a new SDK release. If you want to simplify it, you may create a wrapper struct and pass that wrapper instead of 2 values, for example:
type Wrapper struct {
C appengine.Context
R *http.Request
}
And a helper func:
func CreateCtx(r *http.Request) Wrapper {
return Wrapper{appengine.NewContext(r), r}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论