Repository: grpc/grpc-go
File: internal/xds/balancer/clusterimpl/tests/balancer_test.go (Go)

Code before:
		Port:       testutils.ParsePort(t, serverAddr),
		SecLevel:   secLevel,
	})

	// Set the endpoint hostname for authority rewriting.
	resources.Endpoints[0].Endpoints[0].LbEndpoints[0].GetEndpoint().Hostname = endpointHostname

	// Modify the route to enable AutoHostRewrite.
	resources.Routes[0].VirtualHosts[0].Routes[0].GetRoute().HostRewriteSpecifier = &v3routepb.RouteAction_AutoHostRewrite{
		AutoHostRewrite: &wrapperspb.BoolValue{Value: true},
	}

	if err := mgmtServer.Update(ctx, resources); err != nil {
		t.Fatal(err)
	}
}

// TestAuthorityOverriding verifies that the :authority header is correctly
// rewritten to the endpoint's hostname. Also verifies that CallAuthority
// call option takes precedence.
func (s) TestAuthorityOverriding(t *testing.T) {
	testutils.SetEnvConfig(t, &envconfig.XDSAuthorityRewrite, true)
	mgmtServer, resolverBuilder, nodeID := setupManagementServerAndResolver(t)

	// Start a server backend exposing the test service.
	authorityCh := make(chan string, 1)
	f := &stubserver.StubServer{
		EmptyCallF: func(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) {
			if md, ok := metadata.FromIncomingContext(ctx); ok {
				if authVals := md.Get(":authority"); len(authVals) > 0 {
					authorityCh <- authVals[0]
				}
			}
			return &testpb.Empty{}, nil
		},
	}
	server := stubserver.StartTestService(t, f)
	defer server.Stop()

	const xdsAuthorityOverride = "rewritten.example.com"
	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
	defer cancel()
	configureXDSResources(ctx, t, mgmtServer, nodeID, server.Address, xdsAuthorityOverride, e2e.SecurityLevelNone)

	// Create a ClientConn and make a successful RPC.
	cc, err := grpc.NewClient("xds:///my-test-xds-service", grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithResolvers(resolverBuilder))
	if err != nil {
		t.Fatalf("Failed to create client: %v", err)
	}
	defer cc.Close()


Review comment (suggestion):
We may not need a channel here; a simple string should suffice. Since the test waits for the RPC to complete before reading the value, and the RPC completion guarantees the server handler has finished, accessing the string without extra synchronization is safe.

Code after:
		},
	}
	server := stubserver.StartTestService(t, f)
	defer server.Stop()

	const xdsAuthorityOverride = "rewritten.example.com"
	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
	defer cancel()
	configureXDSResources(ctx, t, mgmtServer, nodeID, server.Address, xdsAuthorityOverride, e2e.SecurityLevelNone)

	// Create a ClientConn and make a successful RPC.
	cc, err := grpc.NewClient("xds:///my-test-xds-service", grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithResolvers(resolverBuilder))
	if err != nil {
		t.Fatalf("Failed to create client: %v", err)
	}
	defer cc.Close()

	client := testgrpc.NewTestServiceClient(cc)
	if _, err := client.EmptyCall(ctx, &testpb.Empty{}); err != nil {
		t.Fatalf("client.EmptyCall() failed: %v", err)
	}

	if gotAuthority != xdsAuthorityOverride {
		t.Errorf("invalid authority got: %q, want: %q", gotAuthority, xdsAuthorityOverride)
	}

	// The authority specified via the `CallAuthority` CallOption takes the
	// highest precedence when determining the `:authority` header.
	const userAuthorityOverride = "user-override.com"
	if _, err := client.EmptyCall(ctx, &testpb.Empty{}, grpc.CallAuthority(userAuthorityOverride)); err != nil {
		t.Fatalf("client.EmptyCall() failed: %v", err)
	}

	if gotAuthority != userAuthorityOverride {
		t.Errorf("Server received authority %q, want %q (user override)", gotAuthority, userAuthorityOverride)
	}
}

// TestAuthorityOverridingWithTLS verifies the interaction between xDS Authority
// Rewriting and TLS Secure Naming. It ensures that when the :authority header
// is rewritten by the clusterimpl picker, the new authority is correctly
// validated against the server's TLS certificate before the RPC proceeds.
// Also check that RPC fails when the rewritten authority does not match the
// server's certificate due to secure naming validation.
func (s) TestAuthorityOverridingWithTLS(t *testing.T) {
	tests := []struct {
		name                 string
		xdsAuthorityOverride string
		wantSuccess          bool
	}{
		{