mirror of https://github.com/knative/caching.git
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:
parent
ad23fbda1a
commit
776406ea7b
23
go.mod
23
go.mod
|
@ -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
56
go.sum
|
@ -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=
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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() }
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
func errorf(format string, args ...interface{}) {
|
||||
func errorf(format string, args ...any) {
|
||||
panic(fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
|
|
|
@ -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...))
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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!"},
|
||||
}
|
|
@ -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)
|
||||
})
|
||||
}
|
|
@ -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},
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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...)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
358
vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go
generated
vendored
Normal file
358
vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go
generated
vendored
Normal 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)
|
||||
}
|
2
vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go
generated
vendored
2
vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go
generated
vendored
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
10
vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go
generated
vendored
10
vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go
generated
vendored
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
|
|
54
vendor/google.golang.org/grpc/internal/proxyattributes/proxyattributes.go
generated
vendored
Normal file
54
vendor/google.golang.org/grpc/internal/proxyattributes/proxyattributes.go
generated
vendored
Normal 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
|
||||
}
|
329
vendor/google.golang.org/grpc/internal/resolver/delegatingresolver/delegatingresolver.go
generated
vendored
Normal file
329
vendor/google.golang.org/grpc/internal/resolver/delegatingresolver/delegatingresolver.go
generated
vendored
Normal 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)
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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{}
|
||||
|
|
|
@ -19,4 +19,4 @@
|
|||
package grpc
|
||||
|
||||
// Version is the current grpc version.
|
||||
const Version = "1.70.0"
|
||||
const Version = "1.71.0"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue