upgrade to latest dependencies (#927)

bumping golang.org/x/sys 863b3c4...74cfc93:
  > 74cfc93 all: upgrade go directive to at least 1.23.0 [generated]
bumping knative.dev/hack ce4c934...306ce74:
  > 306ce74 Update community files (# 414)
bumping knative.dev/pkg ae2c6bc...b7bbf4b:
  > b7bbf4b Bump google.golang.org/grpc from 1.70.0 to 1.71.0 (# 3157)
  > 097c752 Bump golang.org/x/tools from 0.30.0 to 0.31.0 (# 3155)
  > 0372c08 Bump github.com/google/go-cmp from 0.6.0 to 0.7.0 (# 3152)
  > 9e26561 Update community files (# 3151)
  > c925de2 upgrade to latest dependencies (# 3150)
bumping github.com/google/go-cmp c3ad843...9b12f36:
  > 9b12f36 Detect proto.Message types when failing to export a field (# 370)
  > 4dd3d63 fix: type 'aribica' => 'arabica' (# 368)
  > 391980c Support compare functions with SortSlices and SortMaps (# 367)
bumping golang.org/x/tools 09747cd...6a5b66b:
  > 6a5b66b go.mod: update golang.org/x dependencies
  > 25a90be gopls/internal/golang: Implementations for func types
  > db6008c go/types/internal/play: show Cursor.Stack of selected node
  > ece9e9b gopls/doc/generate: add status in codelenses and inlayhints
  > 340f21a gopls: move gopls/doc/generate package
  > 0721940 gopls/internal/analysis/modernize: strings.Fields -> FieldsSeq
  > 8d38122 gopls/internal/cache: reproduce and fix crash on if cond overflow
  > d81d6fc gopls/internal/util/asm: better assembly parsing
  > 455db21 gopls/internal/cache/parsego: fix OOB crash in fixInitStmt
  > 2b1f550 gopls/internal/analysis/gofix: allow literal array lengths
  > 0ffdb82 gopls/internal/analysis/gofix: add vet analyzer
  > 2839096 gopls/internal/analysis/gofix: generic aliases
  > 0efa5e5 gopls/internal/analysis/modernize: rangeint: non-integer untyped constants
  > d141499 cmd/toolstash: fix windows executable name handling
  > 5f02a3e gopls/internal/analysis/modernize: don't import slices within slices
  > b2aa62b internal/stdlib: provide API for import graph of std library
  > 608d370 internal/imports: use a more straightforward return value
  > 408d2e2 x/tools: remove workarounds for Go <1.23
  > 66eb306 Revert "internal/settings: drop "annotations" setting"
  > ff03c59 gopls/internal/analysis/modernize: append -> bytes.Clone
  > 1cc80ad internal/event/export/ocagent: delete
  > 8f4b8cd gopls/internal/golang: add package symbols comment
  > 57b529a doc/release/v0.18.0.md: add -fix flag
  > 63229bc gopls/internal/analysis/gofix: register "alias" fact type
  > d740adf gopls/internal/settings: correct SemanticTokenTypes source
  > 779331a gopls/internal/test/integration/misc: only test asm on {arm,amd}64
  > 5dc980c gopls/internal/test/integration/misc: fix "want" assembly
  > 6399d21 go/analysis/passes/reflectvaluecompare/cmd/reflectvaluecompare: add main.go
  > 7fed2a4 gopls/internal/analysis/modernize: fix bug in rangeint
  > 6f7906b x/tools: use ast.IsGenerated throughout
  > e890c1f gopls/internal/golang: Assembly: support package level var and init
  > 6d4af1e gopls/internal/golang: Assembly: update "Compiling" message
  > bf9e2a8 gopls/internal: test fixes for some imports bugs
  > 851c747 gopls/internal/golang: fix crash when hovering over implicit
  > 3e76cae internal/analysisinternal: ValidateFix: more specific errors
  > d2fcd36 go/analysis/passes/unreachable/testdata: relax test for CL 638395
  > 2b2a44e gopls/internal/test: avoid panic in TestDoubleParamReturnCompletion
  > 739a5af gopls/internal/test/marker: skip on the freebsd race builder
  > 274b237 gopls: add a -severity flag for gopls check
  > 5299dcb gopls/internal/settings: fix misleading error messages
  > 3d7c2e2 gopls/internal/golang: add missing json tags for hoverResult
  > 6e3d8bc gopls/internal/analysis/gofix: use 1.24 iterators
  > 1c52ccd gopls/internal/analysis/gofix: inline most aliases
  > 4e0c888 gopls/internal/hover: show alias rhs type declaration on hover
  > 7347766 gopls/internal/test: fix failures when running tests with GOTOOLCHAIN
  > f2beb33 gopls: temporarily reinstate the "Structured" hover kind
  > 23211ff gopls/internal/test/integration: better expectation failures
  > 8b85edc gopls/internal: use go1.24-isms
  > f95771e gopls/go.mod: update to go1.24
  > 96bfb60 gopls/internal/analysis/modernize: fix minmax bug
  > 1f6c6d6 gopls/doc: adjust nvim-lspconfig link target
  > 33f1ed9 gopls/go.mod: update dependencies following the v0.18.0 release
  > 9f7a2b6 gopls/doc/features: tweak markdown
  > f0af81c gopls/internal/goasm: support Definition in Go *.s assembly
  > 300465c gopls/internal/analysis/modernize: fix rangeint bug
  > 8a39d47 gopls/internal/golang: Add "Eliminate dot import" code action.
  > 99337eb x/tools: modernize interface{} -> any
  > 107c5b2 gopls/internal/analysis/modernize: disable unsound maps.Clone fix
  > 0b693ed internal/astutil/cursor: FindPos: don't assume Files are in Pos order
  > cd01e86 gopls/internal/golang: make singleFileFixer like fixer
  > 4991e7d gopls/internal/golang: use pgf.Cursor in CodeAction fix
  > 877c1d1 gopls: address various staticcheck findings
  > 44abb0a go/types/internal/play: display type structure
  > 3c245da gopls: fix diagnostics integration test
  > e6754ce gopls/internal/cache/parsego: add File.Cursor, and use it
  > 776604a gopls/internal/analysis/modernize: sortslice: fix crash
  > df7baa0 gopls/internal/analysis/simplifyrange: more precise fix
  > ad5dd98 gopls: fix a few bugs related to the new modcache imports source
  > 4b3fdfd go/analysis/passes/printf: suppress diagnostic for Println("...%XX...")
  > fe883a8 gopls/internal/analysis/unusedvariable: refine bug.Report golang/go# 71812
  > d115b34 gopls/internal/analysis: simplify type-error analyzers with Cursor
  > c18bffa all: delete redundant //go:debug gotypesalias=1 directives [generated]
  > 94db710 all: upgrade go directive to at least 1.23.0 [generated]
  > ead62e9 gopls/internal/analysis/modernize: handle parens
  > 32ffaa3 gopls/internal/analysis/gofix: one function per kind
  > 2880aae gopls/internal/protocol: Avoid omitempty for integer fields
  > 8807101 gopls/internal/analysis/gofix: one function per pass
  > c0dbb60 gopls: tweak release notes
  > 85a3833 internal/analysis/gofix: simple type aliases
  > 809cde4 gopls/internal/analysis/modernize: fix bug in minmax
  > ab04c19 gopls/internal/analysis/modernize: improve rangeint transformation
  > ddd4bde gopls/internal/golang: avoid PackageSymbols errors with missing packages
  > 44b61a1 x/tools: eliminate various unparen (et al) helpers
  > d0d86e4 x/tools: run gopls/internal/analysis/gofix/main.go -fix
  > 2f1b076 x/tools: add //go:fix inline
  > 86f13a9 gopls/internal/analysis/gofix: rename local
  > 5762944 gopls/internal/analysis/gofix: check package visibility
  > f9aad70 go/types/typeutil: avoid shifting uintptr by 32 on 32-bit archs
  > b5a64bb go/analysis/internal/checker: be silent with -fix
  > b752317 internal/analysisinternal: disable AddImport test without go command
  > d98774e cmd/signature-fuzzer/internal/fuzz-generator: update to math/rand/v2
  > 2593262 gopls/internal/telemetry/cmd/stacks: remove leading \b match
  > b3c5d10 gopls: record telemetry counters for settings that are used
  > d2585c4 gopls/internal/golang: folding range: remove FoldingRangeInfo
  > 0d16805 internal/stdlib: update stdlib index for Go 1.24.0
  > 027eab5 go/analysis/analysistest: RunWithSuggestedFix: 3-way merge
  > f61b225 internal/analysisinternal: AddImport puts new import in a group
  > 91bac86 internal/analysisinternal: add CanImport
  > 94c41d3 gopls/internal/golang: add comment about SymbolKind
bumping golang.org/x/sync fe3591b...b637f27:
  > b637f27 errgroup: drop support for Go versions before 1.20
  > 960bf1f all: upgrade go directive to at least 1.23.0 [generated]
bumping golang.org/x/text 3b64043...566b44f:
  > 566b44f go.mod: update golang.org/x dependencies
  > d5156da collate/build: do not use println in tests
  > 221d88c x/text: fix scientific notation by removing extraneous spaces
  > b18c107 internal/export/unicode: change C comment to mention unassigned code points
  > 835f8ac language: use a more straightforward return value
  > ae68efb internal/export/unicode: add CategoryAliases, Cn, and LC
  > 518d9c0 all: upgrade go directive to at least 1.23.0 [generated]
bumping golang.org/x/mod 52289f1...dc121ce:
  > dc121ce all: upgrade go directive to at least 1.23.0 [generated]
bumping golang.org/x/net df97a48...99b3ae0:
  > 99b3ae0 go.mod: update golang.org/x dependencies
  > 85d1d54 go.mod: update golang.org/x dependencies
  > cde1dda proxy, http/httpproxy: do not mismatch IPv6 zone ids against hosts
  > fe7f039 publicsuffix: spruce up code gen and speed up PublicSuffix
  > 459513d internal/http3: move more common stream processing to genericConn
  > aad0180 http2: fix flakiness from t.Log when GOOS=js
  > b73e574 http2: don't log expected errors from writing invalid trailers
  > 5f45c77 internal/http3: make read-data tests usable for server handlers
  > 43c2540 http2, internal/httpcommon: reject userinfo in :authority
  > 1d78a08 http2, internal/httpcommon: factor out server header logic for h2/h3
  > 0d7dc54 quic: add Conn.ConnectionState
  > b4c8655 http2: avoid extended CONNECT hang when connection breaks during startup
  > 163d836 internal/http3: add Server
  > 447f458 context: delete lone example
  > 918d64e context: delete dead code, sync docs with upstream context package
  > 5095d0c all: upgrade go directive to at least 1.23.0 [generated]
  > 8844327 internal/httpcommon: don't depend on net/http
  > cd9d661 route: fix RTM_GET netmask parsing on Darwin
bumping golang.org/x/term 743b270...04218fd:
  > 04218fd go.mod: update golang.org/x dependencies
  > 208db03 all: upgrade go directive to at least 1.23.0 [generated]
bumping google.golang.org/grpc 98a0092...d01db5c:
  > d01db5c Change version to 1.71.0 (# 8105)
  > 012f8bf xds: Enable dualstack flag (# 8134)
  > bf0c885 examples/features/dualstack: Demonstrate Dual Stack functionality (# 8098) (# 8115)
  > 05bdd66 ringhash: Remove TODO comment (# 8096)
  > ddb2484 xds: remove obsolete xDS transport custom dialer option (# 8079)
  > 8528f43 cleanup: replace Dial with NewClient (# 7975)
  > ae2a04f ringhash: Replace DNS resolver before sending xDS Update in test  (# 8091)
  > e55819e lazy: Use channel to wait for resolver error being received in test (# 8088)
  > b524c08 xdsclient: include xds node ID in errors from the WatchResource API (# 8093)
  > 91eb6aa client: improve documentation of target strings (# 8078)
  > 59c84a9 rls: change lossy GetState() and WaitForStateChange() to use grpcsync.PubSub (# 8055)
  > a26ff2a ringhash: Sort endpoints to prevent unnecessary connection attempts (# 8086)
  > fabe274 ringhash:  Delegate subchannel creation to pickfirst (# 8047)
  > 75c51bf interop: Introduce env var for xDS dualstack support and add xDS interop config (# 8081)
  > cf60e5a test: Remove fake petiole in health tests (# 8082)
  > 0003b4f weightedtarget: return erroring picker when no targets are configured (# 8070)
  > 4b5608f xdsclient: invoke connectivity failure callback only after all listed servers have failed (# 8075)
  > ad5cd32 cleanup: Remove test contexts without timeouts (# 8072)
  > e95a4b7 roundrobin: Delegate subchannel creation to pickfirst (# 7966)
  > cbb5c2f advancedtls: update CRL provider certificates (# 8073)
  > c80ea18 interop: Fix logging and totalIterations issues in soak_tests.go (# 8060)
  > e0d191d test/gracefulstop: use stubserver instead of testservice implementation (# 7907)
  > 9afb49d endpointsharding: cast EndpointMap values to *balancerWrapper instead of Balancer (# 8069)
  > 267a09b xds/internal/xdsclient: Add counter metrics for valid and invalid resource updates (# 8038)
  > f227ba9 balancer: Move metrics recorder from BuildOptions to ClientConn (# 8027)
  > 3e27c17 balancer: Enforce embedding requirement for balancer.ClientConn (# 8026)
  > b963f4b deps: bump envoyproxy/go-control-plane/envoy and synchronize go.mods (# 8067)
  > 79b6830 xds: resubmit xds client pool changes from # 7898 along with fix to set fallback bootstrap config from googledirectpath to xdsclient pool (# 8050)
  > 947e2a4 internal/dns: update TestDNSResolver_ExponentialBackoff to not return error before last resolution attempt (# 8061)
  > ee3e8d9 test: modify tests to use stubserver instead of Testservice implementation (# 8022)
  > 990f5e0 endpointsharding, lazy: Remove intermediary gracefulswitch balancers (# 8052)
  > 7dbf12e xds: introduce generic xds clients common configs (# 8024)
  > c524b8b outlierdetection: Support ejection of endpoints  (# 8045)
  > 1318104 Revert "xdsclient: introduce pool to manage multiple xDS clients with same bootstrap content (# 7898)" (# 8058)
  > 39f0e5a vet: make revive check submodules for lint errors (# 8029)
  > e4a0dfd grpcsync : Remove OnceFunc (# 8049)
  > 78eebff stats/opentelemetry: Introduce Tracing API (# 7852)
  > 7e1c9b2 test: modify tests to use stubserver (# 7951)
  > 59411f2 xds: add xDS transport custom dial options support (# 7997)
  > 73e4470 cleanup: fix new vet errors (# 8044)
  > cc637f7 xds: log bootstrap config missing warning from env var only when debugging (# 8039)
  > 3409a56 cleanup: rename fields for clarity (# 8043)
  > b0e2ae9 endpointsharding: Allow children to remain idle if configured (# 8031)
  > 81e4aaf balancer/lazy: Add a lazy balancer (# 8032)
  > e03960d xds: Implement system root certs support (# 8013)
  > cf9e380 picker_wrapper: simplify picker error when timing out waiting for con… (# 8035)
  > 9d4fa67 transport_test: change testgrpc.Emtpy to testpb.Empty (# 8040)
  > 2fd426d transport,grpc: Integrate delegating resolver and introduce dial options for target host resolution (# 7881)
  > 66f6471 *: regenrate pbs (# 8034)
  > 35cec50 grpc: Fix encoded message size reported in error message (# 8033)
  > 2517a46 xdsclient: introduce pool to manage multiple xDS clients with same bootstrap content (# 7898)
  > 897818a interop: improve rpc_soak and channel_soak test to cover concurrency in Go (# 8025)
  > 8cf8fd1 grpc: fix message length checks when compression is enabled and maxReceiveMessageSize is MaxInt (# 7918)
  > 67bee55 server: fix buffer release timing in processUnaryRPC (# 7998)
  > fe04c06 xds: remove unused code in testutils (# 8003)
  > be12ee9 deps: Update go.opentelemetry.io dependencies (# 8020)
  > eb7c484 Revert "interop: improve rpc_soak and channel_soak test to cover concurrency in Go (# 7926)" (# 8019)
  > c26dd46 deps: bump github.com/golang/glog (# 8018)
  > c879198 cleanup: fix comments spacing (# 8015)
  > 89093a3 github: Run deps workflow against PR target branch and improve dir names (# 8010)
  > 9dc22c0 xdsclient: release lock before attempting to close underlying transport (# 8011)
  > eb1adde credentials: Add experimental credentials that don't enforce ALPN (# 7980)
  > 130c1d7 leastrequest: Delegate subchannel creation to pickfirst (# 7969)
  > 74ac821 endpointsharding: Export parsed pickfirst config instead of json string (# 8007)
  > f35fb34 authz: modify the tests to use stubserver instead of testservice implementations (# 7888)
  > aad8a12 clustetresolver: Copy endpoints.Addresses slice from DNS updates to avoid data races (# 7991)
  > f9bc335 deps: update dependencies for all modules (# 7987)
  > 2d4daf3 protoc-gen-go-grpc: Update grpc-go and unskip test (# 7995)
  > 62b4867 clusterresolver: Avoid blocking for subsequent resolver updates in test (# 7937)
  > 9223fd6 deps: bump github.com/envoyproxy/go-control-plane to v0.13.4 (# 7974)
  > d118866 interop: improve rpc_soak and channel_soak test to cover concurrency in Go (# 7926)
  > 6f41085 Change version to 1.71.0-dev (# 7986)

Signed-off-by: Knative Automation <automation@knative.team>
This commit is contained in:
Knative Automation 2025-03-13 12:49:38 -04:00 committed by GitHub
parent ad23fbda1a
commit 776406ea7b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
58 changed files with 2010 additions and 700 deletions

23
go.mod
View File

@ -3,15 +3,15 @@ module knative.dev/caching
go 1.23.0
require (
github.com/google/go-cmp v0.6.0
github.com/google/go-cmp v0.7.0
go.uber.org/zap v1.27.0
k8s.io/api v0.32.2
k8s.io/apimachinery v0.32.2
k8s.io/client-go v0.32.2
k8s.io/code-generator v0.32.2
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7
knative.dev/hack v0.0.0-20250217122557-ce4c934f30e5
knative.dev/pkg v0.0.0-20250214140553-ae2c6bcc1f59
knative.dev/hack v0.0.0-20250219013704-306ce745e077
knative.dev/pkg v0.0.0-20250312035536-b7bbf4be5dbd
)
require (
@ -56,22 +56,21 @@ require (
github.com/spf13/pflag v1.0.6 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.23.0 // indirect
golang.org/x/net v0.35.0 // indirect
golang.org/x/mod v0.24.0 // indirect
golang.org/x/net v0.37.0 // indirect
golang.org/x/oauth2 v0.26.0 // indirect
golang.org/x/sync v0.11.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/term v0.29.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/term v0.30.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/time v0.10.0 // indirect
golang.org/x/tools v0.30.0 // indirect
golang.org/x/tools v0.31.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/api v0.183.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250207221924-e9438ea467c6 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect
google.golang.org/grpc v1.70.0 // indirect
google.golang.org/grpc v1.71.0 // indirect
google.golang.org/protobuf v1.36.5 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect

56
go.sum
View File

@ -156,8 +156,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
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/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -315,14 +315,14 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
@ -368,8 +368,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -404,8 +404,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -426,8 +426,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -469,12 +469,12 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/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-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
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/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -482,8 +482,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -531,8 +531,8 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -612,8 +612,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -675,10 +675,10 @@ k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8X
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas=
k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
knative.dev/hack v0.0.0-20250217122557-ce4c934f30e5 h1:BIkxsbG01S563JJ68n4SIeIpizDlAcf1vgss6b1QAhE=
knative.dev/hack v0.0.0-20250217122557-ce4c934f30e5/go.mod h1:R0ritgYtjLDO9527h5vb5X6gfvt5LCrJ55BNbVDsWiY=
knative.dev/pkg v0.0.0-20250214140553-ae2c6bcc1f59 h1:gUycV6nl+ZFIVTeAkQESbdeVmbdDQtELo4eQQ/FwyDY=
knative.dev/pkg v0.0.0-20250214140553-ae2c6bcc1f59/go.mod h1:MvZDDprJBCEwaeZhdPVTZJtODEHF0ZSj2M3jt1FQ4+Y=
knative.dev/hack v0.0.0-20250219013704-306ce745e077 h1:kcYrHAI+x7KHChjFfJ37Sq5QNAIwQExRor+g6Rbg1K0=
knative.dev/hack v0.0.0-20250219013704-306ce745e077/go.mod h1:R0ritgYtjLDO9527h5vb5X6gfvt5LCrJ55BNbVDsWiY=
knative.dev/pkg v0.0.0-20250312035536-b7bbf4be5dbd h1:KXG6bACwjKSZcT0JxyQDVYLcDPSip+7l6sVULeITi7k=
knative.dev/pkg v0.0.0-20250312035536-b7bbf4be5dbd/go.mod h1:OuszA8pcsXmO+Pp4QCtD10ph6tjRPFN+LrF/XgAMDb8=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View File

@ -19,6 +19,7 @@ const (
tbFunc // func(T) bool
ttbFunc // func(T, T) bool
ttiFunc // func(T, T) int
trbFunc // func(T, R) bool
tibFunc // func(T, I) bool
trFunc // func(T) R
@ -28,11 +29,13 @@ const (
Transformer = trFunc // func(T) R
ValueFilter = ttbFunc // func(T, T) bool
Less = ttbFunc // func(T, T) bool
Compare = ttiFunc // func(T, T) int
ValuePredicate = tbFunc // func(T) bool
KeyValuePredicate = trbFunc // func(T, R) bool
)
var boolType = reflect.TypeOf(true)
var intType = reflect.TypeOf(0)
// IsType reports whether the reflect.Type is of the specified function type.
func IsType(t reflect.Type, ft funcType) bool {
@ -49,6 +52,10 @@ func IsType(t reflect.Type, ft funcType) bool {
if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType {
return true
}
case ttiFunc: // func(T, T) int
if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == intType {
return true
}
case trbFunc: // func(T, R) bool
if ni == 2 && no == 1 && t.Out(0) == boolType {
return true

View File

@ -232,7 +232,15 @@ func (validator) apply(s *state, vx, vy reflect.Value) {
if t := s.curPath.Index(-2).Type(); t.Name() != "" {
// Named type with unexported fields.
name = fmt.Sprintf("%q.%v", t.PkgPath(), t.Name()) // e.g., "path/to/package".MyType
if _, ok := reflect.New(t).Interface().(error); ok {
isProtoMessage := func(t reflect.Type) bool {
m, ok := reflect.PointerTo(t).MethodByName("ProtoReflect")
return ok && m.Type.NumIn() == 1 && m.Type.NumOut() == 1 &&
m.Type.Out(0).PkgPath() == "google.golang.org/protobuf/reflect/protoreflect" &&
m.Type.Out(0).Name() == "Message"
}
if isProtoMessage(t) {
help = `consider using "google.golang.org/protobuf/testing/protocmp".Transform to compare proto.Message types`
} else if _, ok := reflect.New(t).Interface().(error); ok {
help = "consider using cmpopts.EquateErrors to compare error values"
} else if t.Comparable() {
help = "consider using cmpopts.EquateComparable to compare comparable Go types"

View File

@ -2233,25 +2233,25 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream
func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) {
sc.serveG.check()
rp := requestParam{
method: f.PseudoValue("method"),
scheme: f.PseudoValue("scheme"),
authority: f.PseudoValue("authority"),
path: f.PseudoValue("path"),
protocol: f.PseudoValue("protocol"),
rp := httpcommon.ServerRequestParam{
Method: f.PseudoValue("method"),
Scheme: f.PseudoValue("scheme"),
Authority: f.PseudoValue("authority"),
Path: f.PseudoValue("path"),
Protocol: f.PseudoValue("protocol"),
}
// extended connect is disabled, so we should not see :protocol
if disableExtendedConnectProtocol && rp.protocol != "" {
if disableExtendedConnectProtocol && rp.Protocol != "" {
return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol))
}
isConnect := rp.method == "CONNECT"
isConnect := rp.Method == "CONNECT"
if isConnect {
if rp.protocol == "" && (rp.path != "" || rp.scheme != "" || rp.authority == "") {
if rp.Protocol == "" && (rp.Path != "" || rp.Scheme != "" || rp.Authority == "") {
return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol))
}
} else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
} else if rp.Method == "" || rp.Path == "" || (rp.Scheme != "https" && rp.Scheme != "http") {
// See 8.1.2.6 Malformed Requests and Responses:
//
// Malformed requests or responses that are detected
@ -2265,15 +2265,16 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
return nil, nil, sc.countError("bad_path_method", streamError(f.StreamID, ErrCodeProtocol))
}
rp.header = make(http.Header)
header := make(http.Header)
rp.Header = header
for _, hf := range f.RegularFields() {
rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
header.Add(sc.canonicalHeader(hf.Name), hf.Value)
}
if rp.authority == "" {
rp.authority = rp.header.Get("Host")
if rp.Authority == "" {
rp.Authority = header.Get("Host")
}
if rp.protocol != "" {
rp.header.Set(":protocol", rp.protocol)
if rp.Protocol != "" {
header.Set(":protocol", rp.Protocol)
}
rw, req, err := sc.newWriterAndRequestNoBody(st, rp)
@ -2282,7 +2283,7 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
}
bodyOpen := !f.StreamEnded()
if bodyOpen {
if vv, ok := rp.header["Content-Length"]; ok {
if vv, ok := rp.Header["Content-Length"]; ok {
if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {
req.ContentLength = int64(cl)
} else {
@ -2298,84 +2299,38 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
return rw, req, nil
}
type requestParam struct {
method string
scheme, authority, path string
protocol string
header http.Header
}
func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*responseWriter, *http.Request, error) {
func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp httpcommon.ServerRequestParam) (*responseWriter, *http.Request, error) {
sc.serveG.check()
var tlsState *tls.ConnectionState // nil if not scheme https
if rp.scheme == "https" {
if rp.Scheme == "https" {
tlsState = sc.tlsState
}
needsContinue := httpguts.HeaderValuesContainsToken(rp.header["Expect"], "100-continue")
if needsContinue {
rp.header.Del("Expect")
}
// Merge Cookie headers into one "; "-delimited value.
if cookies := rp.header["Cookie"]; len(cookies) > 1 {
rp.header.Set("Cookie", strings.Join(cookies, "; "))
}
// Setup Trailers
var trailer http.Header
for _, v := range rp.header["Trailer"] {
for _, key := range strings.Split(v, ",") {
key = http.CanonicalHeaderKey(textproto.TrimString(key))
switch key {
case "Transfer-Encoding", "Trailer", "Content-Length":
// Bogus. (copy of http1 rules)
// Ignore.
default:
if trailer == nil {
trailer = make(http.Header)
}
trailer[key] = nil
}
}
}
delete(rp.header, "Trailer")
var url_ *url.URL
var requestURI string
if rp.method == "CONNECT" && rp.protocol == "" {
url_ = &url.URL{Host: rp.authority}
requestURI = rp.authority // mimic HTTP/1 server behavior
} else {
var err error
url_, err = url.ParseRequestURI(rp.path)
if err != nil {
return nil, nil, sc.countError("bad_path", streamError(st.id, ErrCodeProtocol))
}
requestURI = rp.path
res := httpcommon.NewServerRequest(rp)
if res.InvalidReason != "" {
return nil, nil, sc.countError(res.InvalidReason, streamError(st.id, ErrCodeProtocol))
}
body := &requestBody{
conn: sc,
stream: st,
needsContinue: needsContinue,
needsContinue: res.NeedsContinue,
}
req := &http.Request{
Method: rp.method,
URL: url_,
req := (&http.Request{
Method: rp.Method,
URL: res.URL,
RemoteAddr: sc.remoteAddrStr,
Header: rp.header,
RequestURI: requestURI,
Header: rp.Header,
RequestURI: res.RequestURI,
Proto: "HTTP/2.0",
ProtoMajor: 2,
ProtoMinor: 0,
TLS: tlsState,
Host: rp.authority,
Host: rp.Authority,
Body: body,
Trailer: trailer,
}
req = req.WithContext(st.ctx)
Trailer: res.Trailer,
}).WithContext(st.ctx)
rw := sc.newResponseWriter(st, req)
return rw, req, nil
}
@ -3270,12 +3225,12 @@ func (sc *serverConn) startPush(msg *startPushRequest) {
// we start in "half closed (remote)" for simplicity.
// See further comments at the definition of stateHalfClosedRemote.
promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote)
rw, req, err := sc.newWriterAndRequestNoBody(promised, requestParam{
method: msg.method,
scheme: msg.url.Scheme,
authority: msg.url.Host,
path: msg.url.RequestURI(),
header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
rw, req, err := sc.newWriterAndRequestNoBody(promised, httpcommon.ServerRequestParam{
Method: msg.method,
Scheme: msg.url.Scheme,
Authority: msg.url.Host,
Path: msg.url.RequestURI(),
Header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
})
if err != nil {
// Should not happen, since we've already validated msg.url.

View File

@ -1286,6 +1286,19 @@ func (cc *ClientConn) responseHeaderTimeout() time.Duration {
return 0
}
// actualContentLength returns a sanitized version of
// req.ContentLength, where 0 actually means zero (not unknown) and -1
// means unknown.
func actualContentLength(req *http.Request) int64 {
if req.Body == nil || req.Body == http.NoBody {
return 0
}
if req.ContentLength != 0 {
return req.ContentLength
}
return -1
}
func (cc *ClientConn) decrStreamReservations() {
cc.mu.Lock()
defer cc.mu.Unlock()
@ -1310,7 +1323,7 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream))
reqCancel: req.Cancel,
isHead: req.Method == "HEAD",
reqBody: req.Body,
reqBodyContentLength: httpcommon.ActualContentLength(req),
reqBodyContentLength: actualContentLength(req),
trace: httptrace.ContextClientTrace(ctx),
peerClosed: make(chan struct{}),
abort: make(chan struct{}),
@ -1318,7 +1331,7 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream))
donec: make(chan struct{}),
}
cs.requestedGzip = httpcommon.IsRequestGzip(req, cc.t.disableCompression())
cs.requestedGzip = httpcommon.IsRequestGzip(req.Method, req.Header, cc.t.disableCompression())
go cs.doRequest(req, streamf)
@ -1349,7 +1362,7 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream))
}
res.Request = req
res.TLS = cc.tlsState
if res.Body == noBody && httpcommon.ActualContentLength(req) == 0 {
if res.Body == noBody && actualContentLength(req) == 0 {
// If there isn't a request or response body still being
// written, then wait for the stream to be closed before
// RoundTrip returns.
@ -1596,12 +1609,7 @@ func (cs *clientStream) encodeAndWriteHeaders(req *http.Request) error {
// sent by writeRequestBody below, along with any Trailers,
// again in form HEADERS{1}, CONTINUATION{0,})
cc.hbuf.Reset()
res, err := httpcommon.EncodeHeaders(httpcommon.EncodeHeadersParam{
Request: req,
AddGzipHeader: cs.requestedGzip,
PeerMaxHeaderListSize: cc.peerMaxHeaderListSize,
DefaultUserAgent: defaultUserAgent,
}, func(name, value string) {
res, err := encodeRequestHeaders(req, cs.requestedGzip, cc.peerMaxHeaderListSize, func(name, value string) {
cc.writeHeader(name, value)
})
if err != nil {
@ -1617,6 +1625,22 @@ func (cs *clientStream) encodeAndWriteHeaders(req *http.Request) error {
return err
}
func encodeRequestHeaders(req *http.Request, addGzipHeader bool, peerMaxHeaderListSize uint64, headerf func(name, value string)) (httpcommon.EncodeHeadersResult, error) {
return httpcommon.EncodeHeaders(req.Context(), httpcommon.EncodeHeadersParam{
Request: httpcommon.Request{
Header: req.Header,
Trailer: req.Trailer,
URL: req.URL,
Host: req.Host,
Method: req.Method,
ActualContentLength: actualContentLength(req),
},
AddGzipHeader: addGzipHeader,
PeerMaxHeaderListSize: peerMaxHeaderListSize,
DefaultUserAgent: defaultUserAgent,
}, headerf)
}
// cleanupWriteRequest performs post-request tasks.
//
// If err (the result of writeRequest) is non-nil and the stream is not closed,
@ -2186,6 +2210,13 @@ func (rl *clientConnReadLoop) cleanup() {
}
cc.cond.Broadcast()
cc.mu.Unlock()
if !cc.seenSettings {
// If we have a pending request that wants extended CONNECT,
// let it continue and fail with the connection error.
cc.extendedConnectAllowed = true
close(cc.seenSettingsChan)
}
}
// countReadFrameError calls Transport.CountError with a string
@ -2278,9 +2309,6 @@ func (rl *clientConnReadLoop) run() error {
if VerboseLogs {
cc.vlogf("http2: Transport conn %p received error from processing frame %v: %v", cc, summarizeFrame(f), err)
}
if !cc.seenSettings {
close(cc.seenSettingsChan)
}
return err
}
}

View File

@ -5,7 +5,7 @@
package httpcommon
import (
"net/http"
"net/textproto"
"sync"
)
@ -82,7 +82,7 @@ func buildCommonHeaderMaps() {
commonLowerHeader = make(map[string]string, len(common))
commonCanonHeader = make(map[string]string, len(common))
for _, v := range common {
chk := http.CanonicalHeaderKey(v)
chk := textproto.CanonicalMIMEHeaderKey(v)
commonLowerHeader[chk] = v
commonCanonHeader[v] = chk
}
@ -104,7 +104,7 @@ func CanonicalHeader(v string) string {
if s, ok := commonCanonHeader[v]; ok {
return s
}
return http.CanonicalHeaderKey(v)
return textproto.CanonicalMIMEHeaderKey(v)
}
// CachedCanonicalHeader returns the canonical form of a well-known header name.

View File

@ -5,10 +5,12 @@
package httpcommon
import (
"context"
"errors"
"fmt"
"net/http"
"net/http/httptrace"
"net/textproto"
"net/url"
"sort"
"strconv"
"strings"
@ -21,9 +23,21 @@ var (
ErrRequestHeaderListSize = errors.New("request header list larger than peer's advertised limit")
)
// Request is a subset of http.Request.
// It'd be simpler to pass an *http.Request, of course, but we can't depend on net/http
// without creating a dependency cycle.
type Request struct {
URL *url.URL
Method string
Host string
Header map[string][]string
Trailer map[string][]string
ActualContentLength int64 // 0 means 0, -1 means unknown
}
// EncodeHeadersParam is parameters to EncodeHeaders.
type EncodeHeadersParam struct {
Request *http.Request
Request Request
// AddGzipHeader indicates that an "accept-encoding: gzip" header should be
// added to the request.
@ -47,11 +61,11 @@ type EncodeHeadersResult struct {
// It validates a request and calls headerf with each pseudo-header and header
// for the request.
// The headerf function is called with the validated, canonicalized header name.
func EncodeHeaders(param EncodeHeadersParam, headerf func(name, value string)) (res EncodeHeadersResult, _ error) {
func EncodeHeaders(ctx context.Context, param EncodeHeadersParam, headerf func(name, value string)) (res EncodeHeadersResult, _ error) {
req := param.Request
// Check for invalid connection-level headers.
if err := checkConnHeaders(req); err != nil {
if err := checkConnHeaders(req.Header); err != nil {
return res, err
}
@ -73,7 +87,10 @@ func EncodeHeaders(param EncodeHeadersParam, headerf func(name, value string)) (
// isNormalConnect is true if this is a non-extended CONNECT request.
isNormalConnect := false
protocol := req.Header.Get(":protocol")
var protocol string
if vv := req.Header[":protocol"]; len(vv) > 0 {
protocol = vv[0]
}
if req.Method == "CONNECT" && protocol == "" {
isNormalConnect = true
} else if protocol != "" && req.Method != "CONNECT" {
@ -107,9 +124,7 @@ func EncodeHeaders(param EncodeHeadersParam, headerf func(name, value string)) (
return res, fmt.Errorf("invalid HTTP trailer %s", err)
}
contentLength := ActualContentLength(req)
trailers, err := commaSeparatedTrailers(req)
trailers, err := commaSeparatedTrailers(req.Trailer)
if err != nil {
return res, err
}
@ -123,7 +138,7 @@ func EncodeHeaders(param EncodeHeadersParam, headerf func(name, value string)) (
f(":authority", host)
m := req.Method
if m == "" {
m = http.MethodGet
m = "GET"
}
f(":method", m)
if !isNormalConnect {
@ -198,8 +213,8 @@ func EncodeHeaders(param EncodeHeadersParam, headerf func(name, value string)) (
f(k, v)
}
}
if shouldSendReqContentLength(req.Method, contentLength) {
f("content-length", strconv.FormatInt(contentLength, 10))
if shouldSendReqContentLength(req.Method, req.ActualContentLength) {
f("content-length", strconv.FormatInt(req.ActualContentLength, 10))
}
if param.AddGzipHeader {
f("accept-encoding", "gzip")
@ -225,7 +240,7 @@ func EncodeHeaders(param EncodeHeadersParam, headerf func(name, value string)) (
}
}
trace := httptrace.ContextClientTrace(req.Context())
trace := httptrace.ContextClientTrace(ctx)
// Header list size is ok. Write the headers.
enumerateHeaders(func(name, value string) {
@ -243,19 +258,19 @@ func EncodeHeaders(param EncodeHeadersParam, headerf func(name, value string)) (
}
})
res.HasBody = contentLength != 0
res.HasBody = req.ActualContentLength != 0
res.HasTrailers = trailers != ""
return res, nil
}
// IsRequestGzip reports whether we should add an Accept-Encoding: gzip header
// for a request.
func IsRequestGzip(req *http.Request, disableCompression bool) bool {
func IsRequestGzip(method string, header map[string][]string, disableCompression bool) bool {
// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
if !disableCompression &&
req.Header.Get("Accept-Encoding") == "" &&
req.Header.Get("Range") == "" &&
req.Method != "HEAD" {
len(header["Accept-Encoding"]) == 0 &&
len(header["Range"]) == 0 &&
method != "HEAD" {
// Request gzip only, not deflate. Deflate is ambiguous and
// not as universally supported anyway.
// See: https://zlib.net/zlib_faq.html#faq39
@ -280,22 +295,22 @@ func IsRequestGzip(req *http.Request, disableCompression bool) bool {
//
// Certain headers are special-cased as okay but not transmitted later.
// For example, we allow "Transfer-Encoding: chunked", but drop the header when encoding.
func checkConnHeaders(req *http.Request) error {
if v := req.Header.Get("Upgrade"); v != "" {
return fmt.Errorf("invalid Upgrade request header: %q", req.Header["Upgrade"])
func checkConnHeaders(h map[string][]string) error {
if vv := h["Upgrade"]; len(vv) > 0 && (vv[0] != "" && vv[0] != "chunked") {
return fmt.Errorf("invalid Upgrade request header: %q", vv)
}
if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") {
if vv := h["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") {
return fmt.Errorf("invalid Transfer-Encoding request header: %q", vv)
}
if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !asciiEqualFold(vv[0], "close") && !asciiEqualFold(vv[0], "keep-alive")) {
if vv := h["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !asciiEqualFold(vv[0], "close") && !asciiEqualFold(vv[0], "keep-alive")) {
return fmt.Errorf("invalid Connection request header: %q", vv)
}
return nil
}
func commaSeparatedTrailers(req *http.Request) (string, error) {
keys := make([]string, 0, len(req.Trailer))
for k := range req.Trailer {
func commaSeparatedTrailers(trailer map[string][]string) (string, error) {
keys := make([]string, 0, len(trailer))
for k := range trailer {
k = CanonicalHeader(k)
switch k {
case "Transfer-Encoding", "Trailer", "Content-Length":
@ -310,19 +325,6 @@ func commaSeparatedTrailers(req *http.Request) (string, error) {
return "", nil
}
// ActualContentLength returns a sanitized version of
// req.ContentLength, where 0 actually means zero (not unknown) and -1
// means unknown.
func ActualContentLength(req *http.Request) int64 {
if req.Body == nil || req.Body == http.NoBody {
return 0
}
if req.ContentLength != 0 {
return req.ContentLength
}
return -1
}
// validPseudoPath reports whether v is a valid :path pseudo-header
// value. It must be either:
//
@ -340,7 +342,7 @@ func validPseudoPath(v string) bool {
return (len(v) > 0 && v[0] == '/') || v == "*"
}
func validateHeaders(hdrs http.Header) string {
func validateHeaders(hdrs map[string][]string) string {
for k, vv := range hdrs {
if !httpguts.ValidHeaderFieldName(k) && k != ":protocol" {
return fmt.Sprintf("name %q", k)
@ -377,3 +379,89 @@ func shouldSendReqContentLength(method string, contentLength int64) bool {
return false
}
}
// ServerRequestParam is parameters to NewServerRequest.
type ServerRequestParam struct {
Method string
Scheme, Authority, Path string
Protocol string
Header map[string][]string
}
// ServerRequestResult is the result of NewServerRequest.
type ServerRequestResult struct {
// Various http.Request fields.
URL *url.URL
RequestURI string
Trailer map[string][]string
NeedsContinue bool // client provided an "Expect: 100-continue" header
// If the request should be rejected, this is a short string suitable for passing
// to the http2 package's CountError function.
// It might be a bit odd to return errors this way rather than returing an error,
// but this ensures we don't forget to include a CountError reason.
InvalidReason string
}
func NewServerRequest(rp ServerRequestParam) ServerRequestResult {
needsContinue := httpguts.HeaderValuesContainsToken(rp.Header["Expect"], "100-continue")
if needsContinue {
delete(rp.Header, "Expect")
}
// Merge Cookie headers into one "; "-delimited value.
if cookies := rp.Header["Cookie"]; len(cookies) > 1 {
rp.Header["Cookie"] = []string{strings.Join(cookies, "; ")}
}
// Setup Trailers
var trailer map[string][]string
for _, v := range rp.Header["Trailer"] {
for _, key := range strings.Split(v, ",") {
key = textproto.CanonicalMIMEHeaderKey(textproto.TrimString(key))
switch key {
case "Transfer-Encoding", "Trailer", "Content-Length":
// Bogus. (copy of http1 rules)
// Ignore.
default:
if trailer == nil {
trailer = make(map[string][]string)
}
trailer[key] = nil
}
}
}
delete(rp.Header, "Trailer")
// "':authority' MUST NOT include the deprecated userinfo subcomponent
// for "http" or "https" schemed URIs."
// https://www.rfc-editor.org/rfc/rfc9113.html#section-8.3.1-2.3.8
if strings.IndexByte(rp.Authority, '@') != -1 && (rp.Scheme == "http" || rp.Scheme == "https") {
return ServerRequestResult{
InvalidReason: "userinfo_in_authority",
}
}
var url_ *url.URL
var requestURI string
if rp.Method == "CONNECT" && rp.Protocol == "" {
url_ = &url.URL{Host: rp.Authority}
requestURI = rp.Authority // mimic HTTP/1 server behavior
} else {
var err error
url_, err = url.ParseRequestURI(rp.Path)
if err != nil {
return ServerRequestResult{
InvalidReason: "bad_path",
}
}
requestURI = rp.Path
}
return ServerRequestResult{
URL: url_,
NeedsContinue: needsContinue,
RequestURI: requestURI,
Trailer: trailer,
}
}

View File

@ -46,7 +46,7 @@ func (g *Group) done() {
// returns a non-nil error or the first time Wait returns, whichever occurs
// first.
func WithContext(ctx context.Context) (*Group, context.Context) {
ctx, cancel := withCancelCause(ctx)
ctx, cancel := context.WithCancelCause(ctx)
return &Group{cancel: cancel}, ctx
}

View File

@ -1,13 +0,0 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.20
package errgroup
import "context"
func withCancelCause(parent context.Context) (context.Context, func(error)) {
return context.WithCancelCause(parent)
}

View File

@ -1,14 +0,0 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !go1.20
package errgroup
import "context"
func withCancelCause(parent context.Context) (context.Context, func(error)) {
ctx, cancel := context.WithCancel(parent)
return ctx, func(error) { cancel() }
}

View File

@ -59,7 +59,7 @@ func (c CanonType) Parse(s string) (t Tag, err error) {
if changed {
tt.RemakeString()
}
return makeTag(tt), err
return makeTag(tt), nil
}
// Compose creates a Tag from individual parts, which may be of type Tag, Base,

View File

@ -183,7 +183,7 @@ type application struct {
func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.Node) {
// convert typed nil into untyped nil
if v := reflect.ValueOf(n); v.Kind() == reflect.Ptr && v.IsNil() {
if v := reflect.ValueOf(n); v.Kind() == reflect.Pointer && v.IsNil() {
n = nil
}

View File

@ -8,4 +8,6 @@ import "go/ast"
// Unparen returns e with any enclosing parentheses stripped.
// Deprecated: use [ast.Unparen].
//
//go:fix inline
func Unparen(e ast.Expr) ast.Expr { return ast.Unparen(e) }

View File

@ -141,6 +141,8 @@ const (
LoadAllSyntax = LoadSyntax | NeedDeps
// Deprecated: NeedExportsFile is a historical misspelling of NeedExportFile.
//
//go:fix inline
NeedExportsFile = NeedExportFile
)
@ -161,7 +163,7 @@ type Config struct {
// If the user provides a logger, debug logging is enabled.
// If the GOPACKAGESDEBUG environment variable is set to true,
// but the logger is nil, default to log.Printf.
Logf func(format string, args ...interface{})
Logf func(format string, args ...any)
// Dir is the directory in which to run the build system's query tool
// that provides information about the packages.
@ -564,13 +566,13 @@ type ModuleError struct {
}
func init() {
packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError {
packagesinternal.GetDepsErrors = func(p any) []*packagesinternal.PackageError {
return p.(*Package).depsErrors
}
packagesinternal.SetModFile = func(config interface{}, value string) {
packagesinternal.SetModFile = func(config any, value string) {
config.(*Config).modFile = value
}
packagesinternal.SetModFlag = func(config interface{}, value string) {
packagesinternal.SetModFlag = func(config any, value string) {
config.(*Config).modFlag = value
}
packagesinternal.TypecheckCgo = int(typecheckCgo)
@ -739,7 +741,7 @@ func newLoader(cfg *Config) *loader {
if debug {
ld.Config.Logf = log.Printf
} else {
ld.Config.Logf = func(format string, args ...interface{}) {}
ld.Config.Logf = func(format string, args ...any) {}
}
}
if ld.Config.Mode == 0 {

View File

@ -389,8 +389,13 @@ func (hasher) hashTypeName(tname *types.TypeName) uint32 {
// path, and whether or not it is a package-level typename. It
// is rare for a package to define multiple local types with
// the same name.)
hash := uintptr(unsafe.Pointer(tname))
return uint32(hash ^ (hash >> 32))
ptr := uintptr(unsafe.Pointer(tname))
if unsafe.Sizeof(ptr) == 8 {
hash := uint64(ptr)
return uint32(hash ^ (hash >> 32))
} else {
return uint32(ptr)
}
}
// shallowHash computes a hash of t without looking at any of its

View File

@ -32,7 +32,7 @@ func (k *Value) Format(w io.Writer, buf []byte, l label.Label) {
}
// Get can be used to get a label for the key from a label.Map.
func (k *Value) Get(lm label.Map) interface{} {
func (k *Value) Get(lm label.Map) any {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
@ -40,10 +40,10 @@ func (k *Value) Get(lm label.Map) interface{} {
}
// From can be used to get a value from a Label.
func (k *Value) From(t label.Label) interface{} { return t.UnpackValue() }
func (k *Value) From(t label.Label) any { return t.UnpackValue() }
// Of creates a new Label with this key and the supplied value.
func (k *Value) Of(value interface{}) label.Label { return label.OfValue(k, value) }
func (k *Value) Of(value any) label.Label { return label.OfValue(k, value) }
// Tag represents a key for tagging labels that have no value.
// These are used when the existence of the label is the entire information it

View File

@ -32,7 +32,7 @@ type Key interface {
type Label struct {
key Key
packed uint64
untyped interface{}
untyped any
}
// Map is the interface to a collection of Labels indexed by key.
@ -76,13 +76,13 @@ type mapChain struct {
// OfValue creates a new label from the key and value.
// This method is for implementing new key types, label creation should
// normally be done with the Of method of the key.
func OfValue(k Key, value interface{}) Label { return Label{key: k, untyped: value} }
func OfValue(k Key, value any) Label { return Label{key: k, untyped: value} }
// UnpackValue assumes the label was built using LabelOfValue and returns the value
// that was passed to that constructor.
// This method is for implementing new key types, for type safety normal
// access should be done with the From method of the key.
func (t Label) UnpackValue() interface{} { return t.untyped }
func (t Label) UnpackValue() any { return t.untyped }
// Of64 creates a new label from a key and a uint64. This is often
// used for non uint64 values that can be packed into a uint64.

View File

@ -14,7 +14,7 @@ import (
"sync"
)
func errorf(format string, args ...interface{}) {
func errorf(format string, args ...any) {
panic(fmt.Sprintf(format, args...))
}

View File

@ -310,7 +310,7 @@ func IImportShallow(fset *token.FileSet, getPackages GetPackagesFunc, data []byt
}
// ReportFunc is the type of a function used to report formatted bugs.
type ReportFunc = func(string, ...interface{})
type ReportFunc = func(string, ...any)
// Current bundled export format version. Increase with each format change.
// 0: initial implementation
@ -597,7 +597,7 @@ type filePositions struct {
needed []uint64 // unordered list of needed file offsets
}
func (p *iexporter) trace(format string, args ...interface{}) {
func (p *iexporter) trace(format string, args ...any) {
if !trace {
// Call sites should also be guarded, but having this check here allows
// easily enabling/disabling debug trace statements.
@ -1583,6 +1583,6 @@ func (e internalError) Error() string { return "gcimporter: " + string(e) }
// "internalErrorf" as the former is used for bugs, whose cause is
// internal inconsistency, whereas the latter is used for ordinary
// situations like bad input, whose cause is external.
func internalErrorf(format string, args ...interface{}) error {
func internalErrorf(format string, args ...any) error {
return internalError(fmt.Sprintf(format, args...))
}

View File

@ -400,7 +400,7 @@ type iimporter struct {
indent int // for tracing support
}
func (p *iimporter) trace(format string, args ...interface{}) {
func (p *iimporter) trace(format string, args ...any) {
if !trace {
// Call sites should also be guarded, but having this check here allows
// easily enabling/disabling debug trace statements.

View File

@ -574,7 +574,7 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named)
typesinternal.SetVarKind(recv, typesinternal.RecvVar)
methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic()))
methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignatureType(recv, nil, nil, sig.Params(), sig.Results(), sig.Variadic()))
}
embeds := make([]types.Type, iface.NumEmbeddeds())

View File

@ -22,7 +22,7 @@ import (
// Options controls the behavior of a Walk call.
type Options struct {
// If Logf is non-nil, debug logging is enabled through this function.
Logf func(format string, args ...interface{})
Logf func(format string, args ...any)
// Search module caches. Also disables legacy goimports ignore rules.
ModulesEnabled bool
@ -81,7 +81,7 @@ func WalkSkip(roots []Root, add func(root Root, dir string), skip func(root Root
// walkDir creates a walker and starts fastwalk with this walker.
func walkDir(root Root, add func(Root, string), skip func(root Root, dir string) bool, opts Options) {
if opts.Logf == nil {
opts.Logf = func(format string, args ...interface{}) {}
opts.Logf = func(format string, args ...any) {}
}
if _, err := os.Stat(root.Path); os.IsNotExist(err) {
opts.Logf("skipping nonexistent directory: %v", root.Path)

View File

@ -559,7 +559,7 @@ func fixImportsDefault(fset *token.FileSet, f *ast.File, filename string, env *P
return err
}
apply(fset, f, fixes)
return err
return nil
}
// getFixes gets the import fixes that need to be made to f in order to fix the imports.
@ -1030,7 +1030,7 @@ func (e *ProcessEnv) GetResolver() (Resolver, error) {
//
// For gopls, we can optionally explicitly choose a resolver type, since we
// already know the view type.
if len(e.Env["GOMOD"]) == 0 && len(e.Env["GOWORK"]) == 0 {
if e.Env["GOMOD"] == "" && (e.Env["GOWORK"] == "" || e.Env["GOWORK"] == "off") {
e.resolver = newGopathResolver(e)
e.logf("created gopath resolver")
} else if r, err := newModuleResolver(e, e.ModCache); err != nil {

View File

@ -17,4 +17,4 @@ var TypecheckCgo int
var DepsErrors int // must be set as a LoadMode to call GetDepsErrors
var SetModFlag = func(config any, value string) {}
var SetModFile = func(config interface{}, value string) {}
var SetModFile = func(config any, value string) {}

359
vendor/golang.org/x/tools/internal/stdlib/deps.go generated vendored Normal file
View File

@ -0,0 +1,359 @@
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Code generated by generate.go. DO NOT EDIT.
package stdlib
type pkginfo struct {
name string
deps string // list of indices of dependencies, as varint-encoded deltas
}
var deps = [...]pkginfo{
{"archive/tar", "\x03k\x03E5\x01\v\x01#\x01\x01\x02\x05\t\x02\x01\x02\x02\v"},
{"archive/zip", "\x02\x04a\a\x16\x0205\x01+\x05\x01\x10\x03\x02\r\x04"},
{"bufio", "\x03k}E\x13"},
{"bytes", "n+R\x03\fG\x02\x02"},
{"cmp", ""},
{"compress/bzip2", "\x02\x02\xe7\x01B"},
{"compress/flate", "\x02l\x03z\r\x024\x01\x03"},
{"compress/gzip", "\x02\x04a\a\x03\x15eT"},
{"compress/lzw", "\x02l\x03z"},
{"compress/zlib", "\x02\x04a\a\x03\x13\x01f"},
{"container/heap", "\xae\x02"},
{"container/list", ""},
{"container/ring", ""},
{"context", "n\\h\x01\f"},
{"crypto", "\x84\x01gD"},
{"crypto/aes", "\x10\n\a\x8e\x02"},
{"crypto/cipher", "\x03\x1e\x01\x01\x1d\x11\x1d,Q"},
{"crypto/des", "\x10\x13\x1d.,\x95\x01\x03"},
{"crypto/dsa", "@\x04*}\x0e"},
{"crypto/ecdh", "\x03\v\f\x0e\x04\x14\x04\r\x1d}"},
{"crypto/ecdsa", "\x0e\x05\x03\x04\x01\x0e\x16\x01\x04\f\x01\x1d}\x0e\x04K\x01"},
{"crypto/ed25519", "\x0e\x1c\x16\n\a\x1d}D"},
{"crypto/elliptic", "0>}\x0e9"},
{"crypto/fips140", " \x05\x91\x01"},
{"crypto/hkdf", "-\x12\x01.\x16"},
{"crypto/hmac", "\x1a\x14\x11\x01\x113"},
{"crypto/internal/boring", "\x0e\x02\rg"},
{"crypto/internal/boring/bbig", "\x1a\xdf\x01L"},
{"crypto/internal/boring/bcache", "\xb3\x02\x12"},
{"crypto/internal/boring/sig", ""},
{"crypto/internal/cryptotest", "\x03\r\n)\x0e\x1a\x06\x13\x12#\a\t\x11\x11\x11\x1b\x01\f\f\x05\n"},
{"crypto/internal/entropy", "E"},
{"crypto/internal/fips140", ">0}9\f\x15"},
{"crypto/internal/fips140/aes", "\x03\x1d\x03\x02\x13\x04\x01\x01\x05+\x8c\x015"},
{"crypto/internal/fips140/aes/gcm", " \x01\x02\x02\x02\x11\x04\x01\x06+\x8a\x01"},
{"crypto/internal/fips140/alias", "\xc5\x02"},
{"crypto/internal/fips140/bigmod", "%\x17\x01\x06+\x8c\x01"},
{"crypto/internal/fips140/check", " \x0e\x06\b\x02\xad\x01Z"},
{"crypto/internal/fips140/check/checktest", "%\xff\x01!"},
{"crypto/internal/fips140/drbg", "\x03\x1c\x01\x01\x04\x13\x04\b\x01)}\x0f8"},
{"crypto/internal/fips140/ecdh", "\x03\x1d\x05\x02\t\f2}\x0f8"},
{"crypto/internal/fips140/ecdsa", "\x03\x1d\x04\x01\x02\a\x02\x068}G"},
{"crypto/internal/fips140/ed25519", "\x03\x1d\x05\x02\x04\v8\xc1\x01\x03"},
{"crypto/internal/fips140/edwards25519", "%\a\f\x042\x8c\x018"},
{"crypto/internal/fips140/edwards25519/field", "%\x13\x042\x8c\x01"},
{"crypto/internal/fips140/hkdf", "\x03\x1d\x05\t\x06:"},
{"crypto/internal/fips140/hmac", "\x03\x1d\x14\x01\x018"},
{"crypto/internal/fips140/mlkem", "\x03\x1d\x05\x02\x0e\x03\x042"},
{"crypto/internal/fips140/nistec", "%\f\a\x042\x8c\x01*\x0e\x13"},
{"crypto/internal/fips140/nistec/fiat", "%\x136\x8c\x01"},
{"crypto/internal/fips140/pbkdf2", "\x03\x1d\x05\t\x06:"},
{"crypto/internal/fips140/rsa", "\x03\x1d\x04\x01\x02\r\x01\x01\x026}G"},
{"crypto/internal/fips140/sha256", "\x03\x1d\x1c\x01\x06+\x8c\x01"},
{"crypto/internal/fips140/sha3", "\x03\x1d\x18\x04\x011\x8c\x01K"},
{"crypto/internal/fips140/sha512", "\x03\x1d\x1c\x01\x06+\x8c\x01"},
{"crypto/internal/fips140/ssh", " \x05"},
{"crypto/internal/fips140/subtle", "#\x19\xbe\x01"},
{"crypto/internal/fips140/tls12", "\x03\x1d\x05\t\x06\x028"},
{"crypto/internal/fips140/tls13", "\x03\x1d\x05\b\a\b2"},
{"crypto/internal/fips140deps", ""},
{"crypto/internal/fips140deps/byteorder", "\x9a\x01"},
{"crypto/internal/fips140deps/cpu", "\xae\x01\a"},
{"crypto/internal/fips140deps/godebug", "\xb6\x01"},
{"crypto/internal/fips140hash", "5\x1a5\xc1\x01"},
{"crypto/internal/fips140only", "'\r\x01\x01N25"},
{"crypto/internal/fips140test", ""},
{"crypto/internal/hpke", "\x0e\x01\x01\x03\x1a\x1d$,`M"},
{"crypto/internal/impl", "\xb0\x02"},
{"crypto/internal/randutil", "\xeb\x01\x12"},
{"crypto/internal/sysrand", "\xd7\x01@\x1b\x01\f\x06"},
{"crypto/internal/sysrand/internal/seccomp", "n"},
{"crypto/md5", "\x0e2.\x16\x16`"},
{"crypto/mlkem", "/"},
{"crypto/pbkdf2", "2\r\x01.\x16"},
{"crypto/rand", "\x1a\x06\a\x19\x04\x01)}\x0eL"},
{"crypto/rc4", "#\x1d.\xc1\x01"},
{"crypto/rsa", "\x0e\f\x01\t\x0f\f\x01\x04\x06\a\x1d\x03\x1325\r\x01"},
{"crypto/sha1", "\x0e\f&.\x16\x16\x14L"},
{"crypto/sha256", "\x0e\f\x1aP"},
{"crypto/sha3", "\x0e'O\xc1\x01"},
{"crypto/sha512", "\x0e\f\x1cN"},
{"crypto/subtle", "8\x98\x01T"},
{"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x03\x01\a\x01\v\x02\n\x01\b\x05\x03\x01\x01\x01\x01\x02\x01\x02\x01\x18\x02\x03\x13\x16\x14\b5\x16\x16\r\t\x01\x01\x01\x02\x01\f\x06\x02\x01"},
{"crypto/tls/internal/fips140tls", " \x93\x02"},
{"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x011\x03\x02\x01\x01\x02\x05\x01\x0e\x06\x02\x02\x03E5\x03\t\x01\x01\x01\a\x10\x05\t\x05\v\x01\x02\r\x02\x01\x01\x02\x03\x01"},
{"crypto/x509/internal/macos", "\x03k'\x8f\x01\v\x10\x06"},
{"crypto/x509/pkix", "d\x06\a\x88\x01F"},
{"database/sql", "\x03\nK\x16\x03z\f\x06\"\x05\t\x02\x03\x01\f\x02\x02\x02"},
{"database/sql/driver", "\ra\x03\xae\x01\x10\x10"},
{"debug/buildinfo", "\x03X\x02\x01\x01\b\a\x03`\x18\x02\x01+\x10\x1e"},
{"debug/dwarf", "\x03d\a\x03z1\x12\x01\x01"},
{"debug/elf", "\x03\x06Q\r\a\x03`\x19\x01,\x18\x01\x15"},
{"debug/gosym", "\x03d\n\xbd\x01\x01\x01\x02"},
{"debug/macho", "\x03\x06Q\r\n`\x1a,\x18\x01"},
{"debug/pe", "\x03\x06Q\r\a\x03`\x1a,\x18\x01\x15"},
{"debug/plan9obj", "g\a\x03`\x1a,"},
{"embed", "n+:\x18\x01S"},
{"embed/internal/embedtest", ""},
{"encoding", ""},
{"encoding/ascii85", "\xeb\x01D"},
{"encoding/asn1", "\x03k\x03\x87\x01\x01&\x0e\x02\x01\x0f\x03\x01"},
{"encoding/base32", "\xeb\x01B\x02"},
{"encoding/base64", "\x9a\x01QB\x02"},
{"encoding/binary", "n}\r'\x0e\x05"},
{"encoding/csv", "\x02\x01k\x03zE\x11\x02"},
{"encoding/gob", "\x02`\x05\a\x03`\x1a\f\x01\x02\x1d\b\x13\x01\x0e\x02"},
{"encoding/hex", "n\x03zB\x03"},
{"encoding/json", "\x03\x01^\x04\b\x03z\r'\x0e\x02\x01\x02\x0f\x01\x01\x02"},
{"encoding/pem", "\x03c\b}B\x03"},
{"encoding/xml", "\x02\x01_\f\x03z4\x05\v\x01\x02\x0f\x02"},
{"errors", "\xca\x01{"},
{"expvar", "kK9\t\n\x15\r\t\x02\x03\x01\x10"},
{"flag", "b\f\x03z,\b\x05\t\x02\x01\x0f"},
{"fmt", "nE8\r\x1f\b\x0e\x02\x03\x11"},
{"go/ast", "\x03\x01m\x0f\x01j\x03)\b\x0e\x02\x01"},
{"go/ast/internal/tests", ""},
{"go/build", "\x02\x01k\x03\x01\x03\x02\a\x02\x01\x17\x1e\x04\x02\t\x14\x12\x01+\x01\x04\x01\a\t\x02\x01\x11\x02\x02"},
{"go/build/constraint", "n\xc1\x01\x01\x11\x02"},
{"go/constant", "q\x10w\x01\x015\x01\x02\x11"},
{"go/doc", "\x04m\x01\x06\t=-1\x11\x02\x01\x11\x02"},
{"go/doc/comment", "\x03n\xbc\x01\x01\x01\x01\x11\x02"},
{"go/format", "\x03n\x01\f\x01\x02jE"},
{"go/importer", "t\a\x01\x01\x04\x01i9"},
{"go/internal/gccgoimporter", "\x02\x01X\x13\x03\x05\v\x01g\x02,\x01\x05\x12\x01\v\b"},
{"go/internal/gcimporter", "\x02o\x10\x01/\x05\x0e',\x16\x03\x02"},
{"go/internal/srcimporter", "q\x01\x02\n\x03\x01i,\x01\x05\x13\x02\x13"},
{"go/parser", "\x03k\x03\x01\x03\v\x01j\x01+\x06\x13"},
{"go/printer", "q\x01\x03\x03\tj\r\x1f\x16\x02\x01\x02\n\x05\x02"},
{"go/scanner", "\x03n\x10j2\x11\x01\x12\x02"},
{"go/token", "\x04m\xbc\x01\x02\x03\x01\x0e\x02"},
{"go/types", "\x03\x01\x06d\x03\x01\x04\b\x03\x02\x15\x1e\x06+\x04\x03\n%\a\t\x01\x01\x01\x02\x01\x0e\x02\x02"},
{"go/version", "\xbb\x01u"},
{"hash", "\xeb\x01"},
{"hash/adler32", "n\x16\x16"},
{"hash/crc32", "n\x16\x16\x14\x84\x01\x01"},
{"hash/crc64", "n\x16\x16\x98\x01"},
{"hash/fnv", "n\x16\x16`"},
{"hash/maphash", "\x95\x01\x05\x1b\x03@M"},
{"html", "\xb0\x02\x02\x11"},
{"html/template", "\x03h\x06\x19,5\x01\v \x05\x01\x02\x03\r\x01\x02\v\x01\x03\x02"},
{"image", "\x02l\x1f^\x0f5\x03\x01"},
{"image/color", ""},
{"image/color/palette", "\x8d\x01"},
{"image/draw", "\x8c\x01\x01\x04"},
{"image/gif", "\x02\x01\x05f\x03\x1b\x01\x01\x01\vQ"},
{"image/internal/imageutil", "\x8c\x01"},
{"image/jpeg", "\x02l\x1e\x01\x04Z"},
{"image/png", "\x02\a^\n\x13\x02\x06\x01^D"},
{"index/suffixarray", "\x03d\a}\r*\v\x01"},
{"internal/abi", "\xb5\x01\x90\x01"},
{"internal/asan", "\xc5\x02"},
{"internal/bisect", "\xa4\x02\x0e\x01"},
{"internal/buildcfg", "qG_\x06\x02\x05\v\x01"},
{"internal/bytealg", "\xae\x01\x97\x01"},
{"internal/byteorder", ""},
{"internal/cfg", ""},
{"internal/chacha8rand", "\x9a\x01\x1b\x90\x01"},
{"internal/copyright", ""},
{"internal/coverage", ""},
{"internal/coverage/calloc", ""},
{"internal/coverage/cfile", "k\x06\x17\x16\x01\x02\x01\x01\x01\x01\x01\x01\x01$\x01\x1e,\x06\a\v\x01\x03\f\x06"},
{"internal/coverage/cformat", "\x04m-\x04I\f6\x01\x02\f"},
{"internal/coverage/cmerge", "q-Z"},
{"internal/coverage/decodecounter", "g\n-\v\x02@,\x18\x16"},
{"internal/coverage/decodemeta", "\x02e\n\x17\x16\v\x02@,"},
{"internal/coverage/encodecounter", "\x02e\n-\f\x01\x02>\f \x16"},
{"internal/coverage/encodemeta", "\x02\x01d\n\x13\x04\x16\r\x02>,."},
{"internal/coverage/pods", "\x04m-y\x06\x05\v\x02\x01"},
{"internal/coverage/rtcov", "\xc5\x02"},
{"internal/coverage/slicereader", "g\nzZ"},
{"internal/coverage/slicewriter", "qz"},
{"internal/coverage/stringtab", "q8\x04>"},
{"internal/coverage/test", ""},
{"internal/coverage/uleb128", ""},
{"internal/cpu", "\xc5\x02"},
{"internal/dag", "\x04m\xbc\x01\x03"},
{"internal/diff", "\x03n\xbd\x01\x02"},
{"internal/exportdata", "\x02\x01k\x03\x03]\x1a,\x01\x05\x12\x01\x02"},
{"internal/filepathlite", "n+:\x19A"},
{"internal/fmtsort", "\x04\x9b\x02\x0e"},
{"internal/fuzz", "\x03\nA\x19\x04\x03\x03\x01\f\x0355\r\x02\x1d\x01\x05\x02\x05\v\x01\x02\x01\x01\v\x04\x02"},
{"internal/goarch", ""},
{"internal/godebug", "\x97\x01 {\x01\x12"},
{"internal/godebugs", ""},
{"internal/goexperiment", ""},
{"internal/goos", ""},
{"internal/goroot", "\x97\x02\x01\x05\x13\x02"},
{"internal/gover", "\x04"},
{"internal/goversion", ""},
{"internal/itoa", ""},
{"internal/lazyregexp", "\x97\x02\v\x0e\x02"},
{"internal/lazytemplate", "\xeb\x01,\x19\x02\v"},
{"internal/msan", "\xc5\x02"},
{"internal/nettrace", ""},
{"internal/obscuretestdata", "f\x85\x01,"},
{"internal/oserror", "n"},
{"internal/pkgbits", "\x03K\x19\a\x03\x05\vj\x0e\x1e\r\v\x01"},
{"internal/platform", ""},
{"internal/poll", "nO\x1a\x149\x0e\x01\x01\v\x06"},
{"internal/profile", "\x03\x04g\x03z7\f\x01\x01\x0f"},
{"internal/profilerecord", ""},
{"internal/race", "\x95\x01\xb0\x01"},
{"internal/reflectlite", "\x95\x01 3<!"},
{"internal/routebsd", "n,w\x13\x10\x11"},
{"internal/runtime/atomic", "\xae\x01\x97\x01"},
{"internal/runtime/exithook", "\xcc\x01y"},
{"internal/runtime/maps", "\x95\x01\x01\x1f\v\t\x06\x01u"},
{"internal/runtime/math", "\xb5\x01"},
{"internal/runtime/sys", "\xae\x01\a\x04"},
{"internal/saferio", "\xeb\x01Z"},
{"internal/singleflight", "\xb2\x02"},
{"internal/stringslite", "\x99\x01\xac\x01"},
{"internal/sync", "\x95\x01 \x14j\x12"},
{"internal/synctest", "\xc5\x02"},
{"internal/syscall/execenv", "\xb4\x02"},
{"internal/syscall/unix", "\x95\x01\x8f\x01\x10\x11"},
{"internal/sysinfo", "\xae\x01\x84\x01\x02"},
{"internal/syslist", ""},
{"internal/testenv", "\x03\na\x02\x01*\x1a\x10'+\x01\x05\a\v\x01\x02\x02\x01\n"},
{"internal/testlog", "\xb2\x02\x01\x12"},
{"internal/testpty", "n\x03f@\x1d"},
{"internal/trace", "\x02\x01\x01\x06]\a\x03n\x03\x03\x06\x03\n5\x01\x02\x0f\x06"},
{"internal/trace/internal/testgen", "\x03d\nl\x03\x02\x03\x011\v\x0e"},
{"internal/trace/internal/tracev1", "\x03\x01c\a\x03t\x06\r5\x01"},
{"internal/trace/raw", "\x02e\nq\x03\x06D\x01\x11"},
{"internal/trace/testtrace", "\x02\x01k\x03l\x03\x06\x057\v\x02\x01"},
{"internal/trace/tracev2", ""},
{"internal/trace/traceviewer", "\x02^\v\x06\x1a<\x16\a\a\x04\t\n\x15\x01\x05\a\v\x01\x02\r"},
{"internal/trace/traceviewer/format", ""},
{"internal/trace/version", "qq\t"},
{"internal/txtar", "\x03n\xa6\x01\x19"},
{"internal/types/errors", "\xaf\x02"},
{"internal/unsafeheader", "\xc5\x02"},
{"internal/xcoff", "Z\r\a\x03`\x1a,\x18\x01"},
{"internal/zstd", "g\a\x03z\x0f"},
{"io", "n\xc4\x01"},
{"io/fs", "n+*(1\x11\x12\x04"},
{"io/ioutil", "\xeb\x01\x01+\x16\x03"},
{"iter", "\xc9\x01[!"},
{"log", "qz\x05'\r\x0e\x01\f"},
{"log/internal", ""},
{"log/slog", "\x03\nU\t\x03\x03z\x04\x01\x02\x02\x04'\x05\t\x02\x01\x02\x01\f\x02\x02\x02"},
{"log/slog/internal", ""},
{"log/slog/internal/benchmarks", "\ra\x03z\x06\x03;\x10"},
{"log/slog/internal/buffer", "\xb2\x02"},
{"log/slog/internal/slogtest", "\xf1\x01"},
{"log/syslog", "n\x03~\x12\x16\x19\x02\r"},
{"maps", "\xee\x01W"},
{"math", "\xfa\x01K"},
{"math/big", "\x03k\x03)Q\r\x02\x021\x02\x01\x02\x13"},
{"math/bits", "\xc5\x02"},
{"math/cmplx", "\xf8\x01\x02"},
{"math/rand", "\xb6\x01B:\x01\x12"},
{"math/rand/v2", "n,\x02\\\x02K"},
{"mime", "\x02\x01c\b\x03z\f \x16\x03\x02\x0f\x02"},
{"mime/multipart", "\x02\x01G$\x03E5\f\x01\x06\x02\x15\x02\x06\x10\x02\x01\x15"},
{"mime/quotedprintable", "\x02\x01nz"},
{"net", "\x04\ta+\x1d\a\x04\x05\x05\a\x01\x04\x14\x01%\x06\r\t\x05\x01\x01\v\x06\a"},
{"net/http", "\x02\x01\x04\x04\x02=\b\x14\x01\a\x03E5\x01\x03\b\x01\x02\x02\x02\x01\x02\x06\x02\x01\x01\n\x01\x01\x05\x01\x02\x05\t\x01\x01\x01\x02\x01\f\x02\x02\x02\b\x01\x01\x01"},
{"net/http/cgi", "\x02P\x1c\x03z\x04\b\n\x01\x13\x01\x01\x01\x04\x01\x05\x02\t\x02\x01\x0f\x0e"},
{"net/http/cookiejar", "\x04j\x03\x90\x01\x01\b\f\x17\x03\x02\r\x04"},
{"net/http/fcgi", "\x02\x01\nZ\a\x03z\x16\x01\x01\x14\x19\x02\r"},
{"net/http/httptest", "\x02\x01\nE\x02\x1c\x01z\x04\x12\x01\n\t\x02\x18\x01\x02\r\x0e"},
{"net/http/httptrace", "\rEo@\x14\n "},
{"net/http/httputil", "\x02\x01\na\x03z\x04\x0f\x03\x01\x05\x02\x01\v\x01\x1a\x02\r\x0e"},
{"net/http/internal", "\x02\x01k\x03z"},
{"net/http/internal/ascii", "\xb0\x02\x11"},
{"net/http/internal/httpcommon", "\ra\x03\x96\x01\x0e\x01\x18\x01\x01\x02\x1b\x02"},
{"net/http/internal/testcert", "\xb0\x02"},
{"net/http/pprof", "\x02\x01\nd\x19,\x11$\x04\x13\x14\x01\r\x06\x02\x01\x02\x01\x0f"},
{"net/internal/cgotest", "\xd7\x01n"},
{"net/internal/socktest", "q\xc1\x01\x02"},
{"net/mail", "\x02l\x03z\x04\x0f\x03\x14\x1b\x02\r\x04"},
{"net/netip", "\x04j+\x01#;\x025\x15"},
{"net/rpc", "\x02g\x05\x03\x10\n`\x04\x12\x01\x1d\x0e\x03\x02"},
{"net/rpc/jsonrpc", "k\x03\x03z\x16\x11 "},
{"net/smtp", "\x19.\v\x14\b\x03z\x16\x14\x1b"},
{"net/textproto", "\x02\x01k\x03z\r\t.\x01\x02\x13"},
{"net/url", "n\x03\x86\x01%\x11\x02\x01\x15"},
{"os", "n+\x19\v\t\r\x03\x01\x04\x10\x018\t\x05\x01\x01\v\x06"},
{"os/exec", "\x03\naH \x01\x14\x01+\x06\a\v\x01\x04\v"},
{"os/exec/internal/fdtest", "\xb4\x02"},
{"os/signal", "\r\x8a\x02\x16\x05\x02"},
{"os/user", "qfM\v\x01\x02\x02\x11"},
{"path", "n+\xaa\x01"},
{"path/filepath", "n+\x19:+\r\t\x03\x04\x0f"},
{"plugin", "n\xc4\x01\x13"},
{"reflect", "n'\x04\x1c\b\f\x05\x02\x18\x06\n,\v\x03\x0f\x02\x02"},
{"reflect/internal/example1", ""},
{"reflect/internal/example2", ""},
{"regexp", "\x03\xe8\x018\n\x02\x01\x02\x0f\x02"},
{"regexp/syntax", "\xad\x02\x01\x01\x01\x11\x02"},
{"runtime", "\x95\x01\x04\x01\x02\f\x06\a\x02\x01\x01\x0f\x04\x01\x01\x01\x01\x03\x0fc"},
{"runtime/cgo", "\xd0\x01b\x01\x12"},
{"runtime/coverage", "\xa0\x01K"},
{"runtime/debug", "qUQ\r\t\x02\x01\x0f\x06"},
{"runtime/internal/wasitest", ""},
{"runtime/metrics", "\xb7\x01A,!"},
{"runtime/pprof", "\x02\x01\x01\x03\x06Z\a\x03$3#\r\x1f\r\t\x01\x01\x01\x02\x02\b\x03\x06"},
{"runtime/race", ""},
{"runtime/trace", "\rdz9\x0e\x01\x12"},
{"slices", "\x04\xea\x01\fK"},
{"sort", "\xca\x0103"},
{"strconv", "n+:%\x02I"},
{"strings", "n'\x04:\x18\x03\f8\x0f\x02\x02"},
{"structs", ""},
{"sync", "\xc9\x01\vP\x0f\x12"},
{"sync/atomic", "\xc5\x02"},
{"syscall", "n'\x01\x03\x01\x1b\b\x03\x03\x06[\x0e\x01\x12"},
{"testing", "\x03\na\x02\x01X\x0f\x13\r\x04\x1b\x06\x02\x05\x03\x05\x01\x02\x01\x02\x01\f\x02\x02\x02"},
{"testing/fstest", "n\x03z\x01\v%\x11\x03\b\a"},
{"testing/internal/testdeps", "\x02\v\xa7\x01'\x10,\x03\x05\x03\b\x06\x02\r"},
{"testing/iotest", "\x03k\x03z\x04"},
{"testing/quick", "p\x01\x87\x01\x04#\x11\x0f"},
{"testing/slogtest", "\ra\x03\x80\x01.\x05\x11\n"},
{"text/scanner", "\x03nz,*\x02"},
{"text/tabwriter", "qzX"},
{"text/template", "n\x03B8\x01\v\x1f\x01\x05\x01\x02\x05\f\x02\f\x03\x02"},
{"text/template/parse", "\x03n\xb3\x01\v\x01\x11\x02"},
{"time", "n+\x1d\x1d'*\x0e\x02\x11"},
{"time/tzdata", "n\xc6\x01\x11"},
{"unicode", ""},
{"unicode/utf16", ""},
{"unicode/utf8", ""},
{"unique", "\x95\x01>\x01P\x0e\x13\x12"},
{"unsafe", ""},
{"vendor/golang.org/x/crypto/chacha20", "\x10W\a\x8c\x01*&"},
{"vendor/golang.org/x/crypto/chacha20poly1305", "\x10W\a\xd8\x01\x04\x01"},
{"vendor/golang.org/x/crypto/cryptobyte", "d\n\x03\x88\x01& \n"},
{"vendor/golang.org/x/crypto/cryptobyte/asn1", ""},
{"vendor/golang.org/x/crypto/internal/alias", "\xc5\x02"},
{"vendor/golang.org/x/crypto/internal/poly1305", "Q\x16\x93\x01"},
{"vendor/golang.org/x/net/dns/dnsmessage", "n"},
{"vendor/golang.org/x/net/http/httpguts", "\x81\x02\x14\x1b\x13\r"},
{"vendor/golang.org/x/net/http/httpproxy", "n\x03\x90\x01\x15\x01\x19\x13\r"},
{"vendor/golang.org/x/net/http2/hpack", "\x03k\x03zG"},
{"vendor/golang.org/x/net/idna", "q\x87\x018\x13\x10\x02\x01"},
{"vendor/golang.org/x/net/nettest", "\x03d\a\x03z\x11\x05\x16\x01\f\v\x01\x02\x02\x01\n"},
{"vendor/golang.org/x/sys/cpu", "\x97\x02\r\v\x01\x15"},
{"vendor/golang.org/x/text/secure/bidirule", "n\xd5\x01\x11\x01"},
{"vendor/golang.org/x/text/transform", "\x03k}X"},
{"vendor/golang.org/x/text/unicode/bidi", "\x03\bf~?\x15"},
{"vendor/golang.org/x/text/unicode/norm", "g\nzG\x11\x11"},
{"weak", "\x95\x01\x8f\x01!"},
}

89
vendor/golang.org/x/tools/internal/stdlib/import.go generated vendored Normal file
View File

@ -0,0 +1,89 @@
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package stdlib
// This file provides the API for the import graph of the standard library.
//
// Be aware that the compiler-generated code for every package
// implicitly depends on package "runtime" and a handful of others
// (see runtimePkgs in GOROOT/src/cmd/internal/objabi/pkgspecial.go).
import (
"encoding/binary"
"iter"
"slices"
"strings"
)
// Imports returns the sequence of packages directly imported by the
// named standard packages, in name order.
// The imports of an unknown package are the empty set.
//
// The graph is built into the application and may differ from the
// graph in the Go source tree being analyzed by the application.
func Imports(pkgs ...string) iter.Seq[string] {
return func(yield func(string) bool) {
for _, pkg := range pkgs {
if i, ok := find(pkg); ok {
var depIndex uint64
for data := []byte(deps[i].deps); len(data) > 0; {
delta, n := binary.Uvarint(data)
depIndex += delta
if !yield(deps[depIndex].name) {
return
}
data = data[n:]
}
}
}
}
}
// Dependencies returns the set of all dependencies of the named
// standard packages, including the initial package,
// in a deterministic topological order.
// The dependencies of an unknown package are the empty set.
//
// The graph is built into the application and may differ from the
// graph in the Go source tree being analyzed by the application.
func Dependencies(pkgs ...string) iter.Seq[string] {
return func(yield func(string) bool) {
for _, pkg := range pkgs {
if i, ok := find(pkg); ok {
var seen [1 + len(deps)/8]byte // bit set of seen packages
var visit func(i int) bool
visit = func(i int) bool {
bit := byte(1) << (i % 8)
if seen[i/8]&bit == 0 {
seen[i/8] |= bit
var depIndex uint64
for data := []byte(deps[i].deps); len(data) > 0; {
delta, n := binary.Uvarint(data)
depIndex += delta
if !visit(int(depIndex)) {
return false
}
data = data[n:]
}
if !yield(deps[i].name) {
return false
}
}
return true
}
if !visit(i) {
return
}
}
}
}
}
// find returns the index of pkg in the deps table.
func find(pkg string) (int, bool) {
return slices.BinarySearchFunc(deps[:], pkg, func(p pkginfo, n string) int {
return strings.Compare(p.name, n)
})
}

View File

@ -1,4 +1,4 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@ -2151,6 +2151,8 @@ var PackageSymbols = map[string][]Symbol{
{"(Type).String", Method, 0},
{"(Version).GoString", Method, 0},
{"(Version).String", Method, 0},
{"(VersionIndex).Index", Method, 24},
{"(VersionIndex).IsHidden", Method, 24},
{"ARM_MAGIC_TRAMP_NUMBER", Const, 0},
{"COMPRESS_HIOS", Const, 6},
{"COMPRESS_HIPROC", Const, 6},
@ -3834,6 +3836,7 @@ var PackageSymbols = map[string][]Symbol{
{"SymType", Type, 0},
{"SymVis", Type, 0},
{"Symbol", Type, 0},
{"Symbol.HasVersion", Field, 24},
{"Symbol.Info", Field, 0},
{"Symbol.Library", Field, 13},
{"Symbol.Name", Field, 0},
@ -3843,18 +3846,12 @@ var PackageSymbols = map[string][]Symbol{
{"Symbol.Value", Field, 0},
{"Symbol.Version", Field, 13},
{"Symbol.VersionIndex", Field, 24},
{"Symbol.VersionScope", Field, 24},
{"SymbolVersionScope", Type, 24},
{"Type", Type, 0},
{"VER_FLG_BASE", Const, 24},
{"VER_FLG_INFO", Const, 24},
{"VER_FLG_WEAK", Const, 24},
{"Version", Type, 0},
{"VersionScopeGlobal", Const, 24},
{"VersionScopeHidden", Const, 24},
{"VersionScopeLocal", Const, 24},
{"VersionScopeNone", Const, 24},
{"VersionScopeSpecific", Const, 24},
{"VersionIndex", Type, 24},
},
"debug/gosym": {
{"(*DecodingError).Error", Method, 0},
@ -7122,6 +7119,7 @@ var PackageSymbols = map[string][]Symbol{
{"FormatFileInfo", Func, 21},
{"Glob", Func, 16},
{"GlobFS", Type, 16},
{"Lstat", Func, 25},
{"ModeAppend", Const, 16},
{"ModeCharDevice", Const, 16},
{"ModeDevice", Const, 16},
@ -7146,6 +7144,8 @@ var PackageSymbols = map[string][]Symbol{
{"ReadDirFile", Type, 16},
{"ReadFile", Func, 16},
{"ReadFileFS", Type, 16},
{"ReadLink", Func, 25},
{"ReadLinkFS", Type, 25},
{"SkipAll", Var, 20},
{"SkipDir", Var, 16},
{"Stat", Func, 16},
@ -9149,6 +9149,8 @@ var PackageSymbols = map[string][]Symbol{
{"(*ProcessState).SysUsage", Method, 0},
{"(*ProcessState).SystemTime", Method, 0},
{"(*ProcessState).UserTime", Method, 0},
{"(*Root).Chmod", Method, 25},
{"(*Root).Chown", Method, 25},
{"(*Root).Close", Method, 24},
{"(*Root).Create", Method, 24},
{"(*Root).FS", Method, 24},
@ -16757,9 +16759,11 @@ var PackageSymbols = map[string][]Symbol{
},
"testing/fstest": {
{"(MapFS).Glob", Method, 16},
{"(MapFS).Lstat", Method, 25},
{"(MapFS).Open", Method, 16},
{"(MapFS).ReadDir", Method, 16},
{"(MapFS).ReadFile", Method, 16},
{"(MapFS).ReadLink", Method, 25},
{"(MapFS).Stat", Method, 16},
{"(MapFS).Sub", Method, 16},
{"MapFS", Type, 16},

View File

@ -6,7 +6,7 @@
// Package stdlib provides a table of all exported symbols in the
// standard library, along with the version at which they first
// appeared.
// appeared. It also provides the import graph of std packages.
package stdlib
import (

View File

@ -120,7 +120,7 @@ type termSet struct {
terms termlist
}
func indentf(depth int, format string, args ...interface{}) {
func indentf(depth int, format string, args ...any) {
fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...)
}

View File

@ -32,12 +32,14 @@ func SetUsesCgo(conf *types.Config) bool {
return true
}
// ReadGo116ErrorData extracts additional information from types.Error values
// ErrorCodeStartEnd extracts additional information from types.Error values
// generated by Go version 1.16 and later: the error code, start position, and
// end position. If all positions are valid, start <= err.Pos <= end.
//
// If the data could not be read, the final result parameter will be false.
func ReadGo116ErrorData(err types.Error) (code ErrorCode, start, end token.Pos, ok bool) {
//
// TODO(adonovan): eliminate start/end when proposal #71803 is accepted.
func ErrorCodeStartEnd(err types.Error) (code ErrorCode, start, end token.Pos, ok bool) {
var data [3]int
// By coincidence all of these fields are ints, which simplifies things.
v := reflect.ValueOf(err)

View File

@ -129,6 +129,13 @@ type State struct {
// brand new implementation of this interface. For the situations like
// testing, the new implementation should embed this interface. This allows
// gRPC to add new methods to this interface.
//
// NOTICE: This interface is intended to be implemented by gRPC, or intercepted
// by custom load balancing polices. Users should not need their own complete
// implementation of this interface -- they should always delegate to a
// ClientConn passed to Builder.Build() by embedding it in their
// implementations. An embedded ClientConn must never be nil, or runtime panics
// will occur.
type ClientConn interface {
// NewSubConn is called by balancer to create a new SubConn.
// It doesn't block and wait for the connections to be established.
@ -167,6 +174,17 @@ type ClientConn interface {
//
// Deprecated: Use the Target field in the BuildOptions instead.
Target() string
// MetricsRecorder provides the metrics recorder that balancers can use to
// record metrics. Balancer implementations which do not register metrics on
// metrics registry and record on them can ignore this method. The returned
// MetricsRecorder is guaranteed to never be nil.
MetricsRecorder() estats.MetricsRecorder
// EnforceClientConnEmbedding is included to force implementers to embed
// another implementation of this interface, allowing gRPC to add methods
// without breaking users.
internal.EnforceClientConnEmbedding
}
// BuildOptions contains additional information for Build.
@ -198,10 +216,6 @@ type BuildOptions struct {
// same resolver.Target as passed to the resolver. See the documentation for
// the resolver.Target type for details about what it contains.
Target resolver.Target
// MetricsRecorder is the metrics recorder that balancers can use to record
// metrics. Balancer implementations which do not register metrics on
// metrics registry and record on them can ignore this field.
MetricsRecorder estats.MetricsRecorder
}
// Builder creates a balancer.

View File

@ -0,0 +1,358 @@
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Package endpointsharding implements a load balancing policy that manages
// homogeneous child policies each owning a single endpoint.
//
// # Experimental
//
// Notice: This package is EXPERIMENTAL and may be changed or removed in a
// later release.
package endpointsharding
import (
"errors"
rand "math/rand/v2"
"sync"
"sync/atomic"
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/balancer/base"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/resolver"
)
// ChildState is the balancer state of a child along with the endpoint which
// identifies the child balancer.
type ChildState struct {
Endpoint resolver.Endpoint
State balancer.State
// Balancer exposes only the ExitIdler interface of the child LB policy.
// Other methods of the child policy are called only by endpointsharding.
Balancer balancer.ExitIdler
}
// Options are the options to configure the behaviour of the
// endpointsharding balancer.
type Options struct {
// DisableAutoReconnect allows the balancer to keep child balancer in the
// IDLE state until they are explicitly triggered to exit using the
// ChildState obtained from the endpointsharding picker. When set to false,
// the endpointsharding balancer will automatically call ExitIdle on child
// connections that report IDLE.
DisableAutoReconnect bool
}
// ChildBuilderFunc creates a new balancer with the ClientConn. It has the same
// type as the balancer.Builder.Build method.
type ChildBuilderFunc func(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer
// NewBalancer returns a load balancing policy that manages homogeneous child
// policies each owning a single endpoint. The endpointsharding balancer
// forwards the LoadBalancingConfig in ClientConn state updates to its children.
func NewBalancer(cc balancer.ClientConn, opts balancer.BuildOptions, childBuilder ChildBuilderFunc, esOpts Options) balancer.Balancer {
es := &endpointSharding{
cc: cc,
bOpts: opts,
esOpts: esOpts,
childBuilder: childBuilder,
}
es.children.Store(resolver.NewEndpointMap())
return es
}
// endpointSharding is a balancer that wraps child balancers. It creates a child
// balancer with child config for every unique Endpoint received. It updates the
// child states on any update from parent or child.
type endpointSharding struct {
cc balancer.ClientConn
bOpts balancer.BuildOptions
esOpts Options
childBuilder ChildBuilderFunc
// childMu synchronizes calls to any single child. It must be held for all
// calls into a child. To avoid deadlocks, do not acquire childMu while
// holding mu.
childMu sync.Mutex
children atomic.Pointer[resolver.EndpointMap] // endpoint -> *balancerWrapper
// inhibitChildUpdates is set during UpdateClientConnState/ResolverError
// calls (calls to children will each produce an update, only want one
// update).
inhibitChildUpdates atomic.Bool
// mu synchronizes access to the state stored in balancerWrappers in the
// children field. mu must not be held during calls into a child since
// synchronous calls back from the child may require taking mu, causing a
// deadlock. To avoid deadlocks, do not acquire childMu while holding mu.
mu sync.Mutex
}
// UpdateClientConnState creates a child for new endpoints and deletes children
// for endpoints that are no longer present. It also updates all the children,
// and sends a single synchronous update of the childrens' aggregated state at
// the end of the UpdateClientConnState operation. If any endpoint has no
// addresses it will ignore that endpoint. Otherwise, returns first error found
// from a child, but fully processes the new update.
func (es *endpointSharding) UpdateClientConnState(state balancer.ClientConnState) error {
es.childMu.Lock()
defer es.childMu.Unlock()
es.inhibitChildUpdates.Store(true)
defer func() {
es.inhibitChildUpdates.Store(false)
es.updateState()
}()
var ret error
children := es.children.Load()
newChildren := resolver.NewEndpointMap()
// Update/Create new children.
for _, endpoint := range state.ResolverState.Endpoints {
if _, ok := newChildren.Get(endpoint); ok {
// Endpoint child was already created, continue to avoid duplicate
// update.
continue
}
var childBalancer *balancerWrapper
if val, ok := children.Get(endpoint); ok {
childBalancer = val.(*balancerWrapper)
// Endpoint attributes may have changed, update the stored endpoint.
es.mu.Lock()
childBalancer.childState.Endpoint = endpoint
es.mu.Unlock()
} else {
childBalancer = &balancerWrapper{
childState: ChildState{Endpoint: endpoint},
ClientConn: es.cc,
es: es,
}
childBalancer.childState.Balancer = childBalancer
childBalancer.child = es.childBuilder(childBalancer, es.bOpts)
}
newChildren.Set(endpoint, childBalancer)
if err := childBalancer.updateClientConnStateLocked(balancer.ClientConnState{
BalancerConfig: state.BalancerConfig,
ResolverState: resolver.State{
Endpoints: []resolver.Endpoint{endpoint},
Attributes: state.ResolverState.Attributes,
},
}); err != nil && ret == nil {
// Return first error found, and always commit full processing of
// updating children. If desired to process more specific errors
// across all endpoints, caller should make these specific
// validations, this is a current limitation for simplicity sake.
ret = err
}
}
// Delete old children that are no longer present.
for _, e := range children.Keys() {
child, _ := children.Get(e)
if _, ok := newChildren.Get(e); !ok {
child.(*balancerWrapper).closeLocked()
}
}
es.children.Store(newChildren)
if newChildren.Len() == 0 {
return balancer.ErrBadResolverState
}
return ret
}
// ResolverError forwards the resolver error to all of the endpointSharding's
// children and sends a single synchronous update of the childStates at the end
// of the ResolverError operation.
func (es *endpointSharding) ResolverError(err error) {
es.childMu.Lock()
defer es.childMu.Unlock()
es.inhibitChildUpdates.Store(true)
defer func() {
es.inhibitChildUpdates.Store(false)
es.updateState()
}()
children := es.children.Load()
for _, child := range children.Values() {
child.(*balancerWrapper).resolverErrorLocked(err)
}
}
func (es *endpointSharding) UpdateSubConnState(balancer.SubConn, balancer.SubConnState) {
// UpdateSubConnState is deprecated.
}
func (es *endpointSharding) Close() {
es.childMu.Lock()
defer es.childMu.Unlock()
children := es.children.Load()
for _, child := range children.Values() {
child.(*balancerWrapper).closeLocked()
}
}
// updateState updates this component's state. It sends the aggregated state,
// and a picker with round robin behavior with all the child states present if
// needed.
func (es *endpointSharding) updateState() {
if es.inhibitChildUpdates.Load() {
return
}
var readyPickers, connectingPickers, idlePickers, transientFailurePickers []balancer.Picker
es.mu.Lock()
defer es.mu.Unlock()
children := es.children.Load()
childStates := make([]ChildState, 0, children.Len())
for _, child := range children.Values() {
bw := child.(*balancerWrapper)
childState := bw.childState
childStates = append(childStates, childState)
childPicker := childState.State.Picker
switch childState.State.ConnectivityState {
case connectivity.Ready:
readyPickers = append(readyPickers, childPicker)
case connectivity.Connecting:
connectingPickers = append(connectingPickers, childPicker)
case connectivity.Idle:
idlePickers = append(idlePickers, childPicker)
case connectivity.TransientFailure:
transientFailurePickers = append(transientFailurePickers, childPicker)
// connectivity.Shutdown shouldn't appear.
}
}
// Construct the round robin picker based off the aggregated state. Whatever
// the aggregated state, use the pickers present that are currently in that
// state only.
var aggState connectivity.State
var pickers []balancer.Picker
if len(readyPickers) >= 1 {
aggState = connectivity.Ready
pickers = readyPickers
} else if len(connectingPickers) >= 1 {
aggState = connectivity.Connecting
pickers = connectingPickers
} else if len(idlePickers) >= 1 {
aggState = connectivity.Idle
pickers = idlePickers
} else if len(transientFailurePickers) >= 1 {
aggState = connectivity.TransientFailure
pickers = transientFailurePickers
} else {
aggState = connectivity.TransientFailure
pickers = []balancer.Picker{base.NewErrPicker(errors.New("no children to pick from"))}
} // No children (resolver error before valid update).
p := &pickerWithChildStates{
pickers: pickers,
childStates: childStates,
next: uint32(rand.IntN(len(pickers))),
}
es.cc.UpdateState(balancer.State{
ConnectivityState: aggState,
Picker: p,
})
}
// pickerWithChildStates delegates to the pickers it holds in a round robin
// fashion. It also contains the childStates of all the endpointSharding's
// children.
type pickerWithChildStates struct {
pickers []balancer.Picker
childStates []ChildState
next uint32
}
func (p *pickerWithChildStates) Pick(info balancer.PickInfo) (balancer.PickResult, error) {
nextIndex := atomic.AddUint32(&p.next, 1)
picker := p.pickers[nextIndex%uint32(len(p.pickers))]
return picker.Pick(info)
}
// ChildStatesFromPicker returns the state of all the children managed by the
// endpoint sharding balancer that created this picker.
func ChildStatesFromPicker(picker balancer.Picker) []ChildState {
p, ok := picker.(*pickerWithChildStates)
if !ok {
return nil
}
return p.childStates
}
// balancerWrapper is a wrapper of a balancer. It ID's a child balancer by
// endpoint, and persists recent child balancer state.
type balancerWrapper struct {
// The following fields are initialized at build time and read-only after
// that and therefore do not need to be guarded by a mutex.
// child contains the wrapped balancer. Access its methods only through
// methods on balancerWrapper to ensure proper synchronization
child balancer.Balancer
balancer.ClientConn // embed to intercept UpdateState, doesn't deal with SubConns
es *endpointSharding
// Access to the following fields is guarded by es.mu.
childState ChildState
isClosed bool
}
func (bw *balancerWrapper) UpdateState(state balancer.State) {
bw.es.mu.Lock()
bw.childState.State = state
bw.es.mu.Unlock()
if state.ConnectivityState == connectivity.Idle && !bw.es.esOpts.DisableAutoReconnect {
bw.ExitIdle()
}
bw.es.updateState()
}
// ExitIdle pings an IDLE child balancer to exit idle in a new goroutine to
// avoid deadlocks due to synchronous balancer state updates.
func (bw *balancerWrapper) ExitIdle() {
if ei, ok := bw.child.(balancer.ExitIdler); ok {
go func() {
bw.es.childMu.Lock()
if !bw.isClosed {
ei.ExitIdle()
}
bw.es.childMu.Unlock()
}()
}
}
// updateClientConnStateLocked delivers the ClientConnState to the child
// balancer. Callers must hold the child mutex of the parent endpointsharding
// balancer.
func (bw *balancerWrapper) updateClientConnStateLocked(ccs balancer.ClientConnState) error {
return bw.child.UpdateClientConnState(ccs)
}
// closeLocked closes the child balancer. Callers must hold the child mutext of
// the parent endpointsharding balancer.
func (bw *balancerWrapper) closeLocked() {
bw.child.Close()
bw.isClosed = true
}
func (bw *balancerWrapper) resolverErrorLocked(err error) {
bw.child.ResolverError(err)
}

View File

@ -120,7 +120,7 @@ func (pickfirstBuilder) Build(cc balancer.ClientConn, bo balancer.BuildOptions)
b := &pickfirstBalancer{
cc: cc,
target: bo.Target.String(),
metricsRecorder: bo.MetricsRecorder, // ClientConn will always create a Metrics Recorder.
metricsRecorder: cc.MetricsRecorder(),
subConns: resolver.NewAddressMap(),
state: connectivity.Connecting,

View File

@ -22,12 +22,13 @@
package roundrobin
import (
rand "math/rand/v2"
"sync/atomic"
"fmt"
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/balancer/base"
"google.golang.org/grpc/balancer/endpointsharding"
"google.golang.org/grpc/balancer/pickfirst/pickfirstleaf"
"google.golang.org/grpc/grpclog"
internalgrpclog "google.golang.org/grpc/internal/grpclog"
)
// Name is the name of round_robin balancer.
@ -35,47 +36,44 @@ const Name = "round_robin"
var logger = grpclog.Component("roundrobin")
// newBuilder creates a new roundrobin balancer builder.
func newBuilder() balancer.Builder {
return base.NewBalancerBuilder(Name, &rrPickerBuilder{}, base.Config{HealthCheck: true})
}
func init() {
balancer.Register(newBuilder())
balancer.Register(builder{})
}
type rrPickerBuilder struct{}
type builder struct{}
func (*rrPickerBuilder) Build(info base.PickerBuildInfo) balancer.Picker {
logger.Infof("roundrobinPicker: Build called with info: %v", info)
if len(info.ReadySCs) == 0 {
return base.NewErrPicker(balancer.ErrNoSubConnAvailable)
func (bb builder) Name() string {
return Name
}
func (bb builder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
childBuilder := balancer.Get(pickfirstleaf.Name).Build
bal := &rrBalancer{
cc: cc,
Balancer: endpointsharding.NewBalancer(cc, opts, childBuilder, endpointsharding.Options{}),
}
scs := make([]balancer.SubConn, 0, len(info.ReadySCs))
for sc := range info.ReadySCs {
scs = append(scs, sc)
}
return &rrPicker{
subConns: scs,
// Start at a random index, as the same RR balancer rebuilds a new
// picker when SubConn states change, and we don't want to apply excess
// load to the first server in the list.
next: uint32(rand.IntN(len(scs))),
bal.logger = internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[%p] ", bal))
bal.logger.Infof("Created")
return bal
}
type rrBalancer struct {
balancer.Balancer
cc balancer.ClientConn
logger *internalgrpclog.PrefixLogger
}
func (b *rrBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error {
return b.Balancer.UpdateClientConnState(balancer.ClientConnState{
// Enable the health listener in pickfirst children for client side health
// checks and outlier detection, if configured.
ResolverState: pickfirstleaf.EnableHealthListener(ccs.ResolverState),
})
}
func (b *rrBalancer) ExitIdle() {
// Should always be ok, as child is endpoint sharding.
if ei, ok := b.Balancer.(balancer.ExitIdler); ok {
ei.ExitIdle()
}
}
type rrPicker struct {
// subConns is the snapshot of the roundrobin balancer when this picker was
// created. The slice is immutable. Each Get() will do a round robin
// selection from it and return the selected SubConn.
subConns []balancer.SubConn
next uint32
}
func (p *rrPicker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
subConnsLen := uint32(len(p.subConns))
nextIndex := atomic.AddUint32(&p.next, 1)
sc := p.subConns[nextIndex%subConnsLen]
return balancer.PickResult{SubConn: sc}, nil
}

View File

@ -44,7 +44,7 @@ import (
// should only use a single address.
//
// NOTICE: This interface is intended to be implemented by gRPC, or intercepted
// by custom load balancing poilices. Users should not need their own complete
// by custom load balancing polices. Users should not need their own complete
// implementation of this interface -- they should always delegate to a SubConn
// returned by ClientConn.NewSubConn() by embedding it in their implementations.
// An embedded SubConn must never be nil, or runtime panics will occur.

View File

@ -26,6 +26,7 @@ import (
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/experimental/stats"
"google.golang.org/grpc/internal"
"google.golang.org/grpc/internal/balancer/gracefulswitch"
"google.golang.org/grpc/internal/channelz"
@ -59,6 +60,7 @@ var (
// It uses the gracefulswitch.Balancer internally to ensure that balancer
// switches happen in a graceful manner.
type ccBalancerWrapper struct {
internal.EnforceClientConnEmbedding
// The following fields are initialized when the wrapper is created and are
// read-only afterwards, and therefore can be accessed without a mutex.
cc *ClientConn
@ -92,7 +94,6 @@ func newCCBalancerWrapper(cc *ClientConn) *ccBalancerWrapper {
CustomUserAgent: cc.dopts.copts.UserAgent,
ChannelzParent: cc.channelz,
Target: cc.parsedTarget,
MetricsRecorder: cc.metricsRecorderList,
},
serializer: grpcsync.NewCallbackSerializer(ctx),
serializerCancel: cancel,
@ -101,6 +102,10 @@ func newCCBalancerWrapper(cc *ClientConn) *ccBalancerWrapper {
return ccb
}
func (ccb *ccBalancerWrapper) MetricsRecorder() stats.MetricsRecorder {
return ccb.cc.metricsRecorderList
}
// updateClientConnState is invoked by grpc to push a ClientConnState update to
// the underlying balancer. This is always executed from the serializer, so
// it is safe to call into the balancer here.
@ -415,7 +420,7 @@ func (acbw *acBalancerWrapper) GetOrBuildProducer(pb balancer.ProducerBuilder) (
}
acbw.producersMu.Unlock()
}
return pData.producer, grpcsync.OnceFunc(unref)
return pData.producer, sync.OnceFunc(unref)
}
func (acbw *acBalancerWrapper) closeProducers() {

View File

@ -18,7 +18,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.35.2
// protoc-gen-go v1.36.4
// protoc v5.27.1
// source: grpc/binlog/v1/binarylog.proto
@ -31,6 +31,7 @@ import (
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
@ -233,10 +234,7 @@ func (Address_Type) EnumDescriptor() ([]byte, []int) {
// Log entry we store in binary logs
type GrpcLogEntry struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
state protoimpl.MessageState `protogen:"open.v1"`
// The timestamp of the binary log message
Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
// Uniquely identifies a call. The value must not be 0 in order to disambiguate
@ -255,7 +253,7 @@ type GrpcLogEntry struct {
// The logger uses one of the following fields to record the payload,
// according to the type of the log entry.
//
// Types that are assignable to Payload:
// Types that are valid to be assigned to Payload:
//
// *GrpcLogEntry_ClientHeader
// *GrpcLogEntry_ServerHeader
@ -269,7 +267,9 @@ type GrpcLogEntry struct {
// EVENT_TYPE_SERVER_HEADER normally or EVENT_TYPE_SERVER_TRAILER in
// the case of trailers-only. On server side, peer is always
// logged on EVENT_TYPE_CLIENT_HEADER.
Peer *Address `protobuf:"bytes,11,opt,name=peer,proto3" json:"peer,omitempty"`
Peer *Address `protobuf:"bytes,11,opt,name=peer,proto3" json:"peer,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GrpcLogEntry) Reset() {
@ -337,37 +337,45 @@ func (x *GrpcLogEntry) GetLogger() GrpcLogEntry_Logger {
return GrpcLogEntry_LOGGER_UNKNOWN
}
func (m *GrpcLogEntry) GetPayload() isGrpcLogEntry_Payload {
if m != nil {
return m.Payload
func (x *GrpcLogEntry) GetPayload() isGrpcLogEntry_Payload {
if x != nil {
return x.Payload
}
return nil
}
func (x *GrpcLogEntry) GetClientHeader() *ClientHeader {
if x, ok := x.GetPayload().(*GrpcLogEntry_ClientHeader); ok {
return x.ClientHeader
if x != nil {
if x, ok := x.Payload.(*GrpcLogEntry_ClientHeader); ok {
return x.ClientHeader
}
}
return nil
}
func (x *GrpcLogEntry) GetServerHeader() *ServerHeader {
if x, ok := x.GetPayload().(*GrpcLogEntry_ServerHeader); ok {
return x.ServerHeader
if x != nil {
if x, ok := x.Payload.(*GrpcLogEntry_ServerHeader); ok {
return x.ServerHeader
}
}
return nil
}
func (x *GrpcLogEntry) GetMessage() *Message {
if x, ok := x.GetPayload().(*GrpcLogEntry_Message); ok {
return x.Message
if x != nil {
if x, ok := x.Payload.(*GrpcLogEntry_Message); ok {
return x.Message
}
}
return nil
}
func (x *GrpcLogEntry) GetTrailer() *Trailer {
if x, ok := x.GetPayload().(*GrpcLogEntry_Trailer); ok {
return x.Trailer
if x != nil {
if x, ok := x.Payload.(*GrpcLogEntry_Trailer); ok {
return x.Trailer
}
}
return nil
}
@ -416,10 +424,7 @@ func (*GrpcLogEntry_Message) isGrpcLogEntry_Payload() {}
func (*GrpcLogEntry_Trailer) isGrpcLogEntry_Payload() {}
type ClientHeader struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
state protoimpl.MessageState `protogen:"open.v1"`
// This contains only the metadata from the application.
Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"`
// The name of the RPC method, which looks something like:
@ -433,7 +438,9 @@ type ClientHeader struct {
// <host> or <host>:<port> .
Authority string `protobuf:"bytes,3,opt,name=authority,proto3" json:"authority,omitempty"`
// the RPC timeout
Timeout *durationpb.Duration `protobuf:"bytes,4,opt,name=timeout,proto3" json:"timeout,omitempty"`
Timeout *durationpb.Duration `protobuf:"bytes,4,opt,name=timeout,proto3" json:"timeout,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ClientHeader) Reset() {
@ -495,12 +502,11 @@ func (x *ClientHeader) GetTimeout() *durationpb.Duration {
}
type ServerHeader struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
state protoimpl.MessageState `protogen:"open.v1"`
// This contains only the metadata from the application.
Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"`
Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ServerHeader) Reset() {
@ -541,10 +547,7 @@ func (x *ServerHeader) GetMetadata() *Metadata {
}
type Trailer struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
state protoimpl.MessageState `protogen:"open.v1"`
// This contains only the metadata from the application.
Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"`
// The gRPC status code.
@ -555,6 +558,8 @@ type Trailer struct {
// The value of the 'grpc-status-details-bin' metadata key. If
// present, this is always an encoded 'google.rpc.Status' message.
StatusDetails []byte `protobuf:"bytes,4,opt,name=status_details,json=statusDetails,proto3" json:"status_details,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Trailer) Reset() {
@ -617,15 +622,14 @@ func (x *Trailer) GetStatusDetails() []byte {
// Message payload, used by CLIENT_MESSAGE and SERVER_MESSAGE
type Message struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
state protoimpl.MessageState `protogen:"open.v1"`
// Length of the message. It may not be the same as the length of the
// data field, as the logging payload can be truncated or omitted.
Length uint32 `protobuf:"varint,1,opt,name=length,proto3" json:"length,omitempty"`
// May be truncated or omitted.
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Message) Reset() {
@ -694,11 +698,10 @@ func (x *Message) GetData() []byte {
// header is just a normal metadata key.
// The pair will not count towards the size limit.
type Metadata struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Entry []*MetadataEntry `protobuf:"bytes,1,rep,name=entry,proto3" json:"entry,omitempty"`
unknownFields protoimpl.UnknownFields
Entry []*MetadataEntry `protobuf:"bytes,1,rep,name=entry,proto3" json:"entry,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *Metadata) Reset() {
@ -740,12 +743,11 @@ func (x *Metadata) GetEntry() []*MetadataEntry {
// A metadata key value pair
type MetadataEntry struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *MetadataEntry) Reset() {
@ -794,14 +796,13 @@ func (x *MetadataEntry) GetValue() []byte {
// Address information
type Address struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Type Address_Type `protobuf:"varint,1,opt,name=type,proto3,enum=grpc.binarylog.v1.Address_Type" json:"type,omitempty"`
Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
state protoimpl.MessageState `protogen:"open.v1"`
Type Address_Type `protobuf:"varint,1,opt,name=type,proto3,enum=grpc.binarylog.v1.Address_Type" json:"type,omitempty"`
Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
// only for TYPE_IPV4 and TYPE_IPV6
IpPort uint32 `protobuf:"varint,3,opt,name=ip_port,json=ipPort,proto3" json:"ip_port,omitempty"`
IpPort uint32 `protobuf:"varint,3,opt,name=ip_port,json=ipPort,proto3" json:"ip_port,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Address) Reset() {
@ -857,7 +858,7 @@ func (x *Address) GetIpPort() uint32 {
var File_grpc_binlog_v1_binarylog_proto protoreflect.FileDescriptor
var file_grpc_binlog_v1_binarylog_proto_rawDesc = []byte{
var file_grpc_binlog_v1_binarylog_proto_rawDesc = string([]byte{
0x0a, 0x1e, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31,
0x2f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x11, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x6c, 0x6f, 0x67,
@ -983,16 +984,16 @@ var file_grpc_binlog_v1_binarylog_proto_rawDesc = []byte{
0x69, 0x6e, 0x61, 0x72, 0x79, 0x6c, 0x6f, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x62, 0x69,
0x6e, 0x61, 0x72, 0x79, 0x6c, 0x6f, 0x67, 0x5f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
})
var (
file_grpc_binlog_v1_binarylog_proto_rawDescOnce sync.Once
file_grpc_binlog_v1_binarylog_proto_rawDescData = file_grpc_binlog_v1_binarylog_proto_rawDesc
file_grpc_binlog_v1_binarylog_proto_rawDescData []byte
)
func file_grpc_binlog_v1_binarylog_proto_rawDescGZIP() []byte {
file_grpc_binlog_v1_binarylog_proto_rawDescOnce.Do(func() {
file_grpc_binlog_v1_binarylog_proto_rawDescData = protoimpl.X.CompressGZIP(file_grpc_binlog_v1_binarylog_proto_rawDescData)
file_grpc_binlog_v1_binarylog_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_grpc_binlog_v1_binarylog_proto_rawDesc), len(file_grpc_binlog_v1_binarylog_proto_rawDesc)))
})
return file_grpc_binlog_v1_binarylog_proto_rawDescData
}
@ -1051,7 +1052,7 @@ func file_grpc_binlog_v1_binarylog_proto_init() {
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_grpc_binlog_v1_binarylog_proto_rawDesc,
RawDescriptor: unsafe.Slice(unsafe.StringData(file_grpc_binlog_v1_binarylog_proto_rawDesc), len(file_grpc_binlog_v1_binarylog_proto_rawDesc)),
NumEnums: 3,
NumMessages: 8,
NumExtensions: 0,
@ -1063,7 +1064,6 @@ func file_grpc_binlog_v1_binarylog_proto_init() {
MessageInfos: file_grpc_binlog_v1_binarylog_proto_msgTypes,
}.Build()
File_grpc_binlog_v1_binarylog_proto = out.File
file_grpc_binlog_v1_binarylog_proto_rawDesc = nil
file_grpc_binlog_v1_binarylog_proto_goTypes = nil
file_grpc_binlog_v1_binarylog_proto_depIdxs = nil
}

View File

@ -118,12 +118,26 @@ func (dcs *defaultConfigSelector) SelectConfig(rpcInfo iresolver.RPCInfo) (*ires
// NewClient creates a new gRPC "channel" for the target URI provided. No I/O
// is performed. Use of the ClientConn for RPCs will automatically cause it to
// connect. Connect may be used to manually create a connection, but for most
// users this is unnecessary.
// connect. The Connect method may be called to manually create a connection,
// but for most users this should be unnecessary.
//
// The target name syntax is defined in
// https://github.com/grpc/grpc/blob/master/doc/naming.md. e.g. to use dns
// resolver, a "dns:///" prefix should be applied to the target.
// https://github.com/grpc/grpc/blob/master/doc/naming.md. E.g. to use the dns
// name resolver, a "dns:///" prefix may be applied to the target. The default
// name resolver will be used if no scheme is detected, or if the parsed scheme
// is not a registered name resolver. The default resolver is "dns" but can be
// overridden using the resolver package's SetDefaultScheme.
//
// Examples:
//
// - "foo.googleapis.com:8080"
// - "dns:///foo.googleapis.com:8080"
// - "dns:///foo.googleapis.com"
// - "dns:///10.0.0.213:8080"
// - "dns:///%5B2001:db8:85a3:8d3:1319:8a2e:370:7348%5D:443"
// - "dns://8.8.8.8/foo.googleapis.com:8080"
// - "dns://8.8.8.8/foo.googleapis.com"
// - "zookeeper://zk.example.com:9900/example_service"
//
// The DialOptions returned by WithBlock, WithTimeout,
// WithReturnConnectionError, and FailOnNonTempDialError are ignored by this
@ -181,7 +195,7 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error)
}
cc.dopts.defaultServiceConfig, _ = scpr.Config.(*ServiceConfig)
}
cc.mkp = cc.dopts.copts.KeepaliveParams
cc.keepaliveParams = cc.dopts.copts.KeepaliveParams
if err = cc.initAuthority(); err != nil {
return nil, err
@ -225,7 +239,12 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) {
func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) {
// At the end of this method, we kick the channel out of idle, rather than
// waiting for the first rpc.
opts = append([]DialOption{withDefaultScheme("passthrough")}, opts...)
//
// WithLocalDNSResolution dial option in `grpc.Dial` ensures that it
// preserves behavior: when default scheme passthrough is used, skip
// hostname resolution, when "dns" is used for resolution, perform
// resolution on the client.
opts = append([]DialOption{withDefaultScheme("passthrough"), WithLocalDNSResolution()}, opts...)
cc, err := NewClient(target, opts...)
if err != nil {
return nil, err
@ -618,7 +637,7 @@ type ClientConn struct {
balancerWrapper *ccBalancerWrapper // Always recreated whenever entering idle to simplify Close.
sc *ServiceConfig // Latest service config received from the resolver.
conns map[*addrConn]struct{} // Set to nil on close.
mkp keepalive.ClientParameters // May be updated upon receipt of a GoAway.
keepaliveParams keepalive.ClientParameters // May be updated upon receipt of a GoAway.
// firstResolveEvent is used to track whether the name resolver sent us at
// least one update. RPCs block on this event. May be accessed without mu
// if we know we cannot be asked to enter idle mode while accessing it (e.g.
@ -867,7 +886,13 @@ func (cc *ClientConn) Target() string {
return cc.target
}
// CanonicalTarget returns the canonical target string of the ClientConn.
// CanonicalTarget returns the canonical target string used when creating cc.
//
// This always has the form "<scheme>://[authority]/<endpoint>". For example:
//
// - "dns:///example.com:42"
// - "dns://8.8.8.8/example.com:42"
// - "unix:///path/to/socket"
func (cc *ClientConn) CanonicalTarget() string {
return cc.parsedTarget.String()
}
@ -1210,8 +1235,8 @@ func (ac *addrConn) adjustParams(r transport.GoAwayReason) {
case transport.GoAwayTooManyPings:
v := 2 * ac.dopts.copts.KeepaliveParams.Time
ac.cc.mu.Lock()
if v > ac.cc.mkp.Time {
ac.cc.mkp.Time = v
if v > ac.cc.keepaliveParams.Time {
ac.cc.keepaliveParams.Time = v
}
ac.cc.mu.Unlock()
}
@ -1307,7 +1332,7 @@ func (ac *addrConn) tryAllAddrs(ctx context.Context, addrs []resolver.Address, c
ac.mu.Lock()
ac.cc.mu.RLock()
ac.dopts.copts.KeepaliveParams = ac.cc.mkp
ac.dopts.copts.KeepaliveParams = ac.cc.keepaliveParams
ac.cc.mu.RUnlock()
copts := ac.dopts.copts

View File

@ -73,7 +73,7 @@ type dialOptions struct {
chainUnaryInts []UnaryClientInterceptor
chainStreamInts []StreamClientInterceptor
cp Compressor
compressorV0 Compressor
dc Decompressor
bs internalbackoff.Strategy
block bool
@ -94,6 +94,8 @@ type dialOptions struct {
idleTimeout time.Duration
defaultScheme string
maxCallAttempts int
enableLocalDNSResolution bool // Specifies if target hostnames should be resolved when proxying is enabled.
useProxy bool // Specifies if a server should be connected via proxy.
}
// DialOption configures how we set up the connection.
@ -256,7 +258,7 @@ func WithCodec(c Codec) DialOption {
// Deprecated: use UseCompressor instead. Will be supported throughout 1.x.
func WithCompressor(cp Compressor) DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.cp = cp
o.compressorV0 = cp
})
}
@ -377,7 +379,22 @@ func WithInsecure() DialOption {
// later release.
func WithNoProxy() DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.copts.UseProxy = false
o.useProxy = false
})
}
// WithLocalDNSResolution forces local DNS name resolution even when a proxy is
// specified in the environment. By default, the server name is provided
// directly to the proxy as part of the CONNECT handshake. This is ignored if
// WithNoProxy is used.
//
// # Experimental
//
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
// later release.
func WithLocalDNSResolution() DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.enableLocalDNSResolution = true
})
}
@ -667,14 +684,15 @@ func defaultDialOptions() dialOptions {
copts: transport.ConnectOptions{
ReadBufferSize: defaultReadBufSize,
WriteBufferSize: defaultWriteBufSize,
UseProxy: true,
UserAgent: grpcUA,
BufferPool: mem.DefaultBufferPool(),
},
bs: internalbackoff.DefaultExponential,
idleTimeout: 30 * time.Minute,
defaultScheme: "dns",
maxCallAttempts: defaultMaxCallAttempts,
bs: internalbackoff.DefaultExponential,
idleTimeout: 30 * time.Minute,
defaultScheme: "dns",
maxCallAttempts: defaultMaxCallAttempts,
useProxy: true,
enableLocalDNSResolution: false,
}
}

View File

@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.35.2
// protoc-gen-go v1.36.4
// protoc v5.27.1
// source: grpc/health/v1/health.proto
@ -28,6 +28,7 @@ import (
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
@ -90,11 +91,10 @@ func (HealthCheckResponse_ServingStatus) EnumDescriptor() ([]byte, []int) {
}
type HealthCheckRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
unknownFields protoimpl.UnknownFields
Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *HealthCheckRequest) Reset() {
@ -135,11 +135,10 @@ func (x *HealthCheckRequest) GetService() string {
}
type HealthCheckResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
state protoimpl.MessageState `protogen:"open.v1"`
Status HealthCheckResponse_ServingStatus `protobuf:"varint,1,opt,name=status,proto3,enum=grpc.health.v1.HealthCheckResponse_ServingStatus" json:"status,omitempty"`
unknownFields protoimpl.UnknownFields
Status HealthCheckResponse_ServingStatus `protobuf:"varint,1,opt,name=status,proto3,enum=grpc.health.v1.HealthCheckResponse_ServingStatus" json:"status,omitempty"`
sizeCache protoimpl.SizeCache
}
func (x *HealthCheckResponse) Reset() {
@ -181,7 +180,7 @@ func (x *HealthCheckResponse) GetStatus() HealthCheckResponse_ServingStatus {
var File_grpc_health_v1_health_proto protoreflect.FileDescriptor
var file_grpc_health_v1_health_proto_rawDesc = []byte{
var file_grpc_health_v1_health_proto_rawDesc = string([]byte{
0x0a, 0x1b, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2f, 0x76, 0x31,
0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x67,
0x72, 0x70, 0x63, 0x2e, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x22, 0x2e, 0x0a,
@ -210,23 +209,24 @@ var file_grpc_health_v1_health_proto_rawDesc = []byte{
0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x72,
0x70, 0x63, 0x2e, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61,
0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x30, 0x01, 0x42, 0x61, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x68, 0x65,
0x30, 0x01, 0x42, 0x70, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x68, 0x65,
0x61, 0x6c, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50,
0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67,
0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x68,
0x65, 0x61, 0x6c, 0x74, 0x68, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x68, 0x65, 0x61, 0x6c, 0x74,
0x68, 0x5f, 0x76, 0x31, 0xaa, 0x02, 0x0e, 0x47, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x65, 0x61, 0x6c,
0x74, 0x68, 0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
0x68, 0x5f, 0x76, 0x31, 0xa2, 0x02, 0x0c, 0x47, 0x72, 0x70, 0x63, 0x48, 0x65, 0x61, 0x6c, 0x74,
0x68, 0x56, 0x31, 0xaa, 0x02, 0x0e, 0x47, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74,
0x68, 0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
})
var (
file_grpc_health_v1_health_proto_rawDescOnce sync.Once
file_grpc_health_v1_health_proto_rawDescData = file_grpc_health_v1_health_proto_rawDesc
file_grpc_health_v1_health_proto_rawDescData []byte
)
func file_grpc_health_v1_health_proto_rawDescGZIP() []byte {
file_grpc_health_v1_health_proto_rawDescOnce.Do(func() {
file_grpc_health_v1_health_proto_rawDescData = protoimpl.X.CompressGZIP(file_grpc_health_v1_health_proto_rawDescData)
file_grpc_health_v1_health_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_grpc_health_v1_health_proto_rawDesc), len(file_grpc_health_v1_health_proto_rawDesc)))
})
return file_grpc_health_v1_health_proto_rawDescData
}
@ -260,7 +260,7 @@ func file_grpc_health_v1_health_proto_init() {
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_grpc_health_v1_health_proto_rawDesc,
RawDescriptor: unsafe.Slice(unsafe.StringData(file_grpc_health_v1_health_proto_rawDesc), len(file_grpc_health_v1_health_proto_rawDesc)),
NumEnums: 1,
NumMessages: 2,
NumExtensions: 0,
@ -272,7 +272,6 @@ func file_grpc_health_v1_health_proto_init() {
MessageInfos: file_grpc_health_v1_health_proto_msgTypes,
}.Build()
File_grpc_health_v1_health_proto = out.File
file_grpc_health_v1_health_proto_rawDesc = nil
file_grpc_health_v1_health_proto_goTypes = nil
file_grpc_health_v1_health_proto_depIdxs = nil
}

View File

@ -109,8 +109,9 @@ func (gsb *Balancer) switchTo(builder balancer.Builder) (*balancerWrapper, error
return nil, errBalancerClosed
}
bw := &balancerWrapper{
builder: builder,
gsb: gsb,
ClientConn: gsb.cc,
builder: builder,
gsb: gsb,
lastState: balancer.State{
ConnectivityState: connectivity.Connecting,
Picker: base.NewErrPicker(balancer.ErrNoSubConnAvailable),
@ -293,6 +294,7 @@ func (gsb *Balancer) Close() {
// State updates from the wrapped balancer can result in invocation of the
// graceful switch logic.
type balancerWrapper struct {
balancer.ClientConn
balancer.Balancer
gsb *Balancer
builder balancer.Builder
@ -413,7 +415,3 @@ func (bw *balancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver
bw.gsb.mu.Unlock()
bw.gsb.cc.UpdateAddresses(sc, addrs)
}
func (bw *balancerWrapper) Target() string {
return bw.gsb.cc.Target()
}

View File

@ -56,7 +56,11 @@ var (
// XDSDualstackEndpointsEnabled is true if gRPC should read the
// "additional addresses" in the xDS endpoint resource.
// TODO: https://github.com/grpc/grpc-go/issues/7866 - Control this using
// an env variable when all LB policies handle endpoints.
XDSDualstackEndpointsEnabled = false
XDSDualstackEndpointsEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_DUALSTACK_ENDPOINTS", true)
// XDSSystemRootCertsEnabled is true when xDS enabled gRPC clients can use
// the system's default root certificates for TLS certificate validation.
// For more details, see:
// https://github.com/grpc/proposal/blob/master/A82-xds-system-root-certs.md.
XDSSystemRootCertsEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_SYSTEM_ROOT_CERTS", false)
)

View File

@ -1,32 +0,0 @@
/*
*
* Copyright 2022 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package grpcsync
import (
"sync"
)
// OnceFunc returns a function wrapping f which ensures f is only executed
// once even if the returned function is executed multiple times.
func OnceFunc(f func()) func() {
var once sync.Once
return func() {
once.Do(f)
}
}

View File

@ -64,6 +64,9 @@ var (
// gRPC server. An xDS-enabled server needs to know what type of credentials
// is configured on the underlying gRPC server. This is set by server.go.
GetServerCredentials any // func (*grpc.Server) credentials.TransportCredentials
// MetricsRecorderForServer returns the MetricsRecorderList derived from a
// server's stats handlers.
MetricsRecorderForServer any // func (*grpc.Server) estats.MetricsRecorder
// CanonicalString returns the canonical string of the code defined here:
// https://github.com/grpc/grpc/blob/master/doc/statuscodes.md.
//
@ -151,6 +154,20 @@ var (
// other features, including the CSDS service.
NewXDSResolverWithConfigForTesting any // func([]byte) (resolver.Builder, error)
// NewXDSResolverWithPoolForTesting creates a new xDS resolver builder
// using the provided xDS pool instead of creating a new one using the
// bootstrap configuration specified by the supported environment variables.
// The resolver.Builder is meant to be used in conjunction with the
// grpc.WithResolvers DialOption. The resolver.Builder does not take
// ownership of the provided xDS client and it is the responsibility of the
// caller to close the client when no longer required.
//
// Testing Only
//
// This function should ONLY be used for testing and may not work with some
// other features, including the CSDS service.
NewXDSResolverWithPoolForTesting any // func(*xdsclient.Pool) (resolver.Builder, error)
// NewXDSResolverWithClientForTesting creates a new xDS resolver builder
// using the provided xDS client instead of creating a new one using the
// bootstrap configuration specified by the supported environment variables.
@ -277,3 +294,9 @@ const RLSLoadBalancingPolicyName = "rls_experimental"
type EnforceSubConnEmbedding interface {
enforceSubConnEmbedding()
}
// EnforceClientConnEmbedding is used to enforce proper ClientConn implementation
// embedding.
type EnforceClientConnEmbedding interface {
enforceClientConnEmbedding()
}

View File

@ -0,0 +1,54 @@
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Package proxyattributes contains functions for getting and setting proxy
// attributes like the CONNECT address and user info.
package proxyattributes
import (
"net/url"
"google.golang.org/grpc/resolver"
)
type keyType string
const proxyOptionsKey = keyType("grpc.resolver.delegatingresolver.proxyOptions")
// Options holds the proxy connection details needed during the CONNECT
// handshake.
type Options struct {
User *url.Userinfo
ConnectAddr string
}
// Set returns a copy of addr with opts set in its attributes.
func Set(addr resolver.Address, opts Options) resolver.Address {
addr.Attributes = addr.Attributes.WithValue(proxyOptionsKey, opts)
return addr
}
// Get returns the Options for the proxy [resolver.Address] and a boolean
// value representing if the attribute is present or not. The returned data
// should not be mutated.
func Get(addr resolver.Address) (Options, bool) {
if a := addr.Attributes.Value(proxyOptionsKey); a != nil {
return a.(Options), true
}
return Options{}, false
}

View File

@ -0,0 +1,329 @@
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Package delegatingresolver implements a resolver capable of resolving both
// target URIs and proxy addresses.
package delegatingresolver
import (
"fmt"
"net/http"
"net/url"
"sync"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/proxyattributes"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/serviceconfig"
)
var (
logger = grpclog.Component("delegating-resolver")
// HTTPSProxyFromEnvironment will be overwritten in the tests
HTTPSProxyFromEnvironment = http.ProxyFromEnvironment
)
// delegatingResolver manages both target URI and proxy address resolution by
// delegating these tasks to separate child resolvers. Essentially, it acts as
// a intermediary between the gRPC ClientConn and the child resolvers.
//
// It implements the [resolver.Resolver] interface.
type delegatingResolver struct {
target resolver.Target // parsed target URI to be resolved
cc resolver.ClientConn // gRPC ClientConn
targetResolver resolver.Resolver // resolver for the target URI, based on its scheme
proxyResolver resolver.Resolver // resolver for the proxy URI; nil if no proxy is configured
proxyURL *url.URL // proxy URL, derived from proxy environment and target
mu sync.Mutex // protects all the fields below
targetResolverState *resolver.State // state of the target resolver
proxyAddrs []resolver.Address // resolved proxy addresses; empty if no proxy is configured
}
// nopResolver is a resolver that does nothing.
type nopResolver struct{}
func (nopResolver) ResolveNow(resolver.ResolveNowOptions) {}
func (nopResolver) Close() {}
// proxyURLForTarget determines the proxy URL for the given address based on
// the environment. It can return the following:
// - nil URL, nil error: No proxy is configured or the address is excluded
// using the `NO_PROXY` environment variable or if req.URL.Host is
// "localhost" (with or without // a port number)
// - nil URL, non-nil error: An error occurred while retrieving the proxy URL.
// - non-nil URL, nil error: A proxy is configured, and the proxy URL was
// retrieved successfully without any errors.
func proxyURLForTarget(address string) (*url.URL, error) {
req := &http.Request{URL: &url.URL{
Scheme: "https",
Host: address,
}}
return HTTPSProxyFromEnvironment(req)
}
// New creates a new delegating resolver that can create up to two child
// resolvers:
// - one to resolve the proxy address specified using the supported
// environment variables. This uses the registered resolver for the "dns"
// scheme.
// - one to resolve the target URI using the resolver specified by the scheme
// in the target URI or specified by the user using the WithResolvers dial
// option. As a special case, if the target URI's scheme is "dns" and a
// proxy is specified using the supported environment variables, the target
// URI's path portion is used as the resolved address unless target
// resolution is enabled using the dial option.
func New(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions, targetResolverBuilder resolver.Builder, targetResolutionEnabled bool) (resolver.Resolver, error) {
r := &delegatingResolver{
target: target,
cc: cc,
}
var err error
r.proxyURL, err = proxyURLForTarget(target.Endpoint())
if err != nil {
return nil, fmt.Errorf("delegating_resolver: failed to determine proxy URL for target %s: %v", target, err)
}
// proxy is not configured or proxy address excluded using `NO_PROXY` env
// var, so only target resolver is used.
if r.proxyURL == nil {
return targetResolverBuilder.Build(target, cc, opts)
}
if logger.V(2) {
logger.Infof("Proxy URL detected : %s", r.proxyURL)
}
// When the scheme is 'dns' and target resolution on client is not enabled,
// resolution should be handled by the proxy, not the client. Therefore, we
// bypass the target resolver and store the unresolved target address.
if target.URL.Scheme == "dns" && !targetResolutionEnabled {
state := resolver.State{
Addresses: []resolver.Address{{Addr: target.Endpoint()}},
Endpoints: []resolver.Endpoint{{Addresses: []resolver.Address{{Addr: target.Endpoint()}}}},
}
r.targetResolverState = &state
} else {
wcc := &wrappingClientConn{
stateListener: r.updateTargetResolverState,
parent: r,
}
if r.targetResolver, err = targetResolverBuilder.Build(target, wcc, opts); err != nil {
return nil, fmt.Errorf("delegating_resolver: unable to build the resolver for target %s: %v", target, err)
}
}
if r.proxyResolver, err = r.proxyURIResolver(opts); err != nil {
return nil, fmt.Errorf("delegating_resolver: failed to build resolver for proxy URL %q: %v", r.proxyURL, err)
}
if r.targetResolver == nil {
r.targetResolver = nopResolver{}
}
if r.proxyResolver == nil {
r.proxyResolver = nopResolver{}
}
return r, nil
}
// proxyURIResolver creates a resolver for resolving proxy URIs using the
// "dns" scheme. It adjusts the proxyURL to conform to the "dns:///" format and
// builds a resolver with a wrappingClientConn to capture resolved addresses.
func (r *delegatingResolver) proxyURIResolver(opts resolver.BuildOptions) (resolver.Resolver, error) {
proxyBuilder := resolver.Get("dns")
if proxyBuilder == nil {
panic("delegating_resolver: resolver for proxy not found for scheme dns")
}
url := *r.proxyURL
url.Scheme = "dns"
url.Path = "/" + r.proxyURL.Host
url.Host = "" // Clear the Host field to conform to the "dns:///" format
proxyTarget := resolver.Target{URL: url}
wcc := &wrappingClientConn{
stateListener: r.updateProxyResolverState,
parent: r,
}
return proxyBuilder.Build(proxyTarget, wcc, opts)
}
func (r *delegatingResolver) ResolveNow(o resolver.ResolveNowOptions) {
r.targetResolver.ResolveNow(o)
r.proxyResolver.ResolveNow(o)
}
func (r *delegatingResolver) Close() {
r.targetResolver.Close()
r.targetResolver = nil
r.proxyResolver.Close()
r.proxyResolver = nil
}
// updateClientConnStateLocked creates a list of combined addresses by
// pairing each proxy address with every target address. For each pair, it
// generates a new [resolver.Address] using the proxy address, and adding the
// target address as the attribute along with user info. It returns nil if
// either resolver has not sent update even once and returns the error from
// ClientConn update once both resolvers have sent update atleast once.
func (r *delegatingResolver) updateClientConnStateLocked() error {
if r.targetResolverState == nil || r.proxyAddrs == nil {
return nil
}
curState := *r.targetResolverState
// If multiple resolved proxy addresses are present, we send only the
// unresolved proxy host and let net.Dial handle the proxy host name
// resolution when creating the transport. Sending all resolved addresses
// would increase the number of addresses passed to the ClientConn and
// subsequently to load balancing (LB) policies like Round Robin, leading
// to additional TCP connections. However, if there's only one resolved
// proxy address, we send it directly, as it doesn't affect the address
// count returned by the target resolver and the address count sent to the
// ClientConn.
var proxyAddr resolver.Address
if len(r.proxyAddrs) == 1 {
proxyAddr = r.proxyAddrs[0]
} else {
proxyAddr = resolver.Address{Addr: r.proxyURL.Host}
}
var addresses []resolver.Address
for _, targetAddr := range (*r.targetResolverState).Addresses {
addresses = append(addresses, proxyattributes.Set(proxyAddr, proxyattributes.Options{
User: r.proxyURL.User,
ConnectAddr: targetAddr.Addr,
}))
}
// Create a list of combined endpoints by pairing all proxy endpoints
// with every target endpoint. Each time, it constructs a new
// [resolver.Endpoint] using the all addresses from all the proxy endpoint
// and the target addresses from one endpoint. The target address and user
// information from the proxy URL are added as attributes to the proxy
// address.The resulting list of addresses is then grouped into endpoints,
// covering all combinations of proxy and target endpoints.
var endpoints []resolver.Endpoint
for _, endpt := range (*r.targetResolverState).Endpoints {
var addrs []resolver.Address
for _, proxyAddr := range r.proxyAddrs {
for _, targetAddr := range endpt.Addresses {
addrs = append(addrs, proxyattributes.Set(proxyAddr, proxyattributes.Options{
User: r.proxyURL.User,
ConnectAddr: targetAddr.Addr,
}))
}
}
endpoints = append(endpoints, resolver.Endpoint{Addresses: addrs})
}
// Use the targetResolverState for its service config and attributes
// contents. The state update is only sent after both the target and proxy
// resolvers have sent their updates, and curState has been updated with
// the combined addresses.
curState.Addresses = addresses
curState.Endpoints = endpoints
return r.cc.UpdateState(curState)
}
// updateProxyResolverState updates the proxy resolver state by storing proxy
// addresses and endpoints, marking the resolver as ready, and triggering a
// state update if both proxy and target resolvers are ready. If the ClientConn
// returns a non-nil error, it calls `ResolveNow()` on the target resolver. It
// is a StateListener function of wrappingClientConn passed to the proxy resolver.
func (r *delegatingResolver) updateProxyResolverState(state resolver.State) error {
r.mu.Lock()
defer r.mu.Unlock()
if logger.V(2) {
logger.Infof("Addresses received from proxy resolver: %s", state.Addresses)
}
if len(state.Endpoints) > 0 {
// We expect exactly one address per endpoint because the proxy
// resolver uses "dns" resolution.
r.proxyAddrs = make([]resolver.Address, 0, len(state.Endpoints))
for _, endpoint := range state.Endpoints {
r.proxyAddrs = append(r.proxyAddrs, endpoint.Addresses...)
}
} else if state.Addresses != nil {
r.proxyAddrs = state.Addresses
} else {
r.proxyAddrs = []resolver.Address{} // ensure proxyAddrs is non-nil to indicate an update has been received
}
err := r.updateClientConnStateLocked()
// Another possible approach was to block until updates are received from
// both resolvers. But this is not used because calling `New()` triggers
// `Build()` for the first resolver, which calls `UpdateState()`. And the
// second resolver hasn't sent an update yet, so it would cause `New()` to
// block indefinitely.
if err != nil {
r.targetResolver.ResolveNow(resolver.ResolveNowOptions{})
}
return err
}
// updateTargetResolverState updates the target resolver state by storing target
// addresses, endpoints, and service config, marking the resolver as ready, and
// triggering a state update if both resolvers are ready. If the ClientConn
// returns a non-nil error, it calls `ResolveNow()` on the proxy resolver. It
// is a StateListener function of wrappingClientConn passed to the target resolver.
func (r *delegatingResolver) updateTargetResolverState(state resolver.State) error {
r.mu.Lock()
defer r.mu.Unlock()
if logger.V(2) {
logger.Infof("Addresses received from target resolver: %v", state.Addresses)
}
r.targetResolverState = &state
err := r.updateClientConnStateLocked()
if err != nil {
r.proxyResolver.ResolveNow(resolver.ResolveNowOptions{})
}
return nil
}
// wrappingClientConn serves as an intermediary between the parent ClientConn
// and the child resolvers created here. It implements the resolver.ClientConn
// interface and is passed in that capacity to the child resolvers.
type wrappingClientConn struct {
// Callback to deliver resolver state updates
stateListener func(state resolver.State) error
parent *delegatingResolver
}
// UpdateState receives resolver state updates and forwards them to the
// appropriate listener function (either for the proxy or target resolver).
func (wcc *wrappingClientConn) UpdateState(state resolver.State) error {
return wcc.stateListener(state)
}
// ReportError intercepts errors from the child resolvers and passes them to ClientConn.
func (wcc *wrappingClientConn) ReportError(err error) {
wcc.parent.cc.ReportError(err)
}
// NewAddress intercepts the new resolved address from the child resolvers and
// passes them to ClientConn.
func (wcc *wrappingClientConn) NewAddress(addrs []resolver.Address) {
wcc.UpdateState(resolver.State{Addresses: addrs})
}
// ParseServiceConfig parses the provided service config and returns an
// object that provides the parsed config.
func (wcc *wrappingClientConn) ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult {
return wcc.parent.cc.ParseServiceConfig(serviceConfigJSON)
}

View File

@ -43,6 +43,7 @@ import (
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/grpcutil"
imetadata "google.golang.org/grpc/internal/metadata"
"google.golang.org/grpc/internal/proxyattributes"
istatus "google.golang.org/grpc/internal/status"
isyscall "google.golang.org/grpc/internal/syscall"
"google.golang.org/grpc/internal/transport/networktype"
@ -153,7 +154,7 @@ type http2Client struct {
logger *grpclog.PrefixLogger
}
func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error), addr resolver.Address, useProxy bool, grpcUA string) (net.Conn, error) {
func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error), addr resolver.Address, grpcUA string) (net.Conn, error) {
address := addr.Addr
networkType, ok := networktype.Get(addr)
if fn != nil {
@ -177,8 +178,8 @@ func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error
if !ok {
networkType, address = parseDialTarget(address)
}
if networkType == "tcp" && useProxy {
return proxyDial(ctx, address, grpcUA)
if opts, present := proxyattributes.Get(addr); present {
return proxyDial(ctx, addr, grpcUA, opts)
}
return internal.NetDialerWithTCPKeepalive().DialContext(ctx, networkType, address)
}
@ -217,7 +218,7 @@ func NewHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
// address specific arbitrary data to reach custom dialers and credential handshakers.
connectCtx = icredentials.NewClientHandshakeInfoContext(connectCtx, credentials.ClientHandshakeInfo{Attributes: addr.Attributes})
conn, err := dial(connectCtx, opts.Dialer, addr, opts.UseProxy, opts.UserAgent)
conn, err := dial(connectCtx, opts.Dialer, addr, opts.UserAgent)
if err != nil {
if opts.FailOnNonTempDialError {
return nil, connectionErrorf(isTemporary(err), err, "transport: error while dialing: %v", err)

View File

@ -30,34 +30,16 @@ import (
"net/url"
"google.golang.org/grpc/internal"
"google.golang.org/grpc/internal/proxyattributes"
"google.golang.org/grpc/resolver"
)
const proxyAuthHeaderKey = "Proxy-Authorization"
var (
// The following variable will be overwritten in the tests.
httpProxyFromEnvironment = http.ProxyFromEnvironment
)
func mapAddress(address string) (*url.URL, error) {
req := &http.Request{
URL: &url.URL{
Scheme: "https",
Host: address,
},
}
url, err := httpProxyFromEnvironment(req)
if err != nil {
return nil, err
}
return url, nil
}
// To read a response from a net.Conn, http.ReadResponse() takes a bufio.Reader.
// It's possible that this reader reads more than what's need for the response and stores
// those bytes in the buffer.
// bufConn wraps the original net.Conn and the bufio.Reader to make sure we don't lose the
// bytes in the buffer.
// It's possible that this reader reads more than what's need for the response
// and stores those bytes in the buffer. bufConn wraps the original net.Conn
// and the bufio.Reader to make sure we don't lose the bytes in the buffer.
type bufConn struct {
net.Conn
r io.Reader
@ -72,7 +54,7 @@ func basicAuth(username, password string) string {
return base64.StdEncoding.EncodeToString([]byte(auth))
}
func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, backendAddr string, proxyURL *url.URL, grpcUA string) (_ net.Conn, err error) {
func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, grpcUA string, opts proxyattributes.Options) (_ net.Conn, err error) {
defer func() {
if err != nil {
conn.Close()
@ -81,15 +63,14 @@ func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, backendAddr stri
req := &http.Request{
Method: http.MethodConnect,
URL: &url.URL{Host: backendAddr},
URL: &url.URL{Host: opts.ConnectAddr},
Header: map[string][]string{"User-Agent": {grpcUA}},
}
if t := proxyURL.User; t != nil {
u := t.Username()
p, _ := t.Password()
if user := opts.User; user != nil {
u := user.Username()
p, _ := user.Password()
req.Header.Add(proxyAuthHeaderKey, "Basic "+basicAuth(u, p))
}
if err := sendHTTPRequest(ctx, req, conn); err != nil {
return nil, fmt.Errorf("failed to write the HTTP request: %v", err)
}
@ -117,28 +98,13 @@ func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, backendAddr stri
return conn, nil
}
// proxyDial dials, connecting to a proxy first if necessary. Checks if a proxy
// is necessary, dials, does the HTTP CONNECT handshake, and returns the
// connection.
func proxyDial(ctx context.Context, addr string, grpcUA string) (net.Conn, error) {
newAddr := addr
proxyURL, err := mapAddress(addr)
// proxyDial establishes a TCP connection to the specified address and performs an HTTP CONNECT handshake.
func proxyDial(ctx context.Context, addr resolver.Address, grpcUA string, opts proxyattributes.Options) (net.Conn, error) {
conn, err := internal.NetDialerWithTCPKeepalive().DialContext(ctx, "tcp", addr.Addr)
if err != nil {
return nil, err
}
if proxyURL != nil {
newAddr = proxyURL.Host
}
conn, err := internal.NetDialerWithTCPKeepalive().DialContext(ctx, "tcp", newAddr)
if err != nil {
return nil, err
}
if proxyURL == nil {
// proxy is disabled if proxyURL is nil.
return conn, err
}
return doHTTPConnectHandshake(ctx, conn, addr, proxyURL, grpcUA)
return doHTTPConnectHandshake(ctx, conn, grpcUA, opts)
}
func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error {

View File

@ -502,8 +502,6 @@ type ConnectOptions struct {
ChannelzParent *channelz.SubChannel
// MaxHeaderListSize sets the max (uncompressed) size of header list that is prepared to be received.
MaxHeaderListSize *uint32
// UseProxy specifies if a proxy should be used.
UseProxy bool
// The mem.BufferPool to use when reading/writing to the wire.
BufferPool mem.BufferPool
}

View File

@ -123,7 +123,7 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
if lastPickErr != nil {
errStr = "latest balancer error: " + lastPickErr.Error()
} else {
errStr = fmt.Sprintf("received context error while waiting for new LB policy update: %s", ctx.Err().Error())
errStr = fmt.Sprintf("%v while waiting for connections to become ready", ctx.Err())
}
switch ctx.Err() {
case context.DeadlineExceeded:

View File

@ -30,6 +30,7 @@ import (
"google.golang.org/grpc/attributes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/experimental/stats"
"google.golang.org/grpc/internal"
"google.golang.org/grpc/serviceconfig"
)
@ -175,6 +176,8 @@ type BuildOptions struct {
// Authority is the effective authority of the clientconn for which the
// resolver is built.
Authority string
// MetricsRecorder is the metrics recorder to do recording.
MetricsRecorder stats.MetricsRecorder
}
// An Endpoint is one network endpoint, or server, which may have multiple

View File

@ -26,6 +26,7 @@ import (
"google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/pretty"
"google.golang.org/grpc/internal/resolver/delegatingresolver"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/serviceconfig"
)
@ -76,9 +77,19 @@ func (ccr *ccResolverWrapper) start() error {
CredsBundle: ccr.cc.dopts.copts.CredsBundle,
Dialer: ccr.cc.dopts.copts.Dialer,
Authority: ccr.cc.authority,
MetricsRecorder: ccr.cc.metricsRecorderList,
}
var err error
ccr.resolver, err = ccr.cc.resolverBuilder.Build(ccr.cc.parsedTarget, ccr, opts)
// The delegating resolver is used unless:
// - A custom dialer is provided via WithContextDialer dialoption or
// - Proxy usage is disabled through WithNoProxy dialoption.
// In these cases, the resolver is built based on the scheme of target,
// using the appropriate resolver builder.
if ccr.cc.dopts.copts.Dialer != nil || !ccr.cc.dopts.useProxy {
ccr.resolver, err = ccr.cc.resolverBuilder.Build(ccr.cc.parsedTarget, ccr, opts)
} else {
ccr.resolver, err = delegatingresolver.New(ccr.cc.parsedTarget, ccr, opts, ccr.cc.resolverBuilder, ccr.cc.dopts.enableLocalDNSResolution)
}
errCh <- err
})
return <-errCh

View File

@ -151,7 +151,7 @@ func (d *gzipDecompressor) Type() string {
// callInfo contains all related configuration and information about an RPC.
type callInfo struct {
compressorType string
compressorName string
failFast bool
maxReceiveMessageSize *int
maxSendMessageSize *int
@ -222,7 +222,7 @@ type HeaderCallOption struct {
func (o HeaderCallOption) before(*callInfo) error { return nil }
func (o HeaderCallOption) after(_ *callInfo, attempt *csAttempt) {
*o.HeaderAddr, _ = attempt.s.Header()
*o.HeaderAddr, _ = attempt.transportStream.Header()
}
// Trailer returns a CallOptions that retrieves the trailer metadata
@ -244,7 +244,7 @@ type TrailerCallOption struct {
func (o TrailerCallOption) before(*callInfo) error { return nil }
func (o TrailerCallOption) after(_ *callInfo, attempt *csAttempt) {
*o.TrailerAddr = attempt.s.Trailer()
*o.TrailerAddr = attempt.transportStream.Trailer()
}
// Peer returns a CallOption that retrieves peer information for a unary RPC.
@ -266,7 +266,7 @@ type PeerCallOption struct {
func (o PeerCallOption) before(*callInfo) error { return nil }
func (o PeerCallOption) after(_ *callInfo, attempt *csAttempt) {
if x, ok := peer.FromContext(attempt.s.Context()); ok {
if x, ok := peer.FromContext(attempt.transportStream.Context()); ok {
*o.PeerAddr = *x
}
}
@ -435,7 +435,7 @@ type CompressorCallOption struct {
}
func (o CompressorCallOption) before(c *callInfo) error {
c.compressorType = o.CompressorType
c.compressorName = o.CompressorType
return nil
}
func (o CompressorCallOption) after(*callInfo, *csAttempt) {}
@ -692,9 +692,9 @@ func encode(c baseCodec, msg any) (mem.BufferSlice, error) {
if err != nil {
return nil, status.Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error())
}
if uint(b.Len()) > math.MaxUint32 {
if bufSize := uint(b.Len()); bufSize > math.MaxUint32 {
b.Free()
return nil, status.Errorf(codes.ResourceExhausted, "grpc: message too large (%d bytes)", len(b))
return nil, status.Errorf(codes.ResourceExhausted, "grpc: message too large (%d bytes)", bufSize)
}
return b, nil
}
@ -828,30 +828,13 @@ func recvAndDecompress(p *parser, s recvCompressor, dc Decompressor, maxReceiveM
return nil, st.Err()
}
var size int
if pf.isCompressed() {
defer compressed.Free()
// To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor,
// use this decompressor as the default.
if dc != nil {
var uncompressedBuf []byte
uncompressedBuf, err = dc.Do(compressed.Reader())
if err == nil {
out = mem.BufferSlice{mem.SliceBuffer(uncompressedBuf)}
}
size = len(uncompressedBuf)
} else {
out, size, err = decompress(compressor, compressed, maxReceiveMessageSize, p.bufferPool)
}
out, err = decompress(compressor, compressed, dc, maxReceiveMessageSize, p.bufferPool)
if err != nil {
return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err)
}
if size > maxReceiveMessageSize {
out.Free()
// TODO: Revisit the error code. Currently keep it consistent with java
// implementation.
return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize)
return nil, err
}
} else {
out = compressed
@ -866,20 +849,46 @@ func recvAndDecompress(p *parser, s recvCompressor, dc Decompressor, maxReceiveM
return out, nil
}
// Using compressor, decompress d, returning data and size.
// Optionally, if data will be over maxReceiveMessageSize, just return the size.
func decompress(compressor encoding.Compressor, d mem.BufferSlice, maxReceiveMessageSize int, pool mem.BufferPool) (mem.BufferSlice, int, error) {
dcReader, err := compressor.Decompress(d.Reader())
if err != nil {
return nil, 0, err
// decompress processes the given data by decompressing it using either a custom decompressor or a standard compressor.
// If a custom decompressor is provided, it takes precedence. The function validates that the decompressed data
// does not exceed the specified maximum size and returns an error if this limit is exceeded.
// On success, it returns the decompressed data. Otherwise, it returns an error if decompression fails or the data exceeds the size limit.
func decompress(compressor encoding.Compressor, d mem.BufferSlice, dc Decompressor, maxReceiveMessageSize int, pool mem.BufferPool) (mem.BufferSlice, error) {
if dc != nil {
uncompressed, err := dc.Do(d.Reader())
if err != nil {
return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err)
}
if len(uncompressed) > maxReceiveMessageSize {
return nil, status.Errorf(codes.ResourceExhausted, "grpc: message after decompression larger than max (%d vs. %d)", len(uncompressed), maxReceiveMessageSize)
}
return mem.BufferSlice{mem.SliceBuffer(uncompressed)}, nil
}
if compressor != nil {
dcReader, err := compressor.Decompress(d.Reader())
if err != nil {
return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the message: %v", err)
}
out, err := mem.ReadAll(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1), pool)
if err != nil {
out.Free()
return nil, 0, err
out, err := mem.ReadAll(io.LimitReader(dcReader, int64(maxReceiveMessageSize)), pool)
if err != nil {
out.Free()
return nil, status.Errorf(codes.Internal, "grpc: failed to read decompressed data: %v", err)
}
if out.Len() == maxReceiveMessageSize && !atEOF(dcReader) {
out.Free()
return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max %d", maxReceiveMessageSize)
}
return out, nil
}
return out, out.Len(), nil
return nil, status.Errorf(codes.Internal, "grpc: no decompressor available for compressed payload")
}
// atEOF reads data from r and returns true if zero bytes could be read and r.Read returns EOF.
func atEOF(dcReader io.Reader) bool {
n, err := dcReader.Read(make([]byte, 1))
return n == 0 && err == io.EOF
}
type recvCompressor interface {

View File

@ -37,12 +37,14 @@ import (
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/encoding"
"google.golang.org/grpc/encoding/proto"
estats "google.golang.org/grpc/experimental/stats"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal"
"google.golang.org/grpc/internal/binarylog"
"google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/grpcutil"
istats "google.golang.org/grpc/internal/stats"
"google.golang.org/grpc/internal/transport"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/mem"
@ -82,6 +84,9 @@ func init() {
internal.BinaryLogger = binaryLogger
internal.JoinServerOptions = newJoinServerOption
internal.BufferPool = bufferPool
internal.MetricsRecorderForServer = func(srv *Server) estats.MetricsRecorder {
return istats.NewMetricsRecorderList(srv.opts.statsHandlers)
}
}
var statusOK = status.New(codes.OK, "")
@ -643,7 +648,7 @@ func (s *Server) serverWorker() {
// connections to reduce the time spent overall on runtime.morestack.
func (s *Server) initServerWorkers() {
s.serverWorkerChannel = make(chan func())
s.serverWorkerChannelClose = grpcsync.OnceFunc(func() {
s.serverWorkerChannelClose = sync.OnceFunc(func() {
close(s.serverWorkerChannel)
})
for i := uint32(0); i < s.opts.numServerWorkers; i++ {
@ -1645,10 +1650,10 @@ func (s *Server) processStreamingRPC(ctx context.Context, stream *transport.Serv
// If dc is set and matches the stream's compression, use it. Otherwise, try
// to find a matching registered compressor for decomp.
if rc := stream.RecvCompress(); s.opts.dc != nil && s.opts.dc.Type() == rc {
ss.dc = s.opts.dc
ss.decompressorV0 = s.opts.dc
} else if rc != "" && rc != encoding.Identity {
ss.decomp = encoding.GetCompressor(rc)
if ss.decomp == nil {
ss.decompressorV1 = encoding.GetCompressor(rc)
if ss.decompressorV1 == nil {
st := status.Newf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", rc)
ss.s.WriteStatus(st)
return st.Err()
@ -1660,12 +1665,12 @@ func (s *Server) processStreamingRPC(ctx context.Context, stream *transport.Serv
//
// NOTE: this needs to be ahead of all handling, https://github.com/grpc/grpc-go/issues/686.
if s.opts.cp != nil {
ss.cp = s.opts.cp
ss.compressorV0 = s.opts.cp
ss.sendCompressorName = s.opts.cp.Type()
} else if rc := stream.RecvCompress(); rc != "" && rc != encoding.Identity {
// Legacy compressor not specified; attempt to respond with same encoding.
ss.comp = encoding.GetCompressor(rc)
if ss.comp != nil {
ss.compressorV1 = encoding.GetCompressor(rc)
if ss.compressorV1 != nil {
ss.sendCompressorName = rc
}
}
@ -1676,7 +1681,7 @@ func (s *Server) processStreamingRPC(ctx context.Context, stream *transport.Serv
}
}
ss.ctx = newContextWithRPCInfo(ss.ctx, false, ss.codec, ss.cp, ss.comp)
ss.ctx = newContextWithRPCInfo(ss.ctx, false, ss.codec, ss.compressorV0, ss.compressorV1)
if trInfo != nil {
trInfo.tr.LazyLog(&trInfo.firstLine, false)
@ -1930,7 +1935,7 @@ func (s *Server) stop(graceful bool) {
s.conns = nil
if s.opts.numServerWorkers > 0 {
// Closing the channel (only once, via grpcsync.OnceFunc) after all the
// Closing the channel (only once, via sync.OnceFunc) after all the
// connections have been closed above ensures that there are no
// goroutines executing the callback passed to st.HandleStreams (where
// the channel is written to).

View File

@ -258,9 +258,9 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
}
func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, mc serviceconfig.MethodConfig, onCommit, doneFunc func(), opts ...CallOption) (_ iresolver.ClientStream, err error) {
c := defaultCallInfo()
callInfo := defaultCallInfo()
if mc.WaitForReady != nil {
c.failFast = !*mc.WaitForReady
callInfo.failFast = !*mc.WaitForReady
}
// Possible context leak:
@ -281,20 +281,20 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client
}()
for _, o := range opts {
if err := o.before(c); err != nil {
if err := o.before(callInfo); err != nil {
return nil, toRPCErr(err)
}
}
c.maxSendMessageSize = getMaxSize(mc.MaxReqSize, c.maxSendMessageSize, defaultClientMaxSendMessageSize)
c.maxReceiveMessageSize = getMaxSize(mc.MaxRespSize, c.maxReceiveMessageSize, defaultClientMaxReceiveMessageSize)
if err := setCallInfoCodec(c); err != nil {
callInfo.maxSendMessageSize = getMaxSize(mc.MaxReqSize, callInfo.maxSendMessageSize, defaultClientMaxSendMessageSize)
callInfo.maxReceiveMessageSize = getMaxSize(mc.MaxRespSize, callInfo.maxReceiveMessageSize, defaultClientMaxReceiveMessageSize)
if err := setCallInfoCodec(callInfo); err != nil {
return nil, err
}
callHdr := &transport.CallHdr{
Host: cc.authority,
Method: method,
ContentSubtype: c.contentSubtype,
ContentSubtype: callInfo.contentSubtype,
DoneFunc: doneFunc,
}
@ -302,22 +302,22 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client
// set. In that case, also find the compressor from the encoding package.
// Otherwise, use the compressor configured by the WithCompressor DialOption,
// if set.
var cp Compressor
var comp encoding.Compressor
if ct := c.compressorType; ct != "" {
var compressorV0 Compressor
var compressorV1 encoding.Compressor
if ct := callInfo.compressorName; ct != "" {
callHdr.SendCompress = ct
if ct != encoding.Identity {
comp = encoding.GetCompressor(ct)
if comp == nil {
compressorV1 = encoding.GetCompressor(ct)
if compressorV1 == nil {
return nil, status.Errorf(codes.Internal, "grpc: Compressor is not installed for requested grpc-encoding %q", ct)
}
}
} else if cc.dopts.cp != nil {
callHdr.SendCompress = cc.dopts.cp.Type()
cp = cc.dopts.cp
} else if cc.dopts.compressorV0 != nil {
callHdr.SendCompress = cc.dopts.compressorV0.Type()
compressorV0 = cc.dopts.compressorV0
}
if c.creds != nil {
callHdr.Creds = c.creds
if callInfo.creds != nil {
callHdr.Creds = callInfo.creds
}
cs := &clientStream{
@ -325,12 +325,12 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client
ctx: ctx,
methodConfig: &mc,
opts: opts,
callInfo: c,
callInfo: callInfo,
cc: cc,
desc: desc,
codec: c.codec,
cp: cp,
comp: comp,
codec: callInfo.codec,
compressorV0: compressorV0,
compressorV1: compressorV1,
cancel: cancel,
firstAttempt: true,
onCommit: onCommit,
@ -412,7 +412,7 @@ func (cs *clientStream) newAttemptLocked(isTransparent bool) (*csAttempt, error)
return nil, ErrClientConnClosing
}
ctx := newContextWithRPCInfo(cs.ctx, cs.callInfo.failFast, cs.callInfo.codec, cs.cp, cs.comp)
ctx := newContextWithRPCInfo(cs.ctx, cs.callInfo.failFast, cs.callInfo.codec, cs.compressorV0, cs.compressorV1)
method := cs.callHdr.Method
var beginTime time.Time
shs := cs.cc.dopts.copts.StatsHandlers
@ -454,12 +454,12 @@ func (cs *clientStream) newAttemptLocked(isTransparent bool) (*csAttempt, error)
}
return &csAttempt{
ctx: ctx,
beginTime: beginTime,
cs: cs,
dc: cs.cc.dopts.dc,
statsHandlers: shs,
trInfo: trInfo,
ctx: ctx,
beginTime: beginTime,
cs: cs,
decompressorV0: cs.cc.dopts.dc,
statsHandlers: shs,
trInfo: trInfo,
}, nil
}
@ -467,7 +467,7 @@ func (a *csAttempt) getTransport() error {
cs := a.cs
var err error
a.t, a.pickResult, err = cs.cc.getTransport(a.ctx, cs.callInfo.failFast, cs.callHdr.Method)
a.transport, a.pickResult, err = cs.cc.getTransport(a.ctx, cs.callInfo.failFast, cs.callHdr.Method)
if err != nil {
if de, ok := err.(dropError); ok {
err = de.error
@ -476,7 +476,7 @@ func (a *csAttempt) getTransport() error {
return err
}
if a.trInfo != nil {
a.trInfo.firstLine.SetRemoteAddr(a.t.RemoteAddr())
a.trInfo.firstLine.SetRemoteAddr(a.transport.RemoteAddr())
}
return nil
}
@ -503,7 +503,7 @@ func (a *csAttempt) newStream() error {
a.ctx = metadata.NewOutgoingContext(a.ctx, md)
}
s, err := a.t.NewStream(a.ctx, cs.callHdr)
s, err := a.transport.NewStream(a.ctx, cs.callHdr)
if err != nil {
nse, ok := err.(*transport.NewStreamError)
if !ok {
@ -518,9 +518,9 @@ func (a *csAttempt) newStream() error {
// Unwrap and convert error.
return toRPCErr(nse.Err)
}
a.s = s
a.transportStream = s
a.ctx = s.Context()
a.p = &parser{r: s, bufferPool: a.cs.cc.dopts.copts.BufferPool}
a.parser = &parser{r: s, bufferPool: a.cs.cc.dopts.copts.BufferPool}
return nil
}
@ -532,9 +532,9 @@ type clientStream struct {
cc *ClientConn
desc *StreamDesc
codec baseCodec
cp Compressor
comp encoding.Compressor
codec baseCodec
compressorV0 Compressor
compressorV1 encoding.Compressor
cancel context.CancelFunc // cancels all attempts
@ -583,17 +583,17 @@ type replayOp struct {
// csAttempt implements a single transport stream attempt within a
// clientStream.
type csAttempt struct {
ctx context.Context
cs *clientStream
t transport.ClientTransport
s *transport.ClientStream
p *parser
pickResult balancer.PickResult
ctx context.Context
cs *clientStream
transport transport.ClientTransport
transportStream *transport.ClientStream
parser *parser
pickResult balancer.PickResult
finished bool
dc Decompressor
decomp encoding.Compressor
decompSet bool
finished bool
decompressorV0 Decompressor
decompressorV1 encoding.Compressor
decompressorSet bool
mu sync.Mutex // guards trInfo.tr
// trInfo may be nil (if EnableTracing is false).
@ -639,14 +639,14 @@ func (a *csAttempt) shouldRetry(err error) (bool, error) {
// RPC is finished or committed or was dropped by the picker; cannot retry.
return false, err
}
if a.s == nil && a.allowTransparentRetry {
if a.transportStream == nil && a.allowTransparentRetry {
return true, nil
}
// Wait for the trailers.
unprocessed := false
if a.s != nil {
<-a.s.Done()
unprocessed = a.s.Unprocessed()
if a.transportStream != nil {
<-a.transportStream.Done()
unprocessed = a.transportStream.Unprocessed()
}
if cs.firstAttempt && unprocessed {
// First attempt, stream unprocessed: transparently retry.
@ -658,14 +658,14 @@ func (a *csAttempt) shouldRetry(err error) (bool, error) {
pushback := 0
hasPushback := false
if a.s != nil {
if !a.s.TrailersOnly() {
if a.transportStream != nil {
if !a.transportStream.TrailersOnly() {
return false, err
}
// TODO(retry): Move down if the spec changes to not check server pushback
// before considering this a failure for throttling.
sps := a.s.Trailer()["grpc-retry-pushback-ms"]
sps := a.transportStream.Trailer()["grpc-retry-pushback-ms"]
if len(sps) == 1 {
var e error
if pushback, e = strconv.Atoi(sps[0]); e != nil || pushback < 0 {
@ -682,8 +682,8 @@ func (a *csAttempt) shouldRetry(err error) (bool, error) {
}
var code codes.Code
if a.s != nil {
code = a.s.Status().Code()
if a.transportStream != nil {
code = a.transportStream.Status().Code()
} else {
code = status.Code(err)
}
@ -756,8 +756,8 @@ func (cs *clientStream) Context() context.Context {
cs.commitAttempt()
// No need to lock before using attempt, since we know it is committed and
// cannot change.
if cs.attempt.s != nil {
return cs.attempt.s.Context()
if cs.attempt.transportStream != nil {
return cs.attempt.transportStream.Context()
}
return cs.ctx
}
@ -794,9 +794,9 @@ func (cs *clientStream) withRetry(op func(a *csAttempt) error, onSuccess func())
continue
}
if err == io.EOF {
<-a.s.Done()
<-a.transportStream.Done()
}
if err == nil || (err == io.EOF && a.s.Status().Code() == codes.OK) {
if err == nil || (err == io.EOF && a.transportStream.Status().Code() == codes.OK) {
onSuccess()
cs.mu.Unlock()
return err
@ -812,7 +812,7 @@ func (cs *clientStream) Header() (metadata.MD, error) {
var m metadata.MD
err := cs.withRetry(func(a *csAttempt) error {
var err error
m, err = a.s.Header()
m, err = a.transportStream.Header()
return toRPCErr(err)
}, cs.commitAttemptLocked)
@ -856,10 +856,10 @@ func (cs *clientStream) Trailer() metadata.MD {
// directions -- it will prevent races and should not meaningfully impact
// performance.
cs.commitAttempt()
if cs.attempt.s == nil {
if cs.attempt.transportStream == nil {
return nil
}
return cs.attempt.s.Trailer()
return cs.attempt.transportStream.Trailer()
}
func (cs *clientStream) replayBufferLocked(attempt *csAttempt) error {
@ -904,7 +904,7 @@ func (cs *clientStream) SendMsg(m any) (err error) {
}
// load hdr, payload, data
hdr, data, payload, pf, err := prepareMsg(m, cs.codec, cs.cp, cs.comp, cs.cc.dopts.copts.BufferPool)
hdr, data, payload, pf, err := prepareMsg(m, cs.codec, cs.compressorV0, cs.compressorV1, cs.cc.dopts.copts.BufferPool)
if err != nil {
return err
}
@ -992,7 +992,7 @@ func (cs *clientStream) CloseSend() error {
}
cs.sentLast = true
op := func(a *csAttempt) error {
a.s.Write(nil, nil, &transport.WriteOptions{Last: true})
a.transportStream.Write(nil, nil, &transport.WriteOptions{Last: true})
// Always return nil; io.EOF is the only error that might make sense
// instead, but there is no need to signal the client to call RecvMsg
// as the only use left for the stream after CloseSend is to call
@ -1030,7 +1030,7 @@ func (cs *clientStream) finish(err error) {
if cs.attempt != nil {
cs.attempt.finish(err)
// after functions all rely upon having a stream.
if cs.attempt.s != nil {
if cs.attempt.transportStream != nil {
for _, o := range cs.opts {
o.after(cs.callInfo, cs.attempt)
}
@ -1084,7 +1084,7 @@ func (a *csAttempt) sendMsg(m any, hdr []byte, payld mem.BufferSlice, dataLength
}
a.mu.Unlock()
}
if err := a.s.Write(hdr, payld, &transport.WriteOptions{Last: !cs.desc.ClientStreams}); err != nil {
if err := a.transportStream.Write(hdr, payld, &transport.WriteOptions{Last: !cs.desc.ClientStreams}); err != nil {
if !cs.desc.ClientStreams {
// For non-client-streaming RPCs, we return nil instead of EOF on error
// because the generated code requires it. finish is not called; RecvMsg()
@ -1108,25 +1108,25 @@ func (a *csAttempt) recvMsg(m any, payInfo *payloadInfo) (err error) {
defer payInfo.free()
}
if !a.decompSet {
if !a.decompressorSet {
// Block until we receive headers containing received message encoding.
if ct := a.s.RecvCompress(); ct != "" && ct != encoding.Identity {
if a.dc == nil || a.dc.Type() != ct {
if ct := a.transportStream.RecvCompress(); ct != "" && ct != encoding.Identity {
if a.decompressorV0 == nil || a.decompressorV0.Type() != ct {
// No configured decompressor, or it does not match the incoming
// message encoding; attempt to find a registered compressor that does.
a.dc = nil
a.decomp = encoding.GetCompressor(ct)
a.decompressorV0 = nil
a.decompressorV1 = encoding.GetCompressor(ct)
}
} else {
// No compression is used; disable our decompressor.
a.dc = nil
a.decompressorV0 = nil
}
// Only initialize this state once per stream.
a.decompSet = true
a.decompressorSet = true
}
if err := recv(a.p, cs.codec, a.s, a.dc, m, *cs.callInfo.maxReceiveMessageSize, payInfo, a.decomp, false); err != nil {
if err := recv(a.parser, cs.codec, a.transportStream, a.decompressorV0, m, *cs.callInfo.maxReceiveMessageSize, payInfo, a.decompressorV1, false); err != nil {
if err == io.EOF {
if statusErr := a.s.Status().Err(); statusErr != nil {
if statusErr := a.transportStream.Status().Err(); statusErr != nil {
return statusErr
}
return io.EOF // indicates successful end of stream.
@ -1157,8 +1157,8 @@ func (a *csAttempt) recvMsg(m any, payInfo *payloadInfo) (err error) {
}
// Special handling for non-server-stream rpcs.
// This recv expects EOF or errors, so we don't collect inPayload.
if err := recv(a.p, cs.codec, a.s, a.dc, m, *cs.callInfo.maxReceiveMessageSize, nil, a.decomp, false); err == io.EOF {
return a.s.Status().Err() // non-server streaming Recv returns nil on success
if err := recv(a.parser, cs.codec, a.transportStream, a.decompressorV0, m, *cs.callInfo.maxReceiveMessageSize, nil, a.decompressorV1, false); err == io.EOF {
return a.transportStream.Status().Err() // non-server streaming Recv returns nil on success
} else if err != nil {
return toRPCErr(err)
}
@ -1177,20 +1177,20 @@ func (a *csAttempt) finish(err error) {
err = nil
}
var tr metadata.MD
if a.s != nil {
a.s.Close(err)
tr = a.s.Trailer()
if a.transportStream != nil {
a.transportStream.Close(err)
tr = a.transportStream.Trailer()
}
if a.pickResult.Done != nil {
br := false
if a.s != nil {
br = a.s.BytesReceived()
if a.transportStream != nil {
br = a.transportStream.BytesReceived()
}
a.pickResult.Done(balancer.DoneInfo{
Err: err,
Trailer: tr,
BytesSent: a.s != nil,
BytesSent: a.transportStream != nil,
BytesReceived: br,
ServerLoad: balancerload.Parse(tr),
})
@ -1272,7 +1272,7 @@ func newNonRetryClientStream(ctx context.Context, desc *StreamDesc, method strin
// if set.
var cp Compressor
var comp encoding.Compressor
if ct := c.compressorType; ct != "" {
if ct := c.compressorName; ct != "" {
callHdr.SendCompress = ct
if ct != encoding.Identity {
comp = encoding.GetCompressor(ct)
@ -1280,9 +1280,9 @@ func newNonRetryClientStream(ctx context.Context, desc *StreamDesc, method strin
return nil, status.Errorf(codes.Internal, "grpc: Compressor is not installed for requested grpc-encoding %q", ct)
}
}
} else if ac.cc.dopts.cp != nil {
callHdr.SendCompress = ac.cc.dopts.cp.Type()
cp = ac.cc.dopts.cp
} else if ac.cc.dopts.compressorV0 != nil {
callHdr.SendCompress = ac.cc.dopts.compressorV0.Type()
cp = ac.cc.dopts.compressorV0
}
if c.creds != nil {
callHdr.Creds = c.creds
@ -1290,26 +1290,26 @@ func newNonRetryClientStream(ctx context.Context, desc *StreamDesc, method strin
// Use a special addrConnStream to avoid retry.
as := &addrConnStream{
callHdr: callHdr,
ac: ac,
ctx: ctx,
cancel: cancel,
opts: opts,
callInfo: c,
desc: desc,
codec: c.codec,
cp: cp,
comp: comp,
t: t,
callHdr: callHdr,
ac: ac,
ctx: ctx,
cancel: cancel,
opts: opts,
callInfo: c,
desc: desc,
codec: c.codec,
sendCompressorV0: cp,
sendCompressorV1: comp,
transport: t,
}
s, err := as.t.NewStream(as.ctx, as.callHdr)
s, err := as.transport.NewStream(as.ctx, as.callHdr)
if err != nil {
err = toRPCErr(err)
return nil, err
}
as.s = s
as.p = &parser{r: s, bufferPool: ac.dopts.copts.BufferPool}
as.transportStream = s
as.parser = &parser{r: s, bufferPool: ac.dopts.copts.BufferPool}
ac.incrCallsStarted()
if desc != unaryStreamDesc {
// Listen on stream context to cleanup when the stream context is
@ -1335,29 +1335,31 @@ func newNonRetryClientStream(ctx context.Context, desc *StreamDesc, method strin
}
type addrConnStream struct {
s *transport.ClientStream
ac *addrConn
callHdr *transport.CallHdr
cancel context.CancelFunc
opts []CallOption
callInfo *callInfo
t transport.ClientTransport
ctx context.Context
sentLast bool
desc *StreamDesc
codec baseCodec
cp Compressor
comp encoding.Compressor
decompSet bool
dc Decompressor
decomp encoding.Compressor
p *parser
mu sync.Mutex
finished bool
transportStream *transport.ClientStream
ac *addrConn
callHdr *transport.CallHdr
cancel context.CancelFunc
opts []CallOption
callInfo *callInfo
transport transport.ClientTransport
ctx context.Context
sentLast bool
desc *StreamDesc
codec baseCodec
sendCompressorV0 Compressor
sendCompressorV1 encoding.Compressor
decompressorSet bool
decompressorV0 Decompressor
decompressorV1 encoding.Compressor
parser *parser
// mu guards finished and is held for the entire finish method.
mu sync.Mutex
finished bool
}
func (as *addrConnStream) Header() (metadata.MD, error) {
m, err := as.s.Header()
m, err := as.transportStream.Header()
if err != nil {
as.finish(toRPCErr(err))
}
@ -1365,7 +1367,7 @@ func (as *addrConnStream) Header() (metadata.MD, error) {
}
func (as *addrConnStream) Trailer() metadata.MD {
return as.s.Trailer()
return as.transportStream.Trailer()
}
func (as *addrConnStream) CloseSend() error {
@ -1375,7 +1377,7 @@ func (as *addrConnStream) CloseSend() error {
}
as.sentLast = true
as.s.Write(nil, nil, &transport.WriteOptions{Last: true})
as.transportStream.Write(nil, nil, &transport.WriteOptions{Last: true})
// Always return nil; io.EOF is the only error that might make sense
// instead, but there is no need to signal the client to call RecvMsg
// as the only use left for the stream after CloseSend is to call
@ -1384,7 +1386,7 @@ func (as *addrConnStream) CloseSend() error {
}
func (as *addrConnStream) Context() context.Context {
return as.s.Context()
return as.transportStream.Context()
}
func (as *addrConnStream) SendMsg(m any) (err error) {
@ -1406,7 +1408,7 @@ func (as *addrConnStream) SendMsg(m any) (err error) {
}
// load hdr, payload, data
hdr, data, payload, pf, err := prepareMsg(m, as.codec, as.cp, as.comp, as.ac.dopts.copts.BufferPool)
hdr, data, payload, pf, err := prepareMsg(m, as.codec, as.sendCompressorV0, as.sendCompressorV1, as.ac.dopts.copts.BufferPool)
if err != nil {
return err
}
@ -1425,7 +1427,7 @@ func (as *addrConnStream) SendMsg(m any) (err error) {
return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", payload.Len(), *as.callInfo.maxSendMessageSize)
}
if err := as.s.Write(hdr, payload, &transport.WriteOptions{Last: !as.desc.ClientStreams}); err != nil {
if err := as.transportStream.Write(hdr, payload, &transport.WriteOptions{Last: !as.desc.ClientStreams}); err != nil {
if !as.desc.ClientStreams {
// For non-client-streaming RPCs, we return nil instead of EOF on error
// because the generated code requires it. finish is not called; RecvMsg()
@ -1446,25 +1448,25 @@ func (as *addrConnStream) RecvMsg(m any) (err error) {
}
}()
if !as.decompSet {
if !as.decompressorSet {
// Block until we receive headers containing received message encoding.
if ct := as.s.RecvCompress(); ct != "" && ct != encoding.Identity {
if as.dc == nil || as.dc.Type() != ct {
if ct := as.transportStream.RecvCompress(); ct != "" && ct != encoding.Identity {
if as.decompressorV0 == nil || as.decompressorV0.Type() != ct {
// No configured decompressor, or it does not match the incoming
// message encoding; attempt to find a registered compressor that does.
as.dc = nil
as.decomp = encoding.GetCompressor(ct)
as.decompressorV0 = nil
as.decompressorV1 = encoding.GetCompressor(ct)
}
} else {
// No compression is used; disable our decompressor.
as.dc = nil
as.decompressorV0 = nil
}
// Only initialize this state once per stream.
as.decompSet = true
as.decompressorSet = true
}
if err := recv(as.p, as.codec, as.s, as.dc, m, *as.callInfo.maxReceiveMessageSize, nil, as.decomp, false); err != nil {
if err := recv(as.parser, as.codec, as.transportStream, as.decompressorV0, m, *as.callInfo.maxReceiveMessageSize, nil, as.decompressorV1, false); err != nil {
if err == io.EOF {
if statusErr := as.s.Status().Err(); statusErr != nil {
if statusErr := as.transportStream.Status().Err(); statusErr != nil {
return statusErr
}
return io.EOF // indicates successful end of stream.
@ -1479,8 +1481,8 @@ func (as *addrConnStream) RecvMsg(m any) (err error) {
// Special handling for non-server-stream rpcs.
// This recv expects EOF or errors, so we don't collect inPayload.
if err := recv(as.p, as.codec, as.s, as.dc, m, *as.callInfo.maxReceiveMessageSize, nil, as.decomp, false); err == io.EOF {
return as.s.Status().Err() // non-server streaming Recv returns nil on success
if err := recv(as.parser, as.codec, as.transportStream, as.decompressorV0, m, *as.callInfo.maxReceiveMessageSize, nil, as.decompressorV1, false); err == io.EOF {
return as.transportStream.Status().Err() // non-server streaming Recv returns nil on success
} else if err != nil {
return toRPCErr(err)
}
@ -1498,8 +1500,8 @@ func (as *addrConnStream) finish(err error) {
// Ending a stream with EOF indicates a success.
err = nil
}
if as.s != nil {
as.s.Close(err)
if as.transportStream != nil {
as.transportStream.Close(err)
}
if err != nil {
@ -1570,10 +1572,10 @@ type serverStream struct {
p *parser
codec baseCodec
cp Compressor
dc Decompressor
comp encoding.Compressor
decomp encoding.Compressor
compressorV0 Compressor
compressorV1 encoding.Compressor
decompressorV0 Decompressor
decompressorV1 encoding.Compressor
sendCompressorName string
@ -1669,12 +1671,12 @@ func (ss *serverStream) SendMsg(m any) (err error) {
// Server handler could have set new compressor by calling SetSendCompressor.
// In case it is set, we need to use it for compressing outbound message.
if sendCompressorsName := ss.s.SendCompress(); sendCompressorsName != ss.sendCompressorName {
ss.comp = encoding.GetCompressor(sendCompressorsName)
ss.compressorV1 = encoding.GetCompressor(sendCompressorsName)
ss.sendCompressorName = sendCompressorsName
}
// load hdr, payload, data
hdr, data, payload, pf, err := prepareMsg(m, ss.codec, ss.cp, ss.comp, ss.p.bufferPool)
hdr, data, payload, pf, err := prepareMsg(m, ss.codec, ss.compressorV0, ss.compressorV1, ss.p.bufferPool)
if err != nil {
return err
}
@ -1755,7 +1757,7 @@ func (ss *serverStream) RecvMsg(m any) (err error) {
payInfo = &payloadInfo{}
defer payInfo.free()
}
if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxReceiveMessageSize, payInfo, ss.decomp, true); err != nil {
if err := recv(ss.p, ss.codec, ss.s, ss.decompressorV0, m, ss.maxReceiveMessageSize, payInfo, ss.decompressorV1, true); err != nil {
if err == io.EOF {
if len(ss.binlogs) != 0 {
chc := &binarylog.ClientHalfClose{}

View File

@ -19,4 +19,4 @@
package grpc
// Version is the current grpc version.
const Version = "1.70.0"
const Version = "1.71.0"

45
vendor/modules.txt vendored
View File

@ -73,8 +73,8 @@ github.com/google/gnostic-models/extensions
github.com/google/gnostic-models/jsonschema
github.com/google/gnostic-models/openapiv2
github.com/google/gnostic-models/openapiv3
# github.com/google/go-cmp v0.6.0
## explicit; go 1.13
# github.com/google/go-cmp v0.7.0
## explicit; go 1.21
github.com/google/go-cmp/cmp
github.com/google/go-cmp/cmp/internal/diff
github.com/google/go-cmp/cmp/internal/flags
@ -179,8 +179,6 @@ go.opencensus.io/trace
go.opencensus.io/trace/internal
go.opencensus.io/trace/propagation
go.opencensus.io/trace/tracestate
# go.opentelemetry.io/auto/sdk v1.1.0
## explicit; go 1.22.0
# go.uber.org/multierr v1.11.0
## explicit; go 1.19
go.uber.org/multierr
@ -195,13 +193,13 @@ go.uber.org/zap/internal/exit
go.uber.org/zap/internal/pool
go.uber.org/zap/internal/stacktrace
go.uber.org/zap/zapcore
# golang.org/x/mod v0.23.0
## explicit; go 1.22.0
# golang.org/x/mod v0.24.0
## explicit; go 1.23.0
golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/module
golang.org/x/mod/semver
# golang.org/x/net v0.35.0
## explicit; go 1.18
# golang.org/x/net v0.37.0
## explicit; go 1.23.0
golang.org/x/net/http/httpguts
golang.org/x/net/http2
golang.org/x/net/http2/h2c
@ -214,20 +212,20 @@ golang.org/x/net/trace
## explicit; go 1.18
golang.org/x/oauth2
golang.org/x/oauth2/internal
# golang.org/x/sync v0.11.0
## explicit; go 1.18
# golang.org/x/sync v0.12.0
## explicit; go 1.23.0
golang.org/x/sync/errgroup
golang.org/x/sync/semaphore
# golang.org/x/sys v0.30.0
## explicit; go 1.18
# golang.org/x/sys v0.31.0
## explicit; go 1.23.0
golang.org/x/sys/plan9
golang.org/x/sys/unix
golang.org/x/sys/windows
# golang.org/x/term v0.29.0
## explicit; go 1.18
# golang.org/x/term v0.30.0
## explicit; go 1.23.0
golang.org/x/term
# golang.org/x/text v0.22.0
## explicit; go 1.18
# golang.org/x/text v0.23.0
## explicit; go 1.23.0
golang.org/x/text/cases
golang.org/x/text/internal
golang.org/x/text/internal/language
@ -241,8 +239,8 @@ golang.org/x/text/unicode/norm
# golang.org/x/time v0.10.0
## explicit; go 1.18
golang.org/x/time/rate
# golang.org/x/tools v0.30.0
## explicit; go 1.22.0
# golang.org/x/tools v0.31.0
## explicit; go 1.23.0
golang.org/x/tools/go/ast/astutil
golang.org/x/tools/go/gcexportdata
golang.org/x/tools/go/packages
@ -277,13 +275,14 @@ google.golang.org/genproto/googleapis/api/httpbody
# google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6
## explicit; go 1.22
google.golang.org/genproto/googleapis/rpc/status
# google.golang.org/grpc v1.70.0
## explicit; go 1.22
# google.golang.org/grpc v1.71.0
## explicit; go 1.22.0
google.golang.org/grpc
google.golang.org/grpc/attributes
google.golang.org/grpc/backoff
google.golang.org/grpc/balancer
google.golang.org/grpc/balancer/base
google.golang.org/grpc/balancer/endpointsharding
google.golang.org/grpc/balancer/grpclb/state
google.golang.org/grpc/balancer/pickfirst
google.golang.org/grpc/balancer/pickfirst/internal
@ -316,7 +315,9 @@ google.golang.org/grpc/internal/grpcutil
google.golang.org/grpc/internal/idle
google.golang.org/grpc/internal/metadata
google.golang.org/grpc/internal/pretty
google.golang.org/grpc/internal/proxyattributes
google.golang.org/grpc/internal/resolver
google.golang.org/grpc/internal/resolver/delegatingresolver
google.golang.org/grpc/internal/resolver/dns
google.golang.org/grpc/internal/resolver/dns/internal
google.golang.org/grpc/internal/resolver/passthrough
@ -856,10 +857,10 @@ k8s.io/utils/net
k8s.io/utils/pointer
k8s.io/utils/ptr
k8s.io/utils/trace
# knative.dev/hack v0.0.0-20250217122557-ce4c934f30e5
# knative.dev/hack v0.0.0-20250219013704-306ce745e077
## explicit; go 1.21
knative.dev/hack
# knative.dev/pkg v0.0.0-20250214140553-ae2c6bcc1f59
# knative.dev/pkg v0.0.0-20250312035536-b7bbf4be5dbd
## explicit; go 1.23.0
knative.dev/pkg/apis
knative.dev/pkg/apis/duck