乐趣区

关于golang:聊聊dubbogoproxy的replacePathFilter

本文次要钻研一下 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
退出移动版