栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

通过golang中的多个HTTP处理程序包括上下文对象

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

通过golang中的多个HTTP处理程序包括上下文对象

我可以想到几种方法来做到这一点。

传递上下文

首先,您可以更改签名以接受上下文

type appHandler func(http.ResponseWriter, *http.Request, context.Context) *appErrorfunc (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {        if e := fn(w, r, nil); e != nil { // e is *appError, not os.Error.     http.Error(w, e.Message, e.Code)        }}

现在,我假设AuthHandler与身份验证有关,并在上下文对象中设置了用户。

您可以做的是创建另一个设置上下文的类型处理程序。像这样

type authHandler func(http.ResponseWriter, *http.Request, context.Context) *appErrorfunc (fn authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {    // setup authentication here uid := 1    // setup the context the way you want   parent := context.TODO()     ctx := context.WithValue(parent, userIdKey, uid)   if e := fn(w, r, ctx); e != nil { // e is *appError, not os.Error.http.Error(w, e.Message, e.Code)    }  }

这样您可以通过以下方式使用它

func init() {http.Handle("/view", appHandler(viewRecord))      // don't require authentication     http.Handle("/viewAuth", authHandler(viewRecord)) // require authentication       }

这是完整的代码

package mainimport (        "fmt"        "net/http"        "pre.google.com/p/go.net/context")type appError struct {        Error   error        Message string        Code    int}type key intconst userIdKey key = 0type appHandler func(http.ResponseWriter, *http.Request, context.Context) *appErrorfunc (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {        if e := fn(w, r, nil); e != nil { // e is *appError, not os.Error.     http.Error(w, e.Message, e.Code)        }}type authHandler func(http.ResponseWriter, *http.Request, context.Context) *appErrorfunc (fn authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {        // setup authentication here        uid := 1        // setup the context the way you want        parent := context.TODO()        ctx := context.WithValue(parent, userIdKey, uid)        if e := fn(w, r, ctx); e != nil { // e is *appError, not os.Error.     http.Error(w, e.Message, e.Code)        }}func viewRecord(w http.ResponseWriter, r *http.Request, c context.Context) *appError {        if c == nil {     fmt.Fprintf(w, "User are not logged in")        } else {     uid := c.Value(userIdKey)     fmt.Fprintf(w, "User logged in with uid: %d", uid)        }        return nil}func init() {        http.Handle("/view", appHandler(viewRecord))      // viewRecord is an appHandler function        http.Handle("/viewAuth", authHandler(viewRecord)) // viewRecord is an authHandler function}func main() {        http.ListenAndServe(":8080", nil)}

创建地图上下文

您无需传递上下文,而是创建

var contexts map[*http.Request]context.Context

并获得上下文中

view
使用
contexts[r]

但是由于映射不是线程安全的,因此必须使用互斥锁保护对映射的访问。

猜猜是什么,这就是大猩猩上下文正在为您做的事情,我认为这是更好的方法

https://github.com/gorilla/context/blob/master/context.go#l20-28

这是完整的代码

package mainimport (        "fmt"        "net/http"        "github.com/gorilla/context")type appError struct {        Error   error        Message string        Code    int}type key intconst userIdKey key = 0type appHandler func(http.ResponseWriter, *http.Request) *appErrorfunc (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {        if e := fn(w, r); e != nil { // e is *appError, not os.Error.     http.Error(w, e.Message, e.Code)        }}type authHandler func(http.ResponseWriter, *http.Request) *appErrorfunc (fn authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {        // setup authentication here        uid := 1        context.Set(r, userIdKey, uid)        if e := fn(w, r); e != nil { // e is *appError, not os.Error.     http.Error(w, e.Message, e.Code)        }}func viewRecord(w http.ResponseWriter, r *http.Request) *appError {        if uid, ok := context.GetOk(r, userIdKey); !ok {     fmt.Fprintf(w, "User are not logged in")        } else {     fmt.Fprintf(w, "User logged in with uid: %d", uid)        }        return nil}func init() {        http.Handle("/view", appHandler(viewRecord))      // don't require authentication        http.Handle("/viewAuth", authHandler(viewRecord)) // require authentication}func main() {        http.ListenAndServe(":8080", nil)}

您还可以选择包装函数而不是类型函数进行身份验证

func AuthHandler(h appHandler) appHandler {      return func(w http.ResponseWriter, r *http.Request) *appError {        // setup authentication here      uid := 1        context.Set(r, userIdKey, uid)    return h(w, r)     }      }func init() {http.Handle("/view", appHandler(viewRecord))       // don't require authentication    http.Handle("/viewAuth", appHandler(AuthHandler(viewRecord))) // require authentication      }


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/484270.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号