From 614b1687cfdc1cf71a0a57b42af4208249698702 Mon Sep 17 00:00:00 2001 From: zhyuri <4649294+zhyuri@users.noreply.github.com> Date: Tue, 18 Mar 2025 08:47:55 -0400 Subject: [PATCH] Restore Unix socket support (#498) https://github.com/fullstorydev/grpcurl/issues/496 Restore -unix to working properly by default with the default dialer. --- cmd/grpcurl/grpcurl.go | 14 +++++++------- grpcurl.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/cmd/grpcurl/grpcurl.go b/cmd/grpcurl/grpcurl.go index b794288..afddba7 100644 --- a/cmd/grpcurl/grpcurl.go +++ b/cmd/grpcurl/grpcurl.go @@ -484,12 +484,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 { @@ -557,7 +557,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 4407d8a..ff4b00a 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