本文主要研究一下dubbo-go-proxy的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
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。