乐趣区

关于golang:聊聊dubbogoproxy的apiFilter

本文次要钻研一下 dubbo-go-proxy 的 apiFilter

apiFilter

dubbo-go-proxy/pkg/filter/api/api.go

func Init() {extension.SetFilterFunc(constant.HTTPApiFilter, apiFilterFunc())
}

Init 办法往 extension 设置了名为 dgp.filters.http.api 的 apiFilterFunc

apiFilterFunc

dubbo-go-proxy/pkg/filter/api/api.go

// apiFilterFunc url match api
func apiFilterFunc() context.FilterFunc {return func(c context.Context) {url := c.GetUrl()
        method := c.GetMethod()
        // [williamfeng323]TO-DO: get the API details from router which saved in constant.LocalMemoryApiDiscoveryService
        if api, ok := api.EmptyApi.FindApi(url); ok {if !api.MatchMethod(method) {c.WriteWithStatus(http.StatusMethodNotAllowed, constant.Default405Body)
                c.AddHeader(constant.HeaderKeyContextType, constant.HeaderValueTextPlain)
                c.Abort()
                return
            }

            if !api.IsOk(api.Name) {c.WriteWithStatus(http.StatusNotAcceptable, constant.Default406Body)
                c.AddHeader(constant.HeaderKeyContextType, constant.HeaderValueTextPlain)
                c.Abort()
                return
            }
            // [williamfeng323]TO-DO: the c.Api method need to be updated to use the newest API definition
            c.Api(api)
            c.Next()} else {c.WriteWithStatus(http.StatusNotFound, constant.Default404Body)
            c.AddHeader(constant.HeaderKeyContextType, constant.HeaderValueTextPlain)
            c.Abort()}
    }
}

apiFilterFunc 首先通过 api.EmptyApi.FindApi(url)来查找对应的 api,找不到则返回 404;找到的话则先通过 api.MatchMethod 判断 method 是否匹配,不匹配的话返回 405;之后通过 api.IsOk 判断该 api 的 status 是否 up,不是的话返回 406;最初执行 c.Api(api)及 c.Next()。

dubbo-go-proxy-filter

dubbo-go-proxy-filter@v0.1.0-rc1.0.20210120132524-c63f4eb13725/pkg/api/api.go

func (a *Api) FindApi(name string) (*Api, bool) {if v, ok := CacheApi.Load(name); ok {return v.(*Api), true
    }

    return nil, false
}

// MatchMethod
func (a *Api) MatchMethod(method string) bool {i := RequestMethodValue[method]
    if a.RequestMethod == RequestMethod(i) {return true}

    return false
}

// IsOk api status equals Up
func (a *Api) IsOk(name string) bool {if v, ok := CacheApi.Load(name); ok {return v.(*Api).Status == Up
    }

    return false
}

api.go 提供了 FindApi、MatchMethod、IsOk 办法

小结

apiFilterFunc 首先通过 api.EmptyApi.FindApi(url)来查找对应的 api,找不到则返回 404;找到的话则先通过 api.MatchMethod 判断 method 是否匹配,不匹配的话返回 405;之后通过 api.IsOk 判断该 api 的 status 是否 up,不是的话返回 406;最初执行 c.Api(api)及 c.Next()。

doc

  • dubbo-go-proxy
退出移动版