func()

in pkg/filter/http/httpproxy/routerfilter.go [111:166]


func (f *Filter) Decode(hc *contexthttp.HttpContext) filter.FilterStatus {
	rEntry := hc.GetRouteEntry()
	if rEntry == nil {
		panic("no route entry")
	}
	logger.Debugf("[dubbo-go-pixiu] client choose endpoint from cluster :%v", rEntry.Cluster)

	clusterName := rEntry.Cluster
	clusterManager := server.GetClusterManager()
	endpoint := clusterManager.PickEndpoint(clusterName, hc)
	if endpoint == nil {
		logger.Debugf("[dubbo-go-pixiu] cluster not found endpoint")
		bt, _ := json.Marshal(contexthttp.ErrResponse{Message: "cluster not found endpoint"})
		hc.SendLocalReply(http.StatusServiceUnavailable, bt)
		return filter.Stop
	}

	logger.Debugf("[dubbo-go-pixiu] client choose endpoint :%v", endpoint.Address.GetAddress())
	r := hc.Request

	var (
		req *http.Request
		err error
	)

	parsedURL := url.URL{
		Host:     endpoint.Address.GetAddress(),
		Scheme:   f.scheme,
		Path:     r.URL.Path,
		RawQuery: r.URL.RawQuery,
	}

	req, err = http.NewRequest(r.Method, parsedURL.String(), r.Body)
	if err != nil {
		bt, _ := json.Marshal(contexthttp.ErrResponse{Message: fmt.Sprintf("BUG: new request failed: %v", err)})
		hc.SendLocalReply(http.StatusInternalServerError, bt)
		return filter.Stop
	}
	req.Header = r.Header

	resp, err := f.client.Do(req)
	if err != nil {
		var urlErr *url.Error
		ok := errors.As(err, &urlErr)
		if ok && urlErr.Timeout() {
			hc.SendLocalReply(http.StatusGatewayTimeout, []byte(err.Error()))
			return filter.Stop
		}
		hc.SendLocalReply(http.StatusServiceUnavailable, []byte(err.Error()))
		return filter.Stop
	}
	logger.Debugf("[dubbo-go-pixiu] client call resp:%v", resp)
	hc.SourceResp = resp
	// response write in hcm
	return filter.Continue
}