github.com/oam-dev/cluster-gateway@v1.9.0/pkg/apis/cluster/transport/roundtripper.go (about)

     1  package multicluster
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strings"
     7  
     8  	"github.com/oam-dev/cluster-gateway/pkg/config"
     9  )
    10  
    11  var _ http.RoundTripper = &clusterGatewayRoundTripper{}
    12  
    13  type clusterGatewayRoundTripper struct {
    14  	delegate http.RoundTripper
    15  	// falling back to the hosting cluster
    16  	// this is required when the client does implicit api discovery
    17  	// e.g. controller-runtime client
    18  	fallback bool
    19  }
    20  
    21  func NewClusterGatewayRoundTripper(delegate http.RoundTripper) http.RoundTripper {
    22  	return &clusterGatewayRoundTripper{
    23  		delegate: delegate,
    24  		fallback: true,
    25  	}
    26  }
    27  
    28  func NewStrictClusterGatewayRoundTripper(delegate http.RoundTripper, fallback bool) http.RoundTripper {
    29  	return &clusterGatewayRoundTripper{
    30  		delegate: delegate,
    31  		fallback: false,
    32  	}
    33  }
    34  
    35  func (c *clusterGatewayRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
    36  	clusterName, exists := GetMultiClusterContext(request.Context())
    37  	if !exists {
    38  		if !c.fallback {
    39  			return nil, fmt.Errorf("missing cluster name in the request context")
    40  		}
    41  		return c.delegate.RoundTrip(request)
    42  	}
    43  	request.URL.Path = formatProxyURL(clusterName, request.URL.Path)
    44  	return c.delegate.RoundTrip(request)
    45  }
    46  
    47  func formatProxyURL(clusterName, originalPath string) string {
    48  	originalPath = strings.TrimPrefix(originalPath, "/")
    49  	return strings.Join([]string{
    50  		"/apis",
    51  		config.MetaApiGroupName,
    52  		config.MetaApiVersionName,
    53  		"clustergateways",
    54  		clusterName,
    55  		"proxy",
    56  		originalPath}, "/")
    57  }