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

replacePathFilter

dubbo-go-proxy/pkg/filter/replacepath/replace_path.go

// replacePathFilter is a filter for host.type replacePathFilter struct {    path string}// New create replace path filter.func New(path string) filter.Filter {    return &replacePathFilter{path: path}}func (f replacePathFilter) Do() context.FilterFunc {    return func(c context.Context) {        f.doReplacePathFilter(c.(*http.HttpContext))    }}func (f replacePathFilter) doReplacePathFilter(ctx *http.HttpContext) {    req := ctx.Request    if req.URL.RawPath == "" {        req.Header.Add(ReplacedPathHeader, req.URL.Path)    } else {        req.Header.Add(ReplacedPathHeader, req.URL.RawPath)    }    req.URL.RawPath = f.path    var err error    req.URL.Path, err = url.PathUnescape(req.URL.RawPath)    if err != nil {        ctx.AddHeader(constant.HeaderKeyContextType, constant.HeaderValueTextPlain)        ctx.WriteWithStatus(nh.StatusInternalServerError, []byte(replacePathError))        ctx.Abort()        return    }    req.RequestURI = req.URL.RequestURI()    ctx.Next()}
replacePathFilter定义了path属性;它实现了Filter的Do办法,该办法执行的是doReplacePathFilter办法,它会往header写入名为ReplacedPathHeader,若req.URL.RawPath为空则取req.URL.Path;之后将req.URL.RawPath更新为f.path,再通过url.PathUnescape(req.URL.RawPath)计算req.URL.Path,最初将req.URL.RequestURI()赋值给req.RequestURI

httpFilter

dubbo-go-proxy/pkg/proxy/listener.go

func httpFilter(ctx *h.HttpContext, request fc.IntegrationRequest) {    if len(request.Host) != 0 {        ctx.AppendFilterFunc(host.New(request.Host).Do())    }    if len(request.Path) != 0 {        ctx.AppendFilterFunc(replacepath.New(request.Path).Do())    }}
httpFilter办法会依据request.Path通过AppendFilterFunc增加replacepath.New(request.Path)

小结

dubbo-go-proxy的httpFilter会依据request.Path通过AppendFilterFunc增加replacepath.New(request.Path);而replacePathFilter会依据path属性替换req.URL.RawPath及req.URL.Path,最初更新req.RequestURI。

doc

  • dubbo-go-proxy