27 Commits
v1.9.2 ... tmp

Author SHA1 Message Date
bcleenders
13ca681bad Add support for TLS 1.3
This PR allows TLS 1.3, by removing the MaxVersion in the client config.

This would silently swallow errors, so e.g. a client without cert
dialing a server that requires client certs would lead to an error which
gets ignored, leading to retries until timeout.

In this PR, we wrap the connection and if an error occurs we send it to
the existing `result` channel.

I think this matches @jhump's comment in https://github.com/fullstorydev/grpcurl/issues/387#issuecomment-1517098394

 **Testing**

```console
 # Start the test server (in another tab)
go run ./internal/testing/cmd/testserver \
    -cert internal/testing/tls/server.crt \
    -key internal/testing/tls/server.key \
    -cacert internal/testing/tls/ca.crt \
    -requirecert -p 9999

 # Old behavior
$ grpcurl -cacert internal/testing/tls/ca.crt \
    localhost:9999 list
Failed to dial target host "localhost:9999": context deadline exceeded

 # New behavior
$ go run ./cmd/grpcurl -cacert internal/testing/tls/ca.crt \
    localhost:9999 list
Failed to dial target host "localhost:9999": remote error: tls: certificate required
exit status 1
```

The old behavior is to hang until we hit the deadline. The new behavior
is to return immediately with an error.

Fixes #563
2026-06-06 15:36:00 +02:00
Oleg Bonar
cb68aaa7f5 Bump google.golang.org/grpc from 1.66.2 to 1.80.0 (#556)
Migrate from deprecated grpc.DialContext/WithBlock to grpc.NewClient
with connectivity state polling in BlockingDial. Add passthrough:///
scheme prefix for bare addresses to preserve resolver behavior.
2026-06-05 11:02:39 -04:00
Shreyas Sriram
2922de784b Bump google.golang.org/grpc to v1.79.3 (CVE-2026-33186 + 3 transitive CVEs) (#559)
* Bump google.golang.org/grpc to v1.79.3 and transitive deps

Upgrades google.golang.org/grpc from v1.66.2 to v1.79.3 to remediate
CVE-2026-33186 (Critical severity, known exploit per VulnCheck).

This also pulls in updated transitive deps that fix additional CVEs:
- golang.org/x/net v0.38.0 → v0.48.0 (CVE-2025-22870, CVE-2025-22872)
- golang.org/x/oauth2 v0.27.0 → v0.34.0 (CVE-2025-22868)
- golang.org/x/sys v0.31.0 → v0.39.0
- golang.org/x/text v0.23.0 → v0.32.0
- cel.dev/expr v0.15.0 → v0.25.1

All existing tests pass.

* Also bump github.com/go-jose/go-jose/v4 to v4.1.4 (Medium vuln)
2026-05-26 15:01:26 -04:00
cuoguojida
f30a5a5545 refactor: remove obsolete // +build tag (#560)
Signed-off-by: cuoguojida <cuoguojida@outlook.com>
2026-05-19 07:47:53 -04:00
Konstantin Preißer
5725f04a83 Try to add Windows Arm64 releases by removing the ignore entry for that combination. (#542)
Fixes fullstorydev/grpcurl#541
2026-05-11 17:03:53 -04:00
dependabot[bot]
c54eac28fd Bump github.com/jhump/protoreflect from 1.17.0 to 1.18.0 (#545)
Bumps [github.com/jhump/protoreflect](https://github.com/jhump/protoreflect) from 1.17.0 to 1.18.0.
- [Release notes](https://github.com/jhump/protoreflect/releases)
- [Commits](https://github.com/jhump/protoreflect/compare/v1.17.0...v1.18.0)

---
updated-dependencies:
- dependency-name: github.com/jhump/protoreflect
  dependency-version: 1.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-27 12:58:19 -05:00
Scott Blum
6caf0e77fa update lead version to Go 1.25 (#543) 2026-01-22 16:01:15 -05:00
rifeplight
1ad1dc15dd refactor: use strings.Builder to improve performance (#537)
Signed-off-by: rifeplight <rifeplight@outlook.com>
2025-10-29 08:07:46 -04:00
vastonus
f575e91b2c refactor: use slices.Contains to simplify code (#536)
Signed-off-by: vastonus <vastonus@outlook.com>
2025-10-16 07:57:01 -04:00
dependabot[bot]
ed672b2bc9 Bump google.golang.org/protobuf from 1.36.8 to 1.36.10 (#535)
Bumps google.golang.org/protobuf from 1.36.8 to 1.36.10.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-version: 1.36.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-06 15:17:34 -04:00
PietroPasotti
eab6c910a6 add arm build for snap (#534) 2025-09-29 09:41:10 -04:00
dependabot[bot]
60e53f304f Bump google.golang.org/protobuf from 1.36.7 to 1.36.8 (#527)
Bumps google.golang.org/protobuf from 1.36.7 to 1.36.8.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-version: 1.36.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-25 19:09:35 -04:00
dependabot[bot]
f093930c85 Bump google.golang.org/protobuf from 1.36.6 to 1.36.7 (#525)
Bumps google.golang.org/protobuf from 1.36.6 to 1.36.7.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-version: 1.36.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-13 12:09:18 -04:00
Mikel Olasagasti Uranga
7ad93a42d9 test: Update TLS error checks for Go 1.25 compatibility (#522)
The error message for client certificate failures changed in Go 1.25.
Update tests to check for both the old ("bad certificate") and new
("handshake failure") error strings to support multiple Go versions.

Signed-off-by: Mikel Olasagasti Uranga <mikel@olasagasti.info>
2025-07-24 18:11:12 -04:00
dependabot[bot]
7155fb6211 Bump golang.org/x/oauth2 from 0.14.0 to 0.27.0 in the go_modules group (#520)
Bumps the go_modules group with 1 update: [golang.org/x/oauth2](https://github.com/golang/oauth2).


Updates `golang.org/x/oauth2` from 0.14.0 to 0.27.0
- [Commits](https://github.com/golang/oauth2/compare/v0.14.0...v0.27.0)

---
updated-dependencies:
- dependency-name: golang.org/x/oauth2
  dependency-version: 0.27.0
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-18 14:47:35 -04:00
dependabot[bot]
f28d506cea Bump golang.org/x/net from 0.36.0 to 0.38.0 in the go_modules group (#517)
Bumps the go_modules group with 1 update: [golang.org/x/net](https://github.com/golang/net).


Updates `golang.org/x/net` from 0.36.0 to 0.38.0
- [Commits](https://github.com/golang/net/compare/v0.36.0...v0.38.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.38.0
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-16 20:05:23 -04:00
dependabot[bot]
58ccc6321e Bump google.golang.org/protobuf from 1.36.5 to 1.36.6 (#515)
* Bump google.golang.org/protobuf from 1.36.5 to 1.36.6

Bumps google.golang.org/protobuf from 1.36.5 to 1.36.6.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix?

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Scott Blum <dragonsinth@gmail.com>
2025-04-09 11:11:29 -04:00
dependabot[bot]
b519ffc959 Bump golang.org/x/net from 0.33.0 to 0.36.0 in the go_modules group (#511)
Bumps the go_modules group with 1 update: [golang.org/x/net](https://github.com/golang/net).


Updates `golang.org/x/net` from 0.33.0 to 0.36.0
- [Commits](https://github.com/golang/net/compare/v0.33.0...v0.36.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 11:01:11 -04:00
PietroPasotti
3a8fa31879 Snap: strict confinement, stable grade and docs (#514) 2025-03-18 23:01:48 -04:00
zhyuri
614b1687cf Restore Unix socket support (#498)
https://github.com/fullstorydev/grpcurl/issues/496

Restore -unix to working properly by default with the default dialer.
2025-03-18 08:47:55 -04:00
Gustavo Passini
30f87c1323 Set GOWORK=off and GOPATHS=-trimpath when building (#513) 2025-03-17 16:42:39 -04:00
PietroPasotti
78655b4786 snap init (#512) 2025-03-13 10:13:48 -04:00
Joshua Humphries
d00c28104b avoid overflow in various timeouts (#505) 2025-02-19 11:36:35 -05:00
dependabot[bot]
9e3e083f29 Bump google.golang.org/protobuf from 1.36.4 to 1.36.5 (#509)
Bumps google.golang.org/protobuf from 1.36.4 to 1.36.5.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-10 18:03:32 -05:00
dependabot[bot]
c32936d71e Bump golang.org/x/net from 0.25.0 to 0.33.0 (#508)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.25.0 to 0.33.0.
- [Commits](https://github.com/golang/net/compare/v0.25.0...v0.33.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-28 18:44:47 +00:00
dependabot[bot]
f3c8ec2564 Bump google.golang.org/protobuf from 1.34.2 to 1.36.4 (#506)
* Bump google.golang.org/protobuf from 1.34.2 to 1.36.4

Bumps google.golang.org/protobuf from 1.34.2 to 1.36.4.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* ignore deprecations

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Scott Blum <dragonsinth@gmail.com>
2025-01-28 18:39:59 +00:00
Joshua Humphries
7e1a6c9068 Update to v1.17.0 of jhump/protoreflect (#502)
* update to v1.17.0 of jhump/protoreflect

* add lint:ignore annotations to fix CI
2025-01-13 10:33:18 -05:00
20 changed files with 429 additions and 242 deletions

View File

@@ -9,22 +9,22 @@ shared_configs:
# Use the latest 2.1 version of CircleCI pipeline process engine. See: https://circleci.com/docs/2.0/configuration-reference
version: 2.1
jobs:
build-1-21:
working_directory: ~/repo
docker:
- image: cimg/go:1.21
steps: *simple_job_steps
build-1-22:
working_directory: ~/repo
docker:
- image: cimg/go:1.22
steps: *simple_job_steps
build-1-23:
working_directory: ~/repo
docker:
- image: cimg/go:1.23
steps: *simple_job_steps
build-1-24:
working_directory: ~/repo
docker:
- image: cimg/go:1.24
steps: *simple_job_steps
build-1-25:
working_directory: ~/repo
docker:
- image: cimg/go:1.25
steps:
- checkout
- run:
@@ -35,6 +35,6 @@ jobs:
workflows:
pr-build-test:
jobs:
- build-1-21
- build-1-22
- build-1-23
- build-1-24
- build-1-25

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@ dist/
.idea/
VERSION
.tmp/
*.snap

View File

@@ -19,8 +19,6 @@ builds:
ignore:
- goos: darwin
goarch: 386
- goos: windows
goarch: arm64
- goos: darwin
goarch: arm
- goos: windows

View File

@@ -1,5 +1,5 @@
FROM golang:1.23-alpine as builder
MAINTAINER Fullstory Engineering
FROM golang:1.25-alpine AS builder
LABEL maintainer="Fullstory Engineering"
# create non-privileged group and user
RUN addgroup -S grpcurl && adduser -S grpcurl -G grpcurl
@@ -16,7 +16,7 @@ RUN go build -o /grpcurl \
-ldflags "-w -extldflags \"-static\" -X \"main.version=$(cat VERSION)\"" \
./cmd/grpcurl
FROM alpine:3 as alpine
FROM alpine:3 AS alpine
WORKDIR /
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /etc/passwd /etc/passwd

View File

@@ -4,6 +4,8 @@ export PATH := $(shell pwd)/.tmp/protoc/bin:$(PATH)
export PROTOC_VERSION := 22.0
# Disable CGO for improved compatibility across distros
export CGO_ENABLED=0
export GOFLAGS=-trimpath
export GOWORK=off
# TODO: run golint and errcheck, but only to catch *new* violations and
# decide whether to change code or not (e.g. we need to be able to whitelist
@@ -48,9 +50,9 @@ generate: .tmp/protoc/bin/protoc
.PHONY: checkgenerate
checkgenerate: generate
git status --porcelain
@if [ -n "$$(git status --porcelain)" ]; then \
git diff; \
git status --porcelain -- '**/*.go'
@if [ -n "$$(git status --porcelain -- '**/*.go')" ]; then \
git diff -- '**/*.go'; \
exit 1; \
fi
@@ -67,8 +69,8 @@ vet:
.PHONY: staticcheck
staticcheck:
@go install honnef.co/go/tools/cmd/staticcheck@v0.5.1
staticcheck ./...
@go install honnef.co/go/tools/cmd/staticcheck@2025.1.1
staticcheck -checks "inherit,-SA1019" ./...
.PHONY: ineffassign
ineffassign:
@@ -77,7 +79,7 @@ ineffassign:
.PHONY: predeclared
predeclared:
@go install github.com/nishanths/predeclared@245576f9a85c
@go install github.com/nishanths/predeclared@51e8c974458a0f93dc03fe356f91ae1a6d791e6f
predeclared ./...
# Intentionally omitted from CI, but target here for ad-hoc reports.
@@ -93,8 +95,7 @@ errcheck:
errcheck ./...
.PHONY: test
test:
# The race detector requires CGO: https://github.com/golang/go/issues/6508
test: deps
CGO_ENABLED=1 go test -race ./...
.tmp/protoc/bin/protoc: ./Makefile ./download_protoc.sh

View File

@@ -1,6 +1,7 @@
# gRPCurl
[![Build Status](https://circleci.com/gh/fullstorydev/grpcurl/tree/master.svg?style=svg)](https://circleci.com/gh/fullstorydev/grpcurl/tree/master)
[![Go Report Card](https://goreportcard.com/badge/github.com/fullstorydev/grpcurl)](https://goreportcard.com/report/github.com/fullstorydev/grpcurl)
[![Snap Release Status](https://snapcraft.io/grpcurl/badge.svg)](https://snapcraft.io/grpcurl)
`grpcurl` is a command-line tool that lets you interact with gRPC servers. It's
basically `curl` for gRPC servers.
@@ -79,6 +80,12 @@ of environments, including Windows and myriad Linux distributions.
You can see more details and the full list of other packages for `grpcurl` at _repology.org_:
https://repology.org/project/grpcurl/information
### Snap
You can install `grpcurl` using the snap package:
`snap install grpcurl`
### From Source
If you already have the [Go SDK](https://golang.org/doc/install) installed, you can use the `go`
tool to install `grpcurl`:

View File

@@ -8,13 +8,14 @@ import (
"flag"
"fmt"
"io"
"math"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/jhump/protoreflect/desc"
"github.com/jhump/protoreflect/desc" //lint:ignore SA1019 required to use APIs in other grpcurl package
"github.com/jhump/protoreflect/grpcreflect"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
@@ -457,7 +458,7 @@ func main() {
ctx := context.Background()
if *maxTime > 0 {
timeout := time.Duration(*maxTime * float64(time.Second))
timeout := floatSecondsToDuration(*maxTime)
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, timeout)
defer cancel()
@@ -468,13 +469,13 @@ func main() {
defer dialTiming.Done()
dialTime := 10 * time.Second
if *connectTimeout > 0 {
dialTime = time.Duration(*connectTimeout * float64(time.Second))
dialTime = floatSecondsToDuration(*connectTimeout)
}
ctx, cancel := context.WithTimeout(ctx, dialTime)
defer cancel()
var opts []grpc.DialOption
if *keepaliveTime > 0 {
timeout := time.Duration(*keepaliveTime * float64(time.Second))
timeout := floatSecondsToDuration(*keepaliveTime)
opts = append(opts, grpc.WithKeepaliveParams(keepalive.ClientParameters{
Time: timeout,
Timeout: timeout,
@@ -483,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 {
@@ -556,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)
}
@@ -847,11 +848,11 @@ func main() {
}
func dumpTiming(td *timingData, lvl int) {
ind := ""
var ind strings.Builder
for x := 0; x < lvl; x++ {
ind += " "
ind.WriteString(" ")
}
fmt.Printf("%s%s: %s\n", ind, td.Title, td.Value)
fmt.Printf("%s%s: %s\n", ind.String(), td.Title, td.Value)
for _, sd := range td.Sub {
dumpTiming(sd, lvl+1)
}
@@ -971,3 +972,12 @@ func (f *optionalBoolFlag) Set(s string) error {
func (f *optionalBoolFlag) IsBoolFlag() bool {
return true
}
func floatSecondsToDuration(seconds float64) time.Duration {
durationFloat := seconds * float64(time.Second)
if durationFloat > math.MaxInt64 {
// Avoid overflow
return math.MaxInt64
}
return time.Duration(durationFloat)
}

View File

@@ -1,5 +1,4 @@
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package main

View File

@@ -9,11 +9,11 @@ import (
"path/filepath"
"sync"
"github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import this because it appears in exported API
"github.com/jhump/protoreflect/desc"
"github.com/jhump/protoreflect/desc/protoparse"
"github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import these because some of their types appear in exported API
"github.com/jhump/protoreflect/desc" //lint:ignore SA1019 same as above
"github.com/jhump/protoreflect/desc/protoparse" //lint:ignore SA1019 same as above
"github.com/jhump/protoreflect/desc/protoprint"
"github.com/jhump/protoreflect/dynamic"
"github.com/jhump/protoreflect/dynamic" //lint:ignore SA1019 same as above
"github.com/jhump/protoreflect/grpcreflect"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

View File

@@ -11,10 +11,10 @@ import (
"strings"
"sync"
"github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 we have to import this because it appears in exported API
"github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import this because it appears in exported API
"github.com/jhump/protoreflect/desc"
"github.com/jhump/protoreflect/dynamic"
"github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 we have to import these because some of their types appear in exported API
"github.com/golang/protobuf/proto" //lint:ignore SA1019 same as above
"github.com/jhump/protoreflect/desc" //lint:ignore SA1019 same as above
"github.com/jhump/protoreflect/dynamic" //lint:ignore SA1019 same as above
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"

View File

@@ -7,9 +7,9 @@ import (
"strings"
"testing"
"github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 we have to import this because it appears in exported API
"github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import this because it appears in exported API
"github.com/jhump/protoreflect/desc"
"github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 we have to import these because some of their types appear in exported API
"github.com/golang/protobuf/proto" //lint:ignore SA1019 same as above
"github.com/jhump/protoreflect/desc" //lint:ignore SA1019 same as above
"google.golang.org/grpc/metadata"
"google.golang.org/protobuf/types/known/structpb"
)

47
go.mod
View File

@@ -1,31 +1,34 @@
module github.com/fullstorydev/grpcurl
go 1.21
go 1.24.0
toolchain go1.24.1
require (
github.com/golang/protobuf v1.5.4
github.com/jhump/protoreflect v1.16.0
google.golang.org/grpc v1.61.0
google.golang.org/protobuf v1.34.2
github.com/jhump/protoreflect v1.18.0
google.golang.org/grpc v1.80.0
google.golang.org/protobuf v1.36.11
)
require (
cloud.google.com/go/compute v1.23.3 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/bufbuild/protocompile v0.10.0 // indirect
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 // indirect
github.com/envoyproxy/go-control-plane v0.11.1 // indirect
github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/oauth2 v0.14.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect
cel.dev/expr v0.25.1 // indirect
cloud.google.com/go/compute/metadata v0.9.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect
github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect
github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/jhump/protoreflect/v2 v2.0.0-beta.1 // indirect
github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect
github.com/stretchr/testify v1.11.1 // indirect
golang.org/x/net v0.49.0 // indirect
golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.33.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect
)

188
go.sum
View File

@@ -1,124 +1,80 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/bufbuild/protocompile v0.10.0 h1:+jW/wnLMLxaCEG8AX9lD0bQ5v9h1RUiMKOBOT5ll9dM=
github.com/bufbuild/protocompile v0.10.0/go.mod h1:G9qQIQo0xZ6Uyj6CMNz0saGmx2so+KONo8/KrELABiY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk=
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY=
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=
cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w=
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM=
github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA=
github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU=
github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g=
github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4=
github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jhump/protoreflect v1.16.0 h1:54fZg+49widqXYQ0b+usAFHbMkBGR4PpXrsHc8+TBDg=
github.com/jhump/protoreflect v1.16.0/go.mod h1:oYPd7nPvcBw/5wlDfm/AVmU9zH9BgqGCI469pGxfj/8=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jhump/protoreflect v1.18.0 h1:TOz0MSR/0JOZ5kECB/0ufGnC2jdsgZ123Rd/k4Z5/2w=
github.com/jhump/protoreflect v1.18.0/go.mod h1:ezWcltJIVF4zYdIFM+D/sHV4Oh5LNU08ORzCGfwvTz8=
github.com/jhump/protoreflect/v2 v2.0.0-beta.1 h1:Dw1rslK/VotaUGYsv53XVWITr+5RCPXfvvlGrM/+B6w=
github.com/jhump/protoreflect/v2 v2.0.0-beta.1/go.mod h1:D9LBEowZyv8/iSu97FU2zmXG3JxVTmNw21mu63niFzU=
github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 h1:KPpdlQLZcHfTMQRi6bFQ7ogNO0ltFT4PmtwTLW4W+14=
github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0=
golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ=
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY=
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo=
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0=
google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo=
github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 h1:vmC/ws+pLzWjj/gzApyoZuSVrDtF1aod4u/+bbj8hgM=
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:p3MLuOwURrGBRoEyFHBT3GjUwaCQVKeNqqWxlcISGdw=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 h1:sNrWoksmOyF5bvJUcnmbeAmQi8baNhqg5IWaI3llQqU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@@ -17,14 +17,17 @@ import (
"net"
"os"
"regexp"
"slices"
"sort"
"strings"
"sync"
"github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import this because it appears in exported API
"github.com/jhump/protoreflect/desc"
"github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import these because some of their types appear in exported API
"github.com/jhump/protoreflect/desc" //lint:ignore SA1019 same as above
"github.com/jhump/protoreflect/desc/protoprint"
"github.com/jhump/protoreflect/dynamic"
"github.com/jhump/protoreflect/dynamic" //lint:ignore SA1019 same as above
"google.golang.org/grpc"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
xdsCredentials "google.golang.org/grpc/credentials/xds"
@@ -450,11 +453,9 @@ func makeTemplate(md *desc.MessageDescriptor, path []*desc.MessageDescriptor) pr
dm := dynamic.NewMessage(md)
// if the message is a recursive structure, we don't want to blow the stack
for _, seen := range path {
if seen == md {
// already visited this type; avoid infinite recursion
return dm
}
if slices.Contains(path, md) {
// already visited this type; avoid infinite recursion
return dm
}
path = append(path, dm.GetMessageDescriptor())
@@ -568,9 +569,6 @@ func ClientTLSConfig(insecureSkipVerify bool, cacertFile, clientCertFile, client
// client certs. The serverCertFile and serverKeyFile must both not be blank.
func ServerTransportCredentials(cacertFile, serverCertFile, serverKeyFile string, requireClientCerts bool) (credentials.TransportCredentials, error) {
var tlsConf tls.Config
// TODO(jh): Remove this line once https://github.com/golang/go/issues/28779 is fixed
// in Go tip. Until then, the recently merged TLS 1.3 support breaks the TLS tests.
tlsConf.MaxVersion = tls.VersionTLS12
// Load the server certificates from disk
certificate, err := tls.LoadX509KeyPair(serverCertFile, serverKeyFile)
@@ -609,6 +607,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,26 +645,69 @@ func BlockingDial(ctx context.Context, network, address string, creds credential
writeResult: writeResult,
}
// 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
// channel to either get the connection or fail-fast.
go func() {
// We put grpc.FailOnNonTempDialError *before* the explicitly provided
// options so that it could be overridden.
opts = append([]grpc.DialOption{grpc.FailOnNonTempDialError(true)}, opts...)
// But we don't want caller to be able to override these two, so we put
// them *after* the explicitly provided options.
opts = append(opts, grpc.WithBlock(), grpc.WithTransportCredentials(creds))
conn, err := grpc.DialContext(ctx, address, opts...)
var res interface{}
if err != nil {
res = err
} else {
res = conn
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...)
}
// grpc.NewClient does not connect immediately, so we use conn.Connect()
// to trigger eager connection and then poll connectivity state to block
// until ready. The errSignalingCreds wrapper will capture TLS handshake
// errors and write them to the result channel for fail-fast behavior.
// Normalize address for NewClient which defaults to "dns" resolver.
// Bare host:port addresses need "passthrough:///" to preserve the old
// grpc.Dial behavior.
if !strings.Contains(address, "://") {
address = "passthrough:///" + address
}
opts = append(opts, grpc.WithTransportCredentials(creds))
conn, err := grpc.NewClient(address, opts...)
if err != nil {
return nil, err
}
conn.Connect()
go func() {
for {
s := conn.GetState()
if s == connectivity.Ready {
writeResult(conn)
return
}
if s == connectivity.Shutdown {
return
}
if !conn.WaitForStateChange(ctx, s) {
// Context expired
return
}
}
writeResult(res)
}()
select {
@@ -689,6 +732,34 @@ func (c *errSignalingCreds) ClientHandshake(ctx context.Context, addr string, ra
conn, auth, err := c.TransportCredentials.ClientHandshake(ctx, addr, rawConn)
if err != nil {
c.writeResult(err)
return conn, auth, err
}
return conn, auth, err
// Wrap TLS connections to capture post-handshake errors. With TLS 1.3,
// client certificate rejection by the server happens after the client
// considers the handshake complete. The server's TLS alert surfaces on the
// first Read from the connection. Only TLS connections need this (plaintext
// connections don't have post-handshake alerts).
if _, isTLS := auth.(credentials.TLSInfo); isTLS {
conn = &errSignalingConn{Conn: conn, writeResult: c.writeResult}
}
return conn, auth, nil
}
// errSignalingConn wraps a net.Conn to capture the first read error and
// report it via writeResult. This allows BlockingDial to surface post-handshake
// errors.
type errSignalingConn struct {
net.Conn
writeResult func(res interface{})
once sync.Once
}
func (c *errSignalingConn) Read(b []byte) (int, error) {
n, err := c.Conn.Read(b)
if err != nil {
c.once.Do(func() {
c.writeResult(err)
})
}
return n, err
}

View File

@@ -12,9 +12,9 @@ import (
"testing"
"time"
"github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 we have to import this because it appears in exported API
"github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import this because it appears in exported API
"github.com/jhump/protoreflect/desc"
"github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 we have to import these because some of their types appear in exported API
"github.com/golang/protobuf/proto" //lint:ignore SA1019 same as above
"github.com/jhump/protoreflect/desc" //lint:ignore SA1019 same as above
"github.com/jhump/protoreflect/grpcreflect"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
@@ -74,10 +74,8 @@ func TestMain(m *testing.M) {
defer svrReflect.Stop()
// And a corresponding client
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if ccReflect, err = grpc.DialContext(ctx, fmt.Sprintf("127.0.0.1:%d", portReflect),
grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock()); err != nil {
if ccReflect, err = grpc.NewClient(fmt.Sprintf("passthrough:///127.0.0.1:%d", portReflect),
grpc.WithTransportCredentials(insecure.NewCredentials())); err != nil {
panic(err)
}
defer ccReflect.Close()
@@ -99,10 +97,8 @@ func TestMain(m *testing.M) {
defer svrProtoset.Stop()
// And a corresponding client
ctx, cancel = context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if ccNoReflect, err = grpc.DialContext(ctx, fmt.Sprintf("127.0.0.1:%d", portProtoset),
grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock()); err != nil {
if ccNoReflect, err = grpc.NewClient(fmt.Sprintf("passthrough:///127.0.0.1:%d", portProtoset),
grpc.WithTransportCredentials(insecure.NewCredentials())); err != nil {
panic(err)
}
defer ccNoReflect.Close()

View File

@@ -1,5 +1,4 @@
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package main

View File

@@ -9,10 +9,10 @@ import (
"sync"
"sync/atomic"
"github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 we have to import this because it appears in exported API
"github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import this because it appears in exported API
"github.com/jhump/protoreflect/desc"
"github.com/jhump/protoreflect/dynamic"
"github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 we have to import these because some of their types appear in exported API
"github.com/golang/protobuf/proto" //lint:ignore SA1019 same as above
"github.com/jhump/protoreflect/desc" //lint:ignore SA1019 same as above
"github.com/jhump/protoreflect/dynamic" //lint:ignore SA1019 same as above
"github.com/jhump/protoreflect/dynamic/grpcdynamic"
"github.com/jhump/protoreflect/grpcreflect"
"google.golang.org/grpc"

23
snap/README.md Normal file
View File

@@ -0,0 +1,23 @@
# packing and releasing
To pack the current branch to a snap package:
`snapcraft pack`
To install the package locally:
`snap install ./grpcurl_v[version tag]_amd64.snap --devmode`
To upload the snap to the edge channel:
`snapcraft upload --release edge ./grpcurl_v[version tag]_amd64.snap`
(you need to own the package name registration for this!)
# ownership
The snap's current owner is `pietro.pasotti@canonical.com`; who is very happy to support with maintaining the snap distribution and/or transfer its ownership to the developers.
Please reach out to me for questions regarding the snap; including:
- adding support for other architectures
- automating the release
Cheers and thanks for the awesome tool!

47
snap/snapcraft.yaml Normal file
View File

@@ -0,0 +1,47 @@
name: grpcurl
base: core24
# allow grpcurl part to call craftctl set-version
adopt-info: grpcurl
summary: grpcurl is a command-line tool that lets you interact with gRPC servers.
description: |
grpcurl is a command-line tool that lets you interact with gRPC servers.
It's basically curl for gRPC servers.
grade: stable
confinement: strict
license: MIT
platforms:
amd64:
build-on:
- amd64
build-for:
- amd64
arm64:
build-on:
- amd64
- arm64
build-for:
- arm64
apps:
grpcurl:
command: grpcurl
plugs:
- network
parts:
grpcurl:
plugin: go
build-snaps: [go/latest/stable]
source: https://github.com/fullstorydev/grpcurl
source-type: git
override-build: |
tag="$(git describe --tags --abbrev=0)"
craftctl set version="$tag"
go build -o $CRAFT_PART_INSTALL/grpcurl ./cmd/grpcurl/grpcurl.go
# adjust the permissions
chmod 0755 $CRAFT_PART_INSTALL/grpcurl

View File

@@ -2,6 +2,7 @@ package grpcurl_test
import (
"context"
"crypto/tls"
"fmt"
"net"
"strings"
@@ -10,6 +11,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/peer"
. "github.com/fullstorydev/grpcurl"
grpcurl_testing "github.com/fullstorydev/grpcurl/internal/testing"
@@ -101,6 +103,68 @@ func TestRequireClientCertTLS(t *testing.T) {
simpleTest(t, e.cc)
}
func TestTLS12(t *testing.T) {
serverCreds, err := ServerTransportCredentials("", "internal/testing/tls/server.crt", "internal/testing/tls/server.key", false)
if err != nil {
t.Fatalf("failed to create server creds: %v", err)
}
tlsConf, err := ClientTLSConfig(false, "internal/testing/tls/ca.crt", "", "")
if err != nil {
t.Fatalf("failed to create client TLS config: %v", err)
}
tlsConf.MaxVersion = tls.VersionTLS12
e, err := createTestServerAndClient(serverCreds, credentials.NewTLS(tlsConf))
if err != nil {
t.Fatalf("failed to setup server and client: %v", err)
}
defer e.Close()
tlsVersion := negotiatedTLSVersion(t, e.cc)
if tlsVersion != tls.VersionTLS12 {
t.Errorf("expected TLS 1.2, got 0x%04x", tlsVersion)
}
}
func TestTLS13(t *testing.T) {
serverCreds, err := ServerTransportCredentials("", "internal/testing/tls/server.crt", "internal/testing/tls/server.key", false)
if err != nil {
t.Fatalf("failed to create server creds: %v", err)
}
clientCreds, err := ClientTransportCredentials(false, "internal/testing/tls/ca.crt", "", "")
if err != nil {
t.Fatalf("failed to create client creds: %v", err)
}
e, err := createTestServerAndClient(serverCreds, clientCreds)
if err != nil {
t.Fatalf("failed to setup server and client: %v", err)
}
defer e.Close()
tlsVersion := negotiatedTLSVersion(t, e.cc)
if tlsVersion != tls.VersionTLS13 {
t.Errorf("expected TLS 1.3, got 0x%04x", tlsVersion)
}
}
func negotiatedTLSVersion(t *testing.T, cc *grpc.ClientConn) uint16 {
t.Helper()
cl := grpcurl_testing.NewTestServiceClient(cc)
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
var p peer.Peer
_, err := cl.UnaryCall(ctx, &grpcurl_testing.SimpleRequest{}, grpc.WaitForReady(true), grpc.Peer(&p))
if err != nil {
t.Fatalf("RPC failed: %v", err)
}
tlsInfo, ok := p.AuthInfo.(credentials.TLSInfo)
if !ok {
t.Fatalf("expected TLS auth info, got %T", p.AuthInfo)
}
return tlsInfo.State.Version
}
func TestBrokenTLS_ClientPlainText(t *testing.T) {
serverCreds, err := ServerTransportCredentials("", "internal/testing/tls/server.crt", "internal/testing/tls/server.key", false)
if err != nil {
@@ -253,8 +317,14 @@ func TestBrokenTLS_ClientNotTrusted(t *testing.T) {
e.Close()
t.Fatal("expecting TLS failure setting up server and client")
}
if !strings.Contains(err.Error(), "bad certificate") {
t.Fatalf("expecting TLS certificate error, got: %v", err)
// The exact TLS alert varies by Go version and TLS version negotiated:
// - TLS 1.2: "bad certificate" (Go <=1.24) or "handshake failure" (Go 1.25+)
// - TLS 1.3: "certificate required" (server rejects after handshake)
errMsg := err.Error()
if !strings.Contains(errMsg, "bad certificate") &&
!strings.Contains(errMsg, "handshake failure") &&
!strings.Contains(errMsg, "certificate required") {
t.Fatalf("expecting a TLS certificate error, got: %v", err)
}
}
@@ -293,8 +363,14 @@ func TestBrokenTLS_RequireClientCertButNonePresented(t *testing.T) {
e.Close()
t.Fatal("expecting TLS failure setting up server and client")
}
if !strings.Contains(err.Error(), "bad certificate") {
t.Fatalf("expecting TLS certificate error, got: %v", err)
// The exact TLS alert varies by Go version and TLS version negotiated:
// - TLS 1.2: "bad certificate" (Go <=1.24) or "handshake failure" (Go 1.25+)
// - TLS 1.3: "certificate required" (server rejects after handshake)
errMsg := err.Error()
if !strings.Contains(errMsg, "bad certificate") &&
!strings.Contains(errMsg, "handshake failure") &&
!strings.Contains(errMsg, "certificate required") {
t.Fatalf("expecting a TLS certificate error, got: %v", err)
}
}