mirror of https://github.com/grpc/grpc-go.git
Add DialOption to overwrite :authority pseudo-header
The :authority pseudo-header for a gRPC Client defaults to the host portion of the dialed target and can only be overwritten by providing a TransportCredentials. However, there are cases where setting this header independent of any tranport security is valid. In my particular case, in order to leverage Envoy for request routing, the cluster/service name must be provided in the :authority header. This may also be useful in a testing context. This patch adds a DialOption to overwrite the authority header, even if TransportCredentials are provided (I'd imagine you'd only ever need to specify one or the other).
This commit is contained in:
parent
21f8ed3094
commit
84bee50bda
|
@ -263,6 +263,15 @@ func WithStreamInterceptor(f StreamClientInterceptor) DialOption {
|
|||
}
|
||||
}
|
||||
|
||||
// WithAuthority returns a DialOption that specifies the value to be used as
|
||||
// the :authority pseudo-header. This value overrides the :authority value
|
||||
// provided by TransportCredentials if present.
|
||||
func WithAuthority(a string) DialOption {
|
||||
return func(o *dialOptions) {
|
||||
o.copts.Authority = a
|
||||
}
|
||||
}
|
||||
|
||||
// Dial creates a client connection to the given target.
|
||||
func Dial(target string, opts ...DialOption) (*ClientConn, error) {
|
||||
return DialContext(context.Background(), target, opts...)
|
||||
|
@ -319,7 +328,9 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
|||
cc.dopts.bs = DefaultBackoffConfig
|
||||
}
|
||||
creds := cc.dopts.copts.TransportCredentials
|
||||
if creds != nil && creds.Info().ServerName != "" {
|
||||
if cc.dopts.copts.Authority != "" {
|
||||
cc.authority = cc.dopts.copts.Authority
|
||||
} else if creds != nil && creds.Info().ServerName != "" {
|
||||
cc.authority = creds.Info().ServerName
|
||||
} else {
|
||||
colonPos := strings.LastIndex(target, ":")
|
||||
|
|
|
@ -85,6 +85,22 @@ func TestTLSServerNameOverwrite(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestWithAuthority(t *testing.T) {
|
||||
overwriteServerName := "over.write.server.name"
|
||||
creds, err := credentials.NewClientTLSFromFile(tlsDir+"ca.pem", "transport.security.overwrite")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create credentials %v", err)
|
||||
}
|
||||
conn, err := Dial("Non-Existent.Server:80", WithTransportCredentials(creds), WithAuthority(overwriteServerName))
|
||||
if err != nil {
|
||||
t.Fatalf("Dial(_, _) = _, %v, want _, <nil>", err)
|
||||
}
|
||||
conn.Close()
|
||||
if conn.authority != overwriteServerName {
|
||||
t.Fatalf("%v.authority = %v, want %v", conn, conn.authority, overwriteServerName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDialContextCancel(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
|
|
|
@ -374,6 +374,8 @@ func NewServerTransport(protocol string, conn net.Conn, config *ServerConfig) (S
|
|||
type ConnectOptions struct {
|
||||
// UserAgent is the application user agent.
|
||||
UserAgent string
|
||||
// Authority is the :authority pseudo-header to use.
|
||||
Authority string
|
||||
// Dialer specifies how to dial a network address.
|
||||
Dialer func(context.Context, string) (net.Conn, error)
|
||||
// FailOnNonTempDialError specifies if gRPC fails on non-temporary dial errors.
|
||||
|
|
Loading…
Reference in New Issue