diff --git a/cmd/grpcurl/grpcurl.go b/cmd/grpcurl/grpcurl.go index 80f87bf..eb02e27 100644 --- a/cmd/grpcurl/grpcurl.go +++ b/cmd/grpcurl/grpcurl.go @@ -483,12 +483,12 @@ func main() { if *maxMsgSz > 0 { opts = append(opts, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(*maxMsgSz))) } - network := "tcp" - if isUnixSocket != nil && isUnixSocket() { - network = "unix" - if *authority == "" { - *authority = "localhost" - } + if isUnixSocket != nil && isUnixSocket() && !strings.HasPrefix(target, "unix://") { + // prepend unix:// to the address if it's not already there + // this is to maintain backwards compatibility because the custom dialer is replaced by + // the default dialer in grpc-go. + // https://github.com/fullstorydev/grpcurl/pull/480 + target = "unix://" + target } var creds credentials.TransportCredentials if *plaintext { @@ -556,7 +556,7 @@ func main() { blockingDialTiming := dialTiming.Child("BlockingDial") defer blockingDialTiming.Done() - cc, err := grpcurl.BlockingDial(ctx, network, target, creds, opts...) + cc, err := grpcurl.BlockingDial(ctx, "", target, creds, opts...) if err != nil { fail(err, "Failed to dial target host %q", target) } diff --git a/grpcurl.go b/grpcurl.go index 9c8b08b..91f23d2 100644 --- a/grpcurl.go +++ b/grpcurl.go @@ -609,6 +609,8 @@ func ServerTransportCredentials(cacertFile, serverCertFile, serverKeyFile string // BlockingDial is a helper method to dial the given address, using optional TLS credentials, // and blocking until the returned connection is ready. If the given credentials are nil, the // connection will be insecure (plain-text). +// The network parameter should be left empty in most cases when your address is a RFC 3986 +// compliant URI. The resolver from grpc-go will resolve the correct network type. func BlockingDial(ctx context.Context, network, address string, creds credentials.TransportCredentials, opts ...grpc.DialOption) (*grpc.ClientConn, error) { if creds == nil { creds = insecure.NewCredentials() @@ -645,6 +647,34 @@ func BlockingDial(ctx context.Context, network, address string, creds credential writeResult: writeResult, } + switch network { + case "": + // no-op, use address as-is + case "tcp": + if strings.HasPrefix(address, "unix://") { + return nil, fmt.Errorf("tcp network type cannot use unix address %s", address) + } + case "unix": + if !strings.HasPrefix(address, "unix://") { + // prepend unix:// to the address if it's not already there + // this is to maintain backwards compatibility because the custom dialer is replaced by + // the default dialer in grpc-go. + // https://github.com/fullstorydev/grpcurl/pull/480 + address = "unix://" + address + } + default: + // custom dialer for other networks + dialer := func(ctx context.Context, address string) (net.Conn, error) { + conn, err := (&net.Dialer{}).DialContext(ctx, network, address) + if err != nil { + // capture the error so we can provide a better message + writeResult(err) + } + return conn, err + } + opts = append([]grpc.DialOption{grpc.WithContextDialer(dialer)}, opts...) + } + // Even with grpc.FailOnNonTempDialError, this call will usually timeout in // the face of TLS handshake errors. So we can't rely on grpc.WithBlock() to // know when we're done. So we run it in a goroutine and then use result