go restful源码剖析-3

2018-08-30  本文已影响0人  tcuze

概述


调试go-restful\examples中的restful-options-filter,在该段代码中主要介绍了处理http option请求的流程,在改短代码中采用了之前通用的container初始化及注册流程,只是在fliter中添加了对应的OPTIONSFilter。

type UserResource struct{}

func (u UserResource) RegisterTo(container *restful.Container) {
    ws := new(restful.WebService)
    ws.
        Path("/users").
        Consumes("*/*").
        Produces("*/*")

    ws.Route(ws.GET("/{user-id}").To(u.nop))
    ws.Route(ws.POST("").To(u.nop))
    ws.Route(ws.PUT("/{user-id}").To(u.nop))
    ws.Route(ws.DELETE("/{user-id}").To(u.nop))

    container.Add(ws)
}

func (u UserResource) nop(request *restful.Request, response *restful.Response) {
    io.WriteString(response.ResponseWriter, "this would be a normal response")
}

func main() {
    wsContainer := restful.NewContainer()
    u := UserResource{}
    u.RegisterTo(wsContainer)

    // Add container filter to respond to OPTIONS
    wsContainer.Filter(wsContainer.OPTIONSFilter)

    // For use on the default container, you can write
    // restful.Filter(restful.OPTIONSFilter())

    log.Print("start listening on localhost:8080")
    server := &http.Server{Addr: ":8080", Handler: wsContainer}
    log.Fatal(server.ListenAndServe())

OPTIONSFilter流程


先看下OPTIONSFilter的代码,该段代码的实现十分的简单,首先查看req方法是否是option方法,并针对option方法定制了resp直接进行返回。

func (c *Container) OPTIONSFilter(req *Request, resp *Response, chain *FilterChain) {
    if "OPTIONS" != req.Request.Method {
        chain.ProcessFilter(req, resp)
        return
    }

    archs := req.Request.Header.Get(HEADER_AccessControlRequestHeaders)
    methods := strings.Join(c.computeAllowedMethods(req), ",")
    origin := req.Request.Header.Get(HEADER_Origin)

    resp.AddHeader(HEADER_Allow, methods)
    resp.AddHeader(HEADER_AccessControlAllowOrigin, origin)
    resp.AddHeader(HEADER_AccessControlAllowHeaders, archs)
    resp.AddHeader(HEADER_AccessControlAllowMethods, methods)
}

由于之前并不了解option方法,因此通过查阅得知option方法主要用于有两个:

上一篇下一篇

猜你喜欢

热点阅读