聊聊dubbo-go-proxy的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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章