From 92403fe09cc4ed0374450a64285b7b191a2b5d27 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 16:30:10 +0000 Subject: [PATCH] chore(deps): bump github.com/caddyserver/caddy/v2 in /plugins/traefik Bumps [github.com/caddyserver/caddy/v2](https://github.com/caddyserver/caddy) from 2.10.0 to 2.11.3. - [Release notes](https://github.com/caddyserver/caddy/releases) - [Commits](https://github.com/caddyserver/caddy/compare/v2.10.0...v2.11.3) --- updated-dependencies: - dependency-name: github.com/caddyserver/caddy/v2 dependency-version: 2.11.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- plugins/traefik/go.mod | 175 +- plugins/traefik/go.sum | 793 +- .../traefik/vendor/cel.dev/expr/.bazelversion | 2 +- .../traefik/vendor/cel.dev/expr/BUILD.bazel | 1 - .../traefik/vendor/cel.dev/expr/MODULE.bazel | 26 +- plugins/traefik/vendor/cel.dev/expr/README.md | 2 - .../traefik/vendor/cel.dev/expr/checked.pb.go | 749 +- .../vendor/cel.dev/expr/cloudbuild.yaml | 2 +- .../traefik/vendor/cel.dev/expr/eval.pb.go | 358 +- .../traefik/vendor/cel.dev/expr/explain.pb.go | 113 +- .../traefik/vendor/cel.dev/expr/syntax.pb.go | 879 +- .../traefik/vendor/cel.dev/expr/value.pb.go | 348 +- .../cloud.google.com/go/auth/CHANGES.md | 475 + .../go/auth}/LICENSE | 0 .../vendor/cloud.google.com/go/auth/README.md | 40 + .../vendor/cloud.google.com/go/auth/auth.go | 618 + .../go/auth/credentials/compute.go | 102 + .../go/auth/credentials/detect.go | 471 + .../go/auth/credentials/doc.go | 45 + .../go/auth/credentials/filetypes.go | 329 + .../internal/externalaccount/aws_provider.go | 531 + .../externalaccount/executable_provider.go | 284 + .../externalaccount/externalaccount.go | 431 + .../internal/externalaccount/file_provider.go | 78 + .../internal/externalaccount/info.go | 74 + .../externalaccount/programmatic_provider.go | 30 + .../internal/externalaccount/url_provider.go | 93 + .../internal/externalaccount/x509_provider.go | 220 + .../externalaccountuser.go | 115 + .../go/auth/credentials/internal/gdch/gdch.go | 198 + .../internal/impersonate/idtoken.go | 105 + .../internal/impersonate/impersonate.go | 168 + .../internal/stsexchange/sts_exchange.go | 167 + .../go/auth/credentials/selfsignedjwt.go | 89 + .../go/auth/httptransport/httptransport.go | 254 + .../go/auth/httptransport/transport.go | 235 + .../go/auth/internal/credsfile/credsfile.go | 63 + .../go/auth/internal/credsfile/filetype.go | 159 + .../go/auth/internal/credsfile/parse.go | 99 + .../go/auth/internal/internal.go | 285 + .../go/auth/internal/jwt/jwt.go | 208 + .../go/auth/internal/retry/retry.go | 117 + .../go/auth/internal/transport/cba.go | 361 + .../internal/transport/cert/default_cert.go | 65 + .../transport/cert/enterprise_cert.go | 54 + .../transport/cert/secureconnect_cert.go | 124 + .../internal/transport/cert/workload_cert.go | 138 + .../internal/transport/headers/headers.go | 61 + .../go/auth/internal/transport/s2a.go | 138 + .../go/auth/internal/transport/transport.go | 107 + .../external_accounts_config_providers.go | 100 + .../internal/trustboundary/trust_boundary.go | 392 + .../go/auth/internal/version.go | 20 + .../go/auth/oauth2adapt/CHANGES.md | 82 + .../go/auth/oauth2adapt}/LICENSE | 0 .../go/auth/oauth2adapt/oauth2adapt.go | 200 + .../cloud.google.com/go/auth/threelegged.go | 382 + .../go/compute/metadata/CHANGES.md | 115 + .../go/compute/metadata/LICENSE | 202 + .../go/compute/metadata/README.md | 27 + .../go/compute/metadata/log.go | 149 + .../go/compute/metadata/metadata.go | 937 + .../go/compute/metadata/retry.go | 117 + .../go/compute/metadata/retry_linux.go | 31 + .../go/compute/metadata/syscheck.go | 28 + .../go/compute/metadata/syscheck_linux.go | 30 + .../go/compute/metadata/syscheck_windows.go | 39 + .../vendor/dario.cat/mergo/FUNDING.json | 7 + .../traefik/vendor/dario.cat/mergo/README.md | 5 - .../vendor/dario.cat/mergo/SECURITY.md | 4 +- .../traefik/vendor/filippo.io/bigmod/LICENSE | 27 + .../vendor/filippo.io/bigmod/README.md | 9 + .../traefik/vendor/filippo.io/bigmod/nat.go | 1241 + .../vendor/filippo.io/bigmod/nat_386.s | 47 + .../vendor/filippo.io/bigmod/nat_amd64.s | 1230 + .../vendor/filippo.io/bigmod/nat_arm.s | 47 + .../vendor/filippo.io/bigmod/nat_arm64.s | 69 + .../vendor/filippo.io/bigmod/nat_asm.go | 28 + .../vendor/filippo.io/bigmod/nat_loong64.s | 93 + .../vendor/filippo.io/bigmod/nat_noasm.go | 21 + .../vendor/filippo.io/bigmod/nat_ppc64x.s | 82 + .../vendor/filippo.io/bigmod/nat_riscv64.s | 91 + .../vendor/filippo.io/bigmod/nat_s390x.s | 85 + .../vendor/filippo.io/bigmod/nat_wasm.go | 61 + .../vendor/filippo.io/edwards25519/README.md | 6 +- .../vendor/filippo.io/edwards25519/doc.go | 6 +- .../vendor/filippo.io/edwards25519/extra.go | 68 +- .../filippo.io/edwards25519/field/fe.go | 34 +- .../filippo.io/edwards25519/field/fe_amd64.go | 3 +- .../filippo.io/edwards25519/field/fe_amd64.s | 203 +- .../edwards25519/field/fe_amd64_noasm.go | 3 +- .../filippo.io/edwards25519/field/fe_arm64.go | 16 - .../filippo.io/edwards25519/field/fe_arm64.s | 42 - .../edwards25519/field/fe_arm64_noasm.go | 12 - .../edwards25519/field/fe_generic.go | 170 +- .../vendor/filippo.io/edwards25519/pull.sh | 53 + .../vendor/filippo.io/edwards25519/scalar.go | 27 +- .../vendor/filippo.io/edwards25519/tables.go | 4 +- .../automemlimit/memlimit/cgroups.go | 53 +- .../automemlimit/memlimit/memlimit.go | 32 +- .../Masterminds/semver/v3/CHANGELOG.md | 28 +- .../Masterminds/semver/v3/README.md | 18 +- .../Masterminds/semver/v3/constraints.go | 127 +- .../Masterminds/semver/v3/version.go | 173 +- .../github.com/Microsoft/go-winio/tools.go | 5 - .../github.com/antlr4-go/antlr/v4/antlrdoc.go | 8 +- .../github.com/antlr4-go/antlr/v4/atn.go | 8 +- .../antlr4-go/antlr/v4/atn_config.go | 3 - .../antlr4-go/antlr/v4/input_stream.go | 2 +- .../github.com/antlr4-go/antlr/v4/jcollect.go | 5 +- .../github.com/antlr4-go/antlr/v4/lexer.go | 2 +- .../antlr4-go/antlr/v4/ll1_analyzer.go | 1 + .../github.com/antlr4-go/antlr/v4/mutex.go | 41 + .../antlr4-go/antlr/v4/mutex_nomutex.go | 32 + .../antlr/v4/parser_atn_simulator.go | 4 +- .../antlr4-go/antlr/v4/prediction_context.go | 60 +- .../antlr4-go/antlr/v4/recognizer.go | 2 +- .../antlr4-go/antlr/v4/statistics.go | 3 +- .../github.com/antlr4-go/antlr/v4/token.go | 82 +- .../github.com/antlr4-go/antlr/v4/utils.go | 53 + .../caddyserver/caddy/v2/.golangci.yml | 243 +- .../caddyserver/caddy/v2/.goreleaser.yml | 4 +- .../caddy/v2/.pre-commit-config.yaml | 20 + .../github.com/caddyserver/caddy/v2/AGENTS.md | 217 + .../github.com/caddyserver/caddy/v2/README.md | 62 +- .../github.com/caddyserver/caddy/v2/admin.go | 163 +- .../github.com/caddyserver/caddy/v2/caddy.go | 224 +- .../caddy/v2/caddyconfig/caddyfile/adapter.go | 2 +- .../v2/caddyconfig/caddyfile/dispenser.go | 26 +- .../v2/caddyconfig/caddyfile/formatter.go | 103 +- .../caddy/v2/caddyconfig/caddyfile/lexer.go | 5 +- .../caddy/v2/caddyconfig/caddyfile/parse.go | 65 +- .../caddy/v2/caddyconfig/configadapters.go | 6 +- .../caddy/v2/caddyconfig/httploader.go | 4 +- .../caddyserver/caddy/v2/caddyconfig/load.go | 9 +- .../caddyserver/caddy/v2/cmd/cobra.go | 18 +- .../caddyserver/caddy/v2/cmd/commandfuncs.go | 162 +- .../caddyserver/caddy/v2/cmd/commands.go | 76 +- .../caddyserver/caddy/v2/cmd/main.go | 44 +- .../caddyserver/caddy/v2/cmd/packagesfuncs.go | 10 +- .../caddyserver/caddy/v2/cmd/storagefuncs.go | 2 +- .../caddyserver/caddy/v2/context.go | 88 +- .../caddy/v2/internal/logbuffer.go | 82 + .../caddy/v2/internal/logmarshalers.go | 54 + .../github.com/caddyserver/caddy/v2/listen.go | 48 +- .../caddy/v2/listen_reuseUnixSocket.go} | 20 +- .../v2/listen_reuseUnixSocket_windows.go | 89 + .../caddyserver/caddy/v2/listen_unix.go | 22 +- .../caddyserver/caddy/v2/listeners.go | 95 +- .../caddyserver/caddy/v2/logging.go | 28 +- .../caddyserver/caddy/v2/modules.go | 10 +- .../caddy/v2/modules/caddyevents/app.go | 4 +- .../caddy/v2/modules/caddyhttp/app.go | 269 +- .../caddy/v2/modules/caddyhttp/autohttps.go | 176 +- .../caddy/v2/modules/caddyhttp/celmatcher.go | 42 +- .../caddy/v2/modules/caddyhttp/errors.go | 4 +- .../v2/modules/caddyhttp/http2listener.go | 175 +- .../caddy/v2/modules/caddyhttp/ip_matchers.go | 5 +- .../caddy/v2/modules/caddyhttp/logging.go | 83 +- .../caddy/v2/modules/caddyhttp/marshalers.go | 48 +- .../caddy/v2/modules/caddyhttp/matchers.go | 44 +- .../caddy/v2/modules/caddyhttp/metrics.go | 228 +- .../caddy/v2/modules/caddyhttp/replacer.go | 55 +- .../caddy/v2/modules/caddyhttp/routes.go | 79 +- .../caddy/v2/modules/caddyhttp/server.go | 319 +- .../caddy/v2/modules/caddyhttp/staticresp.go | 26 +- .../caddy/v2/modules/caddyhttp/vars.go | 58 +- .../caddy/v2/modules/caddypki/adminapi.go | 17 +- .../caddy/v2/modules/caddypki/ca.go | 88 +- .../caddy/v2/modules/caddypki/crypto.go | 67 +- .../caddy/v2/modules/caddypki/maintain.go | 36 +- .../caddy/v2/modules/caddypki/pki.go | 6 +- .../caddy/v2/modules/caddytls/acmeissuer.go | 71 +- .../caddy/v2/modules/caddytls/automation.go | 119 +- .../caddy/v2/modules/caddytls/capools.go | 334 +- .../caddy/v2/modules/caddytls/certmanagers.go | 8 +- .../v2/modules/caddytls/certselection.go | 8 +- .../caddy/v2/modules/caddytls/connpolicy.go | 109 +- .../caddy/v2/modules/caddytls/ech.go | 400 +- .../caddy/v2/modules/caddytls/folderloader.go | 22 +- .../v2/modules/caddytls/internalissuer.go | 3 +- .../v2/modules/caddytls/leaffileloader.go | 21 +- .../v2/modules/caddytls/leaffolderloader.go | 13 +- .../v2/modules/caddytls/leafpemloader.go | 8 + .../caddy/v2/modules/caddytls/tls.go | 163 +- .../v2/modules/caddytls/zerosslissuer.go | 2 +- .../caddy/v2/notify/notify_windows.go | 69 +- .../caddyserver/caddy/v2/replacer.go | 16 +- .../caddyserver/caddy/v2/sigtrap_posix.go | 27 +- .../caddyserver/caddy/v2/usagepool.go | 24 +- .../caddyserver/certmagic/README.md | 9 +- .../caddyserver/certmagic/account.go | 24 +- .../caddyserver/certmagic/acmeclient.go | 64 +- .../caddyserver/certmagic/acmeissuer.go | 19 +- .../github.com/caddyserver/certmagic/cache.go | 10 +- .../caddyserver/certmagic/certificates.go | 65 +- .../caddyserver/certmagic/config.go | 117 +- .../caddyserver/certmagic/filestorage.go | 61 +- .../caddyserver/certmagic/handshake.go | 63 +- .../caddyserver/certmagic/httphandlers.go | 91 +- .../caddyserver/certmagic/maintain.go | 19 +- .../github.com/caddyserver/certmagic/ocsp.go | 29 +- .../caddyserver/certmagic/solvers.go | 2 + .../caddyserver/certmagic/storage.go | 42 + .../github.com/caddyserver/zerossl/client.go | 62 +- .../caddyserver/zerossl/endpoints.go | 8 +- .../github.com/caddyserver/zerossl/models.go | 11 +- .../ccoveille/go-safecast/v2/.editorconfig | 25 + .../ccoveille/go-safecast/v2/.gitattributes | 4 + .../ccoveille/go-safecast/v2/.golangci.yml | 190 + .../ccoveille/go-safecast/v2/.ls-lint.yml | 17 + .../go-safecast/v2/.markdownlint.yml | 14 + .../ccoveille/go-safecast/v2/.yamllint.yml | 14 + .../log => ccoveille/go-safecast/v2}/LICENSE | 2 +- .../ccoveille/go-safecast/v2/README.md | 163 + .../ccoveille/go-safecast/v2/conversion.go | 163 + .../ccoveille/go-safecast/v2/doc.go | 5 + .../ccoveille/go-safecast/v2/errors.go | 105 + .../ccoveille/go-safecast/v2/parse.go | 223 + .../ccoveille/go-safecast/v2/types.go | 82 + .../pgx/v4 => cenkalti/backoff/v5}/.gitignore | 3 +- .../cenkalti/backoff/v5/CHANGELOG.md | 29 + .../github.com/cenkalti/backoff/v5/LICENSE | 20 + .../github.com/cenkalti/backoff/v5/README.md | 31 + .../github.com/cenkalti/backoff/v5/backoff.go | 66 + .../github.com/cenkalti/backoff/v5/error.go | 46 + .../cenkalti/backoff/v5/exponential.go | 118 + .../github.com/cenkalti/backoff/v5/retry.go | 139 + .../github.com/cenkalti/backoff/v5/ticker.go | 83 + .../github.com/cenkalti/backoff/v5/timer.go | 35 + .../cloudflare/circl/hpke/shortkem.go | 4 +- .../circl/internal/sha3/xor_unaligned.go | 6 +- .../cloudflare/circl/kem/xwing/xwing.go | 6 + .../circl/pke/kyber/internal/common/arm64.go | 83 + .../circl/pke/kyber/internal/common/arm64.s | 53 + .../pke/kyber/internal/common/generic.go | 4 +- .../circl/simd/keccakf1600/f1600x.go | 4 +- .../github.com/coreos/go-oidc/v3/LICENSE | 202 + .../github.com/coreos/go-oidc/v3/NOTICE | 5 + .../github.com/coreos/go-oidc/v3/oidc/jose.go | 32 + .../github.com/coreos/go-oidc/v3/oidc/jwks.go | 263 + .../github.com/coreos/go-oidc/v3/oidc/oidc.go | 584 + .../coreos/go-oidc/v3/oidc/verify.go | 338 + .../cpuguy83/go-md2man/v2/md2man/md2man.go | 1 + .../cpuguy83/go-md2man/v2/md2man/roff.go | 15 +- .../github.com/darkweak/souin/api/main.go | 50 - .../souin/api/prometheus/prometheus.go | 5 - .../github.com/darkweak/souin/api/souin.go | 233 - .../github.com/darkweak/souin/api/types.go | 12 - .../souin/configurationtypes/types.go | 34 + .../darkweak/souin/context/cache.go | 1 + .../darkweak/souin/context/graphql.go | 1 + .../github.com/darkweak/souin/context/key.go | 67 +- .../darkweak/souin/context/method.go | 1 + .../github.com/darkweak/souin/context/mode.go | 1 + .../github.com/darkweak/souin/context/now.go | 12 +- .../darkweak/souin/context/timeout.go | 2 + .../darkweak/souin/pkg/api/debug/debug.go | 87 + .../github.com/darkweak/souin/pkg/api/main.go | 9 +- .../souin/pkg/api/prometheus/prometheus.go | 106 +- .../darkweak/souin/pkg/api/souin.go | 132 +- .../souin/pkg/middleware/configuration.go | 12 + .../souin/pkg/middleware/middleware.go | 498 +- .../darkweak/souin/pkg/middleware/writer.go | 130 +- .../darkweak/souin/pkg/rfc/revalidation.go | 184 +- .../github.com/darkweak/souin/pkg/rfc/vary.go | 8 +- .../souin/pkg/storage/abstractProvider.go | 57 - .../souin/pkg/storage/cacheProvider.go | 178 - .../souin/pkg/storage/defaultProvider.go | 213 + .../darkweak/souin/pkg/storage/types/types.go | 23 +- .../souin/pkg/surrogate/providers/common.go | 117 +- .../github.com/felixge/httpsnoop/.gitignore | 0 .../github.com/felixge/httpsnoop/LICENSE.txt | 19 + .../github.com/felixge/httpsnoop/Makefile | 10 + .../github.com/felixge/httpsnoop/README.md | 95 + .../felixge/httpsnoop/capture_metrics.go | 86 + .../github.com/felixge/httpsnoop/docs.go | 10 + .../httpsnoop/wrap_generated_gteq_1.8.go | 436 + .../httpsnoop/wrap_generated_lt_1.8.go | 278 + .../github.com/francoispqt/gojay/.gitignore | 5 - .../github.com/francoispqt/gojay/.travis.yml | 15 - .../github.com/francoispqt/gojay/Gopkg.lock | 163 - .../github.com/francoispqt/gojay/Gopkg.toml | 23 - .../github.com/francoispqt/gojay/LICENSE | 21 - .../github.com/francoispqt/gojay/Makefile | 11 - .../github.com/francoispqt/gojay/README.md | 855 - .../github.com/francoispqt/gojay/decode.go | 386 - .../francoispqt/gojay/decode_array.go | 247 - .../francoispqt/gojay/decode_bool.go | 241 - .../francoispqt/gojay/decode_embedded_json.go | 85 - .../francoispqt/gojay/decode_interface.go | 130 - .../francoispqt/gojay/decode_number.go | 118 - .../francoispqt/gojay/decode_number_float.go | 516 - .../francoispqt/gojay/decode_number_int.go | 1338 - .../francoispqt/gojay/decode_number_uint.go | 715 - .../francoispqt/gojay/decode_object.go | 407 - .../francoispqt/gojay/decode_pool.go | 64 - .../francoispqt/gojay/decode_slice.go | 89 - .../francoispqt/gojay/decode_sqlnull.go | 157 - .../francoispqt/gojay/decode_stream.go | 115 - .../francoispqt/gojay/decode_stream_pool.go | 59 - .../francoispqt/gojay/decode_string.go | 260 - .../gojay/decode_string_unicode.go | 98 - .../francoispqt/gojay/decode_time.go | 53 - .../francoispqt/gojay/decode_unsafe.go | 120 - .../github.com/francoispqt/gojay/encode.go | 202 - .../francoispqt/gojay/encode_array.go | 212 - .../francoispqt/gojay/encode_bool.go | 164 - .../francoispqt/gojay/encode_builder.go | 65 - .../francoispqt/gojay/encode_embedded_json.go | 93 - .../francoispqt/gojay/encode_interface.go | 173 - .../francoispqt/gojay/encode_null.go | 39 - .../francoispqt/gojay/encode_number.go | 1 - .../francoispqt/gojay/encode_number_float.go | 368 - .../francoispqt/gojay/encode_number_int.go | 500 - .../francoispqt/gojay/encode_number_uint.go | 362 - .../francoispqt/gojay/encode_object.go | 400 - .../francoispqt/gojay/encode_pool.go | 50 - .../francoispqt/gojay/encode_slice.go | 113 - .../francoispqt/gojay/encode_sqlnull.go | 377 - .../francoispqt/gojay/encode_stream.go | 205 - .../francoispqt/gojay/encode_stream_pool.go | 38 - .../francoispqt/gojay/encode_string.go | 186 - .../francoispqt/gojay/encode_time.go | 68 - .../github.com/francoispqt/gojay/errors.go | 88 - .../github.com/francoispqt/gojay/gojay.go | 10 - .../github.com/francoispqt/gojay/gojay.png | Bin 44163 -> 0 bytes .../github.com/go-jose/go-jose/v4/.gitignore | 2 + .../go-jose/go-jose/v4/.golangci.yml | 53 + .../github.com/go-jose/go-jose/v4/.travis.yml | 33 + .../go-jose/go-jose/v4/CONTRIBUTING.md | 9 + .../github.com/go-jose/go-jose/v4/LICENSE | 202 + .../github.com/go-jose/go-jose/v4/README.md | 108 + .../github.com/go-jose/go-jose/v4/SECURITY.md | 13 + .../go-jose/go-jose/v4/asymmetric.go | 603 + .../go-jose/go-jose/v4/cipher/cbc_hmac.go | 196 + .../go-jose/go-jose/v4/cipher/concat_kdf.go | 75 + .../go-jose/go-jose/v4/cipher/ecdh_es.go | 86 + .../go-jose/go-jose/v4/cipher/key_wrap.go | 117 + .../github.com/go-jose/go-jose/v4/crypter.go | 595 + .../go-jose/go-jose/v4/doc.go} | 29 +- .../github.com/go-jose/go-jose/v4/encoding.go | 228 + .../go-jose/go-jose/v4/json/LICENSE | 27 + .../go-jose/go-jose/v4/json/README.md | 13 + .../go-jose/go-jose/v4/json/decode.go | 1216 + .../go-jose/go-jose/v4/json/encode.go | 1197 + .../go-jose/go-jose/v4/json/indent.go | 141 + .../go-jose/go-jose/v4/json/scanner.go | 623 + .../go-jose/go-jose/v4/json/stream.go | 484 + .../go-jose/go-jose/v4/json/tags.go | 44 + .../github.com/go-jose/go-jose/v4/jwe.go | 391 + .../github.com/go-jose/go-jose/v4/jwk.go | 848 + .../github.com/go-jose/go-jose/v4/jws.go | 470 + .../github.com/go-jose/go-jose/v4/opaque.go | 147 + .../github.com/go-jose/go-jose/v4/shared.go | 560 + .../github.com/go-jose/go-jose/v4/signing.go | 523 + .../go-jose/go-jose/v4/symmetric.go | 532 + .../github.com/go-kit/kit/log/level/doc.go | 25 - .../github.com/go-kit/kit/log/level/level.go | 120 - .../vendor/github.com/go-kit/log/README.md | 156 - .../vendor/github.com/go-kit/log/doc.go | 116 - .../github.com/go-kit/log/json_logger.go | 91 - .../vendor/github.com/go-kit/log/level/doc.go | 33 - .../github.com/go-kit/log/level/level.go | 256 - .../vendor/github.com/go-kit/log/log.go | 179 - .../github.com/go-kit/log/logfmt_logger.go | 62 - .../github.com/go-kit/log/nop_logger.go | 8 - .../github.com/go-kit/log/staticcheck.conf | 1 - .../vendor/github.com/go-kit/log/stdlib.go | 151 - .../vendor/github.com/go-kit/log/sync.go | 113 - .../vendor/github.com/go-kit/log/value.go | 110 - .../github.com/go-logfmt/logfmt/.gitignore | 1 - .../github.com/go-logfmt/logfmt/CHANGELOG.md | 82 - .../github.com/go-logfmt/logfmt/LICENSE | 22 - .../github.com/go-logfmt/logfmt/README.md | 41 - .../github.com/go-logfmt/logfmt/decode.go | 254 - .../vendor/github.com/go-logfmt/logfmt/doc.go | 6 - .../github.com/go-logfmt/logfmt/encode.go | 322 - .../github.com/go-logfmt/logfmt/jsonstring.go | 277 - .../github.com/go-logr/logr/.golangci.yaml | 28 + .../github.com/go-logr/logr/CHANGELOG.md | 6 + .../github.com/go-logr/logr/CONTRIBUTING.md | 17 + .../vendor/github.com/go-logr/logr/LICENSE | 201 + .../vendor/github.com/go-logr/logr/README.md | 407 + .../github.com/go-logr/logr/SECURITY.md | 18 + .../vendor/github.com/go-logr/logr/context.go | 33 + .../github.com/go-logr/logr/context_noslog.go | 49 + .../github.com/go-logr/logr/context_slog.go | 83 + .../vendor/github.com/go-logr/logr/discard.go | 24 + .../github.com/go-logr/logr/funcr/funcr.go | 914 + .../github.com/go-logr/logr/funcr/slogsink.go | 105 + .../vendor/github.com/go-logr/logr/logr.go | 520 + .../github.com/go-logr/logr/sloghandler.go | 192 + .../vendor/github.com/go-logr/logr/slogr.go | 100 + .../github.com/go-logr/logr/slogsink.go | 120 + .../go-logr/stdr}/LICENSE | 0 .../vendor/github.com/go-logr/stdr/README.md | 6 + .../vendor/github.com/go-logr/stdr/stdr.go | 170 + .../github.com/go-sql-driver/mysql/AUTHORS | 29 + .../go-sql-driver/mysql/CHANGELOG.md | 100 +- .../github.com/go-sql-driver/mysql/README.md | 92 +- .../go-sql-driver/mysql/atomic_bool.go | 19 - .../go-sql-driver/mysql/atomic_bool_go118.go | 47 - .../github.com/go-sql-driver/mysql/auth.go | 63 +- .../github.com/go-sql-driver/mysql/buffer.go | 139 +- .../go-sql-driver/mysql/collations.go | 4 +- .../go-sql-driver/mysql/compress.go | 213 + .../go-sql-driver/mysql/connection.go | 251 +- .../go-sql-driver/mysql/connector.go | 135 +- .../github.com/go-sql-driver/mysql/const.go | 20 +- .../github.com/go-sql-driver/mysql/driver.go | 27 +- .../github.com/go-sql-driver/mysql/dsn.go | 178 +- .../github.com/go-sql-driver/mysql/errors.go | 18 +- .../github.com/go-sql-driver/mysql/fields.go | 72 +- .../github.com/go-sql-driver/mysql/fuzz.go | 25 - .../github.com/go-sql-driver/mysql/infile.go | 28 +- .../go-sql-driver/mysql/nulltime.go | 4 +- .../github.com/go-sql-driver/mysql/packets.go | 517 +- .../github.com/go-sql-driver/mysql/result.go | 36 +- .../github.com/go-sql-driver/mysql/rows.go | 20 +- .../go-sql-driver/mysql/statement.go | 32 +- .../go-sql-driver/mysql/transaction.go | 18 +- .../github.com/go-sql-driver/mysql/utils.go | 60 +- .../go-task/slim-sprig/.editorconfig | 14 - .../go-task/slim-sprig/.gitattributes | 1 - .../github.com/go-task/slim-sprig/.gitignore | 2 - .../go-task/slim-sprig/CHANGELOG.md | 364 - .../github.com/go-task/slim-sprig/LICENSE.txt | 19 - .../github.com/go-task/slim-sprig/README.md | 73 - .../go-task/slim-sprig/Taskfile.yml | 12 - .../github.com/go-task/slim-sprig/crypto.go | 24 - .../github.com/go-task/slim-sprig/date.go | 152 - .../github.com/go-task/slim-sprig/defaults.go | 163 - .../github.com/go-task/slim-sprig/dict.go | 118 - .../github.com/go-task/slim-sprig/doc.go | 19 - .../go-task/slim-sprig/functions.go | 317 - .../github.com/go-task/slim-sprig/list.go | 464 - .../github.com/go-task/slim-sprig/network.go | 12 - .../github.com/go-task/slim-sprig/numeric.go | 228 - .../github.com/go-task/slim-sprig/reflect.go | 28 - .../github.com/go-task/slim-sprig/regex.go | 83 - .../github.com/go-task/slim-sprig/strings.go | 189 - .../github.com/go-task/slim-sprig/url.go | 66 - .../github.com/google/cel-go/cel/BUILD.bazel | 22 +- .../github.com/google/cel-go/cel/decls.go | 34 +- .../github.com/google/cel-go/cel/env.go | 155 +- .../google/cel-go/cel/fieldpaths.go | 163 + .../github.com/google/cel-go/cel/folding.go | 60 +- .../github.com/google/cel-go/cel/inlining.go | 75 +- .../vendor/github.com/google/cel-go/cel/io.go | 57 +- .../github.com/google/cel-go/cel/library.go | 123 +- .../github.com/google/cel-go/cel/macro.go | 30 +- .../github.com/google/cel-go/cel/optimizer.go | 54 +- .../github.com/google/cel-go/cel/options.go | 139 +- .../github.com/google/cel-go/cel/program.go | 256 +- .../github.com/google/cel-go/cel/prompt.go | 226 + .../cel-go/cel/templates/authoring.tmpl | 78 + .../github.com/google/cel-go/cel/validator.go | 8 + .../google/cel-go/checker/checker.go | 78 +- .../github.com/google/cel-go/checker/cost.go | 7 +- .../google/cel-go/checker/decls/decls.go | 33 +- .../github.com/google/cel-go/checker/env.go | 137 +- .../google/cel-go/checker/errors.go | 4 + .../google/cel-go/checker/options.go | 9 + .../google/cel-go/checker/scopes.go | 25 + .../google/cel-go/common/BUILD.bazel | 2 + .../google/cel-go/common/ast/ast.go | 139 + .../google/cel-go/common/ast/conversion.go | 49 + .../google/cel-go/common/debug/debug.go | 15 + .../google/cel-go/common/decls/BUILD.bazel | 2 + .../google/cel-go/common/decls/decls.go | 246 +- .../github.com/google/cel-go/common/doc.go | 167 + .../google/cel-go/common/env/BUILD.bazel | 3 +- .../google/cel-go/common/env/env.go | 128 +- .../google/cel-go/common/stdlib/BUILD.bazel | 1 + .../google/cel-go/common/stdlib/standard.go | 490 +- .../google/cel-go/common/types/BUILD.bazel | 2 +- .../google/cel-go/common/types/bool.go | 11 +- .../google/cel-go/common/types/bytes.go | 17 +- .../google/cel-go/common/types/double.go | 24 +- .../google/cel-go/common/types/duration.go | 7 +- .../google/cel-go/common/types/err.go | 3 + .../google/cel-go/common/types/format.go | 42 + .../google/cel-go/common/types/int.go | 7 +- .../google/cel-go/common/types/json_value.go | 9 +- .../google/cel-go/common/types/list.go | 73 +- .../google/cel-go/common/types/map.go | 84 +- .../google/cel-go/common/types/null.go | 13 +- .../google/cel-go/common/types/object.go | 37 +- .../google/cel-go/common/types/optional.go | 16 +- .../google/cel-go/common/types/pb/file.go | 12 +- .../google/cel-go/common/types/pb/pb.go | 25 +- .../google/cel-go/common/types/pb/type.go | 123 +- .../google/cel-go/common/types/provider.go | 101 +- .../cel-go/common/types/ref/provider.go | 3 + .../google/cel-go/common/types/string.go | 6 +- .../google/cel-go/common/types/timestamp.go | 6 +- .../google/cel-go/common/types/types.go | 7 + .../google/cel-go/common/types/uint.go | 8 +- .../github.com/google/cel-go/ext/BUILD.bazel | 17 +- .../github.com/google/cel-go/ext/README.md | 108 +- .../github.com/google/cel-go/ext/bindings.go | 10 + .../google/cel-go/ext/comprehensions.go | 8 +- .../cel-go/ext/extension_option_factory.go | 92 + .../google/cel-go/ext/formatting.go | 48 +- .../google/cel-go/ext/formatting_v2.go | 793 + .../github.com/google/cel-go/ext/lists.go | 265 +- .../github.com/google/cel-go/ext/math.go | 47 + .../github.com/google/cel-go/ext/native.go | 26 +- .../github.com/google/cel-go/ext/regex.go | 452 + .../github.com/google/cel-go/ext/sets.go | 14 +- .../github.com/google/cel-go/ext/strings.go | 81 +- .../google/cel-go/interpreter/activation.go | 1 + .../cel-go/interpreter/attribute_patterns.go | 12 +- .../google/cel-go/interpreter/attributes.go | 55 +- .../cel-go/interpreter/interpretable.go | 101 +- .../google/cel-go/interpreter/interpreter.go | 204 +- .../google/cel-go/interpreter/planner.go | 148 +- .../google/cel-go/interpreter/runtimecost.go | 225 +- .../github.com/google/cel-go/parser/helper.go | 2 +- .../github.com/google/cel-go/parser/macro.go | 181 +- .../github.com/google/cel-go/parser/parser.go | 1 + .../vendor/github.com/google/pprof/AUTHORS | 7 - .../github.com/google/pprof/CONTRIBUTORS | 16 - .../github.com/google/pprof/profile/encode.go | 588 - .../github.com/google/pprof/profile/filter.go | 274 - .../github.com/google/pprof/profile/index.go | 64 - .../pprof/profile/legacy_java_profile.go | 315 - .../google/pprof/profile/legacy_profile.go | 1228 - .../github.com/google/pprof/profile/merge.go | 667 - .../google/pprof/profile/profile.go | 856 - .../github.com/google/pprof/profile/proto.go | 367 - .../github.com/google/pprof/profile/prune.go | 194 - .../github.com/google/s2a-go/.gitignore | 6 + .../google/s2a-go/CODE_OF_CONDUCT.md | 93 + .../github.com/google/s2a-go/CONTRIBUTING.md | 29 + .../github.com/google/s2a-go/LICENSE.md | 202 + .../vendor/github.com/google/s2a-go/README.md | 14 + .../google/s2a-go/fallback/s2a_fallback.go | 167 + .../s2a-go/internal/authinfo/authinfo.go | 119 + .../s2a-go/internal/handshaker/handshaker.go | 438 + .../internal/handshaker/service/service.go | 66 + .../proto/common_go_proto/common.pb.go | 388 + .../s2a_context_go_proto/s2a_context.pb.go | 267 + .../internal/proto/s2a_go_proto/s2a.pb.go | 1377 + .../proto/s2a_go_proto/s2a_grpc.pb.go | 174 + .../proto/v2/common_go_proto/common.pb.go | 549 + .../v2/s2a_context_go_proto/s2a_context.pb.go | 249 + .../internal/proto/v2/s2a_go_proto/s2a.pb.go | 2518 ++ .../proto/v2/s2a_go_proto/s2a_grpc.pb.go | 160 + .../internal/aeadcrypter/aeadcrypter.go | 34 + .../record/internal/aeadcrypter/aesgcm.go | 70 + .../record/internal/aeadcrypter/chachapoly.go | 67 + .../record/internal/aeadcrypter/common.go | 92 + .../record/internal/halfconn/ciphersuite.go | 98 + .../record/internal/halfconn/counter.go | 60 + .../record/internal/halfconn/expander.go | 59 + .../record/internal/halfconn/halfconn.go | 193 + .../google/s2a-go/internal/record/record.go | 729 + .../s2a-go/internal/record/ticketsender.go | 178 + .../internal/tokenmanager/tokenmanager.go | 79 + .../google/s2a-go/internal/v2/README.md | 1 + .../internal/v2/certverifier/certverifier.go | 122 + .../internal/v2/remotesigner/remotesigner.go | 186 + .../google/s2a-go/internal/v2/s2av2.go | 380 + .../v2/tlsconfigstore/tlsconfigstore.go | 403 + .../github.com/google/s2a-go/retry/retry.go | 144 + .../vendor/github.com/google/s2a-go/s2a.go | 448 + .../github.com/google/s2a-go/s2a_options.go | 272 + .../github.com/google/s2a-go/s2a_utils.go | 79 + .../google/s2a-go/stream/s2a_stream.go | 39 + .../enterprise-certificate-proxy/LICENSE | 202 + .../client/client.go | 219 + .../client/util/util.go | 100 + .../gax-go/v2/.release-please-manifest.json | 3 + .../googleapis/gax-go/v2/CHANGES.md | 201 + .../github.com/googleapis/gax-go/v2/LICENSE | 27 + .../googleapis/gax-go/v2/apierror/apierror.go | 402 + .../v2/apierror/internal/proto/README.md | 30 + .../internal/proto/custom_error.pb.go | 256 + .../internal/proto/custom_error.proto | 50 + .../v2/apierror/internal/proto/error.pb.go | 280 + .../v2/apierror/internal/proto/error.proto | 46 + .../googleapis/gax-go/v2/call_option.go | 268 + .../googleapis/gax-go/v2/callctx/callctx.go | 127 + .../googleapis/gax-go/v2/content_type.go | 112 + .../googleapis/gax-go/v2/feature.go | 75 + .../gax-go/v2/gax.go} | 56 +- .../github.com/googleapis/gax-go/v2/header.go | 200 + .../googleapis/gax-go/v2/internal/version.go | 20 + .../v2/internallog/internal/internal.go | 134 + .../gax-go/v2/internallog/internallog.go | 154 + .../github.com/googleapis/gax-go/v2/invoke.go | 133 + .../googleapis/gax-go/v2/proto_json_stream.go | 127 + .../gax-go/v2/release-please-config.json | 10 + .../grpc-ecosystem/grpc-gateway/v2/LICENSE | 27 + .../v2/internal/httprule/BUILD.bazel | 35 + .../v2/internal/httprule/compile.go | 121 + .../grpc-gateway/v2/internal/httprule/fuzz.go | 11 + .../v2/internal/httprule/parse.go | 368 + .../v2/internal/httprule/types.go | 60 + .../grpc-gateway/v2/runtime/BUILD.bazel | 98 + .../grpc-gateway/v2/runtime/context.go | 417 + .../grpc-gateway/v2/runtime/convert.go | 318 + .../grpc-gateway/v2/runtime/doc.go | 5 + .../grpc-gateway/v2/runtime/errors.go | 204 + .../grpc-gateway/v2/runtime/fieldmask.go | 168 + .../grpc-gateway/v2/runtime/handler.go | 253 + .../v2/runtime/marshal_httpbodyproto.go | 32 + .../grpc-gateway/v2/runtime/marshal_json.go | 50 + .../grpc-gateway/v2/runtime/marshal_jsonpb.go | 349 + .../grpc-gateway/v2/runtime/marshal_proto.go | 60 + .../grpc-gateway/v2/runtime/marshaler.go | 58 + .../v2/runtime/marshaler_registry.go | 109 + .../grpc-gateway/v2/runtime/mux.go | 564 + .../grpc-gateway/v2/runtime/pattern.go | 381 + .../grpc-gateway/v2/runtime/proto2_convert.go | 80 + .../grpc-gateway/v2/runtime/query.go | 378 + .../grpc-gateway/v2/utilities/BUILD.bazel | 31 + .../grpc-gateway/v2/utilities/doc.go | 2 + .../grpc-gateway/v2/utilities/pattern.go | 22 + .../v2/utilities/readerfactory.go | 19 + .../v2/utilities/string_array_flag.go | 33 + .../grpc-gateway/v2/utilities/trie.go | 174 + .../jackc/chunkreader/v2/.travis.yml | 9 - .../github.com/jackc/chunkreader/v2/LICENSE | 22 - .../github.com/jackc/chunkreader/v2/README.md | 8 - .../jackc/chunkreader/v2/chunkreader.go | 104 - .../vendor/github.com/jackc/pgconn/.gitignore | 3 - .../github.com/jackc/pgconn/CHANGELOG.md | 177 - .../vendor/github.com/jackc/pgconn/LICENSE | 22 - .../vendor/github.com/jackc/pgconn/README.md | 62 - .../vendor/github.com/jackc/pgconn/doc.go | 29 - .../vendor/github.com/jackc/pgconn/errors.go | 238 - .../vendor/github.com/jackc/pgconn/pgconn.go | 1901 - .../github.com/jackc/pgconn/stmtcache/lru.go | 169 - .../jackc/pgconn/stmtcache/stmtcache.go | 58 - .../vendor/github.com/jackc/pgio/.travis.yml | 9 - .../vendor/github.com/jackc/pgio/README.md | 11 - .../github.com/jackc/pgproto3/v2/.travis.yml | 9 - .../github.com/jackc/pgproto3/v2/LICENSE | 22 - .../github.com/jackc/pgproto3/v2/README.md | 18 - .../jackc/pgproto3/v2/chunkreader.go | 19 - .../github.com/jackc/pgproto3/v2/doc.go | 4 - .../github.com/jackc/pgproto3/v2/frontend.go | 210 - .../jackc/pgservicefile/.travis.yml | 9 - .../github.com/jackc/pgservicefile/README.md | 5 +- .../jackc/pgservicefile/pgservicefile.go | 4 +- .../github.com/jackc/pgtype/CHANGELOG.md | 164 - .../vendor/github.com/jackc/pgtype/README.md | 14 - .../vendor/github.com/jackc/pgtype/aclitem.go | 138 - .../github.com/jackc/pgtype/aclitem_array.go | 428 - .../github.com/jackc/pgtype/array_type.go | 353 - .../vendor/github.com/jackc/pgtype/bit.go | 45 - .../vendor/github.com/jackc/pgtype/bool.go | 217 - .../github.com/jackc/pgtype/bool_array.go | 517 - .../vendor/github.com/jackc/pgtype/box.go | 165 - .../vendor/github.com/jackc/pgtype/bpchar.go | 93 - .../github.com/jackc/pgtype/bpchar_array.go | 517 - .../vendor/github.com/jackc/pgtype/bytea.go | 163 - .../github.com/jackc/pgtype/bytea_array.go | 489 - .../vendor/github.com/jackc/pgtype/cid.go | 61 - .../vendor/github.com/jackc/pgtype/cidr.go | 43 - .../github.com/jackc/pgtype/cidr_array.go | 546 - .../vendor/github.com/jackc/pgtype/circle.go | 150 - .../jackc/pgtype/composite_fields.go | 107 - .../github.com/jackc/pgtype/composite_type.go | 682 - .../vendor/github.com/jackc/pgtype/convert.go | 476 - .../github.com/jackc/pgtype/database_sql.go | 41 - .../vendor/github.com/jackc/pgtype/date.go | 324 - .../github.com/jackc/pgtype/date_array.go | 518 - .../github.com/jackc/pgtype/daterange.go | 267 - .../github.com/jackc/pgtype/enum_array.go | 428 - .../github.com/jackc/pgtype/enum_type.go | 168 - .../vendor/github.com/jackc/pgtype/float4.go | 282 - .../github.com/jackc/pgtype/float4_array.go | 517 - .../vendor/github.com/jackc/pgtype/float8.go | 272 - .../github.com/jackc/pgtype/float8_array.go | 517 - .../github.com/jackc/pgtype/generic_binary.go | 39 - .../github.com/jackc/pgtype/generic_text.go | 39 - .../vendor/github.com/jackc/pgtype/hstore.go | 465 - .../github.com/jackc/pgtype/hstore_array.go | 489 - .../vendor/github.com/jackc/pgtype/inet.go | 304 - .../github.com/jackc/pgtype/inet_array.go | 546 - .../vendor/github.com/jackc/pgtype/int2.go | 321 - .../github.com/jackc/pgtype/int2_array.go | 909 - .../vendor/github.com/jackc/pgtype/int4.go | 312 - .../github.com/jackc/pgtype/int4_array.go | 909 - .../jackc/pgtype/int4_multirange.go | 239 - .../github.com/jackc/pgtype/int4range.go | 267 - .../vendor/github.com/jackc/pgtype/int8.go | 298 - .../github.com/jackc/pgtype/int8_array.go | 909 - .../jackc/pgtype/int8_multirange.go | 239 - .../github.com/jackc/pgtype/int8range.go | 267 - .../github.com/jackc/pgtype/interval.go | 257 - .../vendor/github.com/jackc/pgtype/json.go | 209 - .../github.com/jackc/pgtype/json_array.go | 546 - .../vendor/github.com/jackc/pgtype/jsonb.go | 85 - .../github.com/jackc/pgtype/jsonb_array.go | 546 - .../vendor/github.com/jackc/pgtype/line.go | 148 - .../vendor/github.com/jackc/pgtype/lseg.go | 165 - .../vendor/github.com/jackc/pgtype/ltree.go | 72 - .../vendor/github.com/jackc/pgtype/macaddr.go | 173 - .../github.com/jackc/pgtype/macaddr_array.go | 518 - .../github.com/jackc/pgtype/multirange.go | 83 - .../vendor/github.com/jackc/pgtype/name.go | 58 - .../github.com/jackc/pgtype/num_multirange.go | 239 - .../vendor/github.com/jackc/pgtype/numeric.go | 853 - .../github.com/jackc/pgtype/numeric_array.go | 685 - .../github.com/jackc/pgtype/numrange.go | 267 - .../vendor/github.com/jackc/pgtype/oid.go | 81 - .../github.com/jackc/pgtype/oid_value.go | 55 - .../vendor/github.com/jackc/pgtype/path.go | 195 - .../vendor/github.com/jackc/pgtype/pgtype.go | 1001 - .../github.com/jackc/pgtype/pguint32.go | 162 - .../vendor/github.com/jackc/pgtype/point.go | 214 - .../vendor/github.com/jackc/pgtype/polygon.go | 226 - .../vendor/github.com/jackc/pgtype/qchar.go | 152 - .../vendor/github.com/jackc/pgtype/record.go | 126 - .../github.com/jackc/pgtype/record_array.go | 318 - .../vendor/github.com/jackc/pgtype/text.go | 212 - .../github.com/jackc/pgtype/text_array.go | 517 - .../vendor/github.com/jackc/pgtype/tid.go | 156 - .../vendor/github.com/jackc/pgtype/time.go | 231 - .../github.com/jackc/pgtype/timestamp.go | 261 - .../jackc/pgtype/timestamp_array.go | 518 - .../github.com/jackc/pgtype/timestamptz.go | 322 - .../jackc/pgtype/timestamptz_array.go | 518 - .../vendor/github.com/jackc/pgtype/tsrange.go | 267 - .../github.com/jackc/pgtype/tsrange_array.go | 470 - .../github.com/jackc/pgtype/tstzrange.go | 267 - .../jackc/pgtype/tstzrange_array.go | 470 - .../jackc/pgtype/typed_array.go.erb | 512 - .../jackc/pgtype/typed_array_gen.sh | 31 - .../jackc/pgtype/typed_multirange.go.erb | 239 - .../jackc/pgtype/typed_multirange_gen.sh | 8 - .../jackc/pgtype/typed_range.go.erb | 269 - .../jackc/pgtype/typed_range_gen.sh | 7 - .../vendor/github.com/jackc/pgtype/unknown.go | 44 - .../vendor/github.com/jackc/pgtype/uuid.go | 231 - .../github.com/jackc/pgtype/uuid_array.go | 573 - .../vendor/github.com/jackc/pgtype/varbit.go | 133 - .../vendor/github.com/jackc/pgtype/varchar.go | 66 - .../github.com/jackc/pgtype/varchar_array.go | 517 - .../vendor/github.com/jackc/pgtype/xid.go | 64 - .../github.com/jackc/pgx/v4/CHANGELOG.md | 311 - .../vendor/github.com/jackc/pgx/v4/LICENSE | 22 - .../vendor/github.com/jackc/pgx/v4/README.md | 196 - .../vendor/github.com/jackc/pgx/v4/batch.go | 228 - .../vendor/github.com/jackc/pgx/v4/conn.go | 857 - .../github.com/jackc/pgx/v4/copy_from.go | 211 - .../vendor/github.com/jackc/pgx/v4/doc.go | 340 - .../jackc/pgx/v4/extended_query_builder.go | 161 - .../pgx/v4/internal/sanitize/sanitize.go | 326 - .../vendor/github.com/jackc/pgx/v4/logger.go | 107 - .../github.com/jackc/pgx/v4/messages.go | 23 - .../vendor/github.com/jackc/pgx/v4/rows.go | 351 - .../vendor/github.com/jackc/pgx/v4/values.go | 280 - .../vendor/github.com/jackc/pgx/v5/.gitignore | 27 + .../github.com/jackc/pgx/v5/.golangci.yml | 26 + .../github.com/jackc/pgx/v5/CHANGELOG.md | 565 + .../vendor/github.com/jackc/pgx/v5/CLAUDE.md | 73 + .../github.com/jackc/pgx/v5/CONTRIBUTING.md | 139 + .../jackc/{pgtype => pgx/v5}/LICENSE | 0 .../vendor/github.com/jackc/pgx/v5/README.md | 192 + .../vendor/github.com/jackc/pgx/v5/Rakefile | 18 + .../vendor/github.com/jackc/pgx/v5/batch.go | 537 + .../vendor/github.com/jackc/pgx/v5/conn.go | 1471 + .../github.com/jackc/pgx/v5/copy_from.go | 276 + .../github.com/jackc/pgx/v5/derived_types.go | 256 + .../vendor/github.com/jackc/pgx/v5/doc.go | 199 + .../jackc/pgx/v5/extended_query_builder.go | 146 + .../pgx/v5/internal/iobufpool/iobufpool.go | 78 + .../jackc/pgx/v5/internal/pgio/README.md | 6 + .../jackc/{ => pgx/v5/internal}/pgio/doc.go | 0 .../jackc/{ => pgx/v5/internal}/pgio/write.go | 22 +- .../pgx/v5/internal/sanitize/benchmark.sh | 60 + .../pgx/v5/internal/sanitize/sanitize.go | 541 + .../pgx/v5/internal/stmtcache/lru_cache.go | 187 + .../pgx/v5/internal/stmtcache/stmtcache.go | 45 + .../jackc/pgx/{v4 => v5}/large_objects.go | 76 +- .../github.com/jackc/pgx/v5/named_args.go | 295 + .../github.com/jackc/pgx/v5/pgconn/README.md | 29 + .../jackc/pgx/v5/pgconn/auth_oauth.go | 67 + .../jackc/{ => pgx/v5}/pgconn/auth_scram.go | 191 +- .../jackc/{ => pgx/v5}/pgconn/config.go | 422 +- .../v5/pgconn}/ctxwatch/context_watcher.go | 61 +- .../jackc/{ => pgx/v5}/pgconn/defaults.go | 2 - .../{ => pgx/v5}/pgconn/defaults_windows.go | 2 - .../github.com/jackc/pgx/v5/pgconn/doc.go | 38 + .../github.com/jackc/pgx/v5/pgconn/errors.go | 273 + .../v5/pgconn/internal/bgreader/bgreader.go | 139 + .../jackc/{ => pgx/v5}/pgconn/krb5.go | 11 +- .../github.com/jackc/pgx/v5/pgconn/pgconn.go | 2972 ++ .../jackc/pgx/v5/pgproto3/README.md | 7 + .../authentication_cleartext_password.go | 5 +- .../v5/pgproto3}/authentication_gss.go | 2 +- .../pgproto3}/authentication_gss_continue.go | 2 +- .../pgproto3}/authentication_md5_password.go | 2 +- .../v5/pgproto3}/authentication_ok.go | 5 +- .../v5/pgproto3}/authentication_sasl.go | 10 +- .../pgproto3}/authentication_sasl_continue.go | 2 +- .../v5/pgproto3}/authentication_sasl_final.go | 2 +- .../v2 => pgx/v5/pgproto3}/backend.go | 119 +- .../v5/pgproto3}/backend_key_data.go | 35 +- .../v2 => pgx/v5/pgproto3}/big_endian.go | 0 .../{pgproto3/v2 => pgx/v5/pgproto3}/bind.go | 10 +- .../v2 => pgx/v5/pgproto3}/bind_complete.go | 0 .../v2 => pgx/v5/pgproto3}/cancel_request.go | 47 +- .../jackc/pgx/v5/pgproto3/chunkreader.go | 90 + .../{pgproto3/v2 => pgx/v5/pgproto3}/close.go | 0 .../v2 => pgx/v5/pgproto3}/close_complete.go | 0 .../v5/pgproto3}/command_complete.go | 5 +- .../v5/pgproto3}/copy_both_response.go | 4 +- .../v2 => pgx/v5/pgproto3}/copy_data.go | 0 .../v2 => pgx/v5/pgproto3}/copy_done.go | 3 +- .../v2 => pgx/v5/pgproto3}/copy_fail.go | 4 + .../v5/pgproto3}/copy_in_response.go | 4 +- .../v5/pgproto3}/copy_out_response.go | 4 +- .../v2 => pgx/v5/pgproto3}/data_row.go | 19 +- .../v2 => pgx/v5/pgproto3}/describe.go | 0 .../github.com/jackc/pgx/v5/pgproto3/doc.go | 11 + .../v5/pgproto3}/empty_query_response.go | 0 .../v2 => pgx/v5/pgproto3}/error_response.go | 0 .../v2 => pgx/v5/pgproto3}/execute.go | 2 +- .../{pgproto3/v2 => pgx/v5/pgproto3}/flush.go | 0 .../jackc/pgx/v5/pgproto3/frontend.go | 471 + .../v2 => pgx/v5/pgproto3}/function_call.go | 29 +- .../v5/pgproto3}/function_call_response.go | 6 +- .../v2 => pgx/v5/pgproto3}/gss_enc_request.go | 5 +- .../v2 => pgx/v5/pgproto3}/gss_response.go | 0 .../v5/pgproto3/negotiate_protocol_version.go | 93 + .../v2 => pgx/v5/pgproto3}/no_data.go | 0 .../v2 => pgx/v5/pgproto3}/notice_response.go | 0 .../v5/pgproto3}/notification_response.go | 6 +- .../v5/pgproto3}/parameter_description.go | 4 +- .../v5/pgproto3}/parameter_status.go | 0 .../{pgproto3/v2 => pgx/v5/pgproto3}/parse.go | 4 +- .../v2 => pgx/v5/pgproto3}/parse_complete.go | 0 .../v5/pgproto3}/password_message.go | 2 +- .../v2 => pgx/v5/pgproto3}/pgproto3.go | 35 +- .../v5/pgproto3}/portal_suspended.go | 0 .../{pgproto3/v2 => pgx/v5/pgproto3}/query.go | 4 + .../v2 => pgx/v5/pgproto3}/ready_for_query.go | 0 .../v2 => pgx/v5/pgproto3}/row_description.go | 5 +- .../v5/pgproto3}/sasl_initial_response.go | 14 +- .../v2 => pgx/v5/pgproto3}/sasl_response.go | 9 +- .../v2 => pgx/v5/pgproto3}/ssl_request.go | 5 +- .../v2 => pgx/v5/pgproto3}/startup_message.go | 17 +- .../{pgproto3/v2 => pgx/v5/pgproto3}/sync.go | 0 .../v2 => pgx/v5/pgproto3}/terminate.go | 0 .../github.com/jackc/pgx/v5/pgproto3/trace.go | 416 + .../jackc/{ => pgx/v5}/pgtype/array.go | 187 +- .../jackc/pgx/v5/pgtype/array_codec.go | 405 + .../github.com/jackc/pgx/v5/pgtype/bits.go | 211 + .../github.com/jackc/pgx/v5/pgtype/bool.go | 346 + .../github.com/jackc/pgx/v5/pgtype/box.go | 239 + .../jackc/pgx/v5/pgtype/builtin_wrappers.go | 952 + .../github.com/jackc/pgx/v5/pgtype/bytea.go | 254 + .../github.com/jackc/pgx/v5/pgtype/circle.go | 224 + .../jackc/pgx/v5/pgtype/composite.go | 601 + .../github.com/jackc/pgx/v5/pgtype/convert.go | 108 + .../github.com/jackc/pgx/v5/pgtype/date.go | 414 + .../github.com/jackc/pgx/v5/pgtype/doc.go | 196 + .../jackc/pgx/v5/pgtype/enum_codec.go | 109 + .../github.com/jackc/pgx/v5/pgtype/float4.go | 323 + .../github.com/jackc/pgx/v5/pgtype/float8.go | 369 + .../github.com/jackc/pgx/v5/pgtype/hstore.go | 494 + .../github.com/jackc/pgx/v5/pgtype/inet.go | 199 + .../github.com/jackc/pgx/v5/pgtype/int.go | 1990 + .../github.com/jackc/pgx/v5/pgtype/int.go.erb | 551 + .../jackc/pgx/v5/pgtype/int_test.go.erb | 93 + .../pgtype/integration_benchmark_test.go.erb | 62 + .../pgtype/integration_benchmark_test_gen.sh | 2 + .../jackc/pgx/v5/pgtype/interval.go | 300 + .../github.com/jackc/pgx/v5/pgtype/json.go | 243 + .../github.com/jackc/pgx/v5/pgtype/jsonb.go | 129 + .../github.com/jackc/pgx/v5/pgtype/line.go | 226 + .../github.com/jackc/pgx/v5/pgtype/lseg.go | 239 + .../github.com/jackc/pgx/v5/pgtype/ltree.go | 122 + .../github.com/jackc/pgx/v5/pgtype/macaddr.go | 162 + .../jackc/pgx/v5/pgtype/multirange.go | 447 + .../github.com/jackc/pgx/v5/pgtype/numeric.go | 836 + .../github.com/jackc/pgx/v5/pgtype/path.go | 273 + .../github.com/jackc/pgx/v5/pgtype/pgtype.go | 2067 + .../jackc/pgx/v5/pgtype/pgtype_default.go | 251 + .../github.com/jackc/pgx/v5/pgtype/point.go | 269 + .../github.com/jackc/pgx/v5/pgtype/polygon.go | 254 + .../github.com/jackc/pgx/v5/pgtype/qchar.go | 141 + .../jackc/{ => pgx/v5}/pgtype/range.go | 82 +- .../jackc/pgx/v5/pgtype/range_codec.go | 379 + .../jackc/pgx/v5/pgtype/record_codec.go | 124 + .../v5/pgtype/register_default_pg_types.go | 35 + .../register_default_pg_types_disabled.go | 6 + .../github.com/jackc/pgx/v5/pgtype/text.go | 226 + .../pgx/v5/pgtype/text_format_only_codec.go | 13 + .../github.com/jackc/pgx/v5/pgtype/tid.go | 242 + .../github.com/jackc/pgx/v5/pgtype/time.go | 275 + .../jackc/pgx/v5/pgtype/timestamp.go | 370 + .../jackc/pgx/v5/pgtype/timestamptz.go | 371 + .../jackc/pgx/v5/pgtype/tsvector.go | 507 + .../github.com/jackc/pgx/v5/pgtype/uint32.go | 352 + .../github.com/jackc/pgx/v5/pgtype/uint64.go | 323 + .../github.com/jackc/pgx/v5/pgtype/uuid.go | 293 + .../github.com/jackc/pgx/v5/pgtype/xml.go | 198 + .../jackc/pgx/v5/pgxpool/batch_results.go | 52 + .../github.com/jackc/pgx/v5/pgxpool/conn.go | 134 + .../github.com/jackc/pgx/v5/pgxpool/doc.go | 27 + .../github.com/jackc/pgx/v5/pgxpool/pool.go | 832 + .../github.com/jackc/pgx/v5/pgxpool/rows.go | 116 + .../github.com/jackc/pgx/v5/pgxpool/stat.go | 91 + .../github.com/jackc/pgx/v5/pgxpool/tracer.go | 33 + .../github.com/jackc/pgx/v5/pgxpool/tx.go | 83 + .../vendor/github.com/jackc/pgx/v5/rows.go | 871 + .../jackc/pgx/{v4 => v5}/stdlib/sql.go | 472 +- .../vendor/github.com/jackc/pgx/v5/test.sh | 170 + .../vendor/github.com/jackc/pgx/v5/tracer.go | 107 + .../github.com/jackc/pgx/{v4 => v5}/tx.go | 240 +- .../vendor/github.com/jackc/pgx/v5/values.go | 63 + .../github.com/jackc/puddle/v2/CHANGELOG.md | 79 + .../jackc/{pgio => puddle/v2}/LICENSE | 2 +- .../github.com/jackc/puddle/v2/README.md | 80 + .../github.com/jackc/puddle/v2/context.go | 24 + .../vendor/github.com/jackc/puddle/v2/doc.go | 11 + .../puddle/v2/internal/genstack/gen_stack.go | 85 + .../puddle/v2/internal/genstack/stack.go | 39 + .../vendor/github.com/jackc/puddle/v2/log.go | 32 + .../github.com/jackc/puddle/v2/nanotime.go | 16 + .../vendor/github.com/jackc/puddle/v2/pool.go | 710 + .../jackc/puddle/v2/resource_list.go | 28 + .../klauspost/compress/.goreleaser.yml | 11 +- .../github.com/klauspost/compress/README.md | 45 +- .../klauspost/compress/fse/bitwriter.go | 2 +- .../klauspost/compress/fse/compress.go | 2 +- .../klauspost/compress/huff0/bitwriter.go | 2 +- .../klauspost/compress/huff0/compress.go | 6 +- .../klauspost/compress/huff0/decompress.go | 14 +- .../compress/huff0/decompress_amd64.go | 8 +- .../compress/huff0/decompress_generic.go | 1 - .../klauspost/compress/huff0/huff0.go | 4 +- .../internal/cpuinfo/cpuinfo_amd64.go | 1 - .../compress/internal/le/unsafe_disabled.go | 4 +- .../compress/internal/le/unsafe_enabled.go | 9 +- .../compress/internal/snapref/decode.go | 2 +- .../compress/internal/snapref/encode.go | 4 +- .../klauspost/compress/zstd/bitwriter.go | 2 +- .../klauspost/compress/zstd/blockdec.go | 6 +- .../klauspost/compress/zstd/blockenc.go | 1 + .../klauspost/compress/zstd/decoder.go | 36 +- .../compress/zstd/decoder_options.go | 60 +- .../klauspost/compress/zstd/dict.go | 20 +- .../klauspost/compress/zstd/enc_base.go | 12 +- .../klauspost/compress/zstd/enc_best.go | 37 +- .../klauspost/compress/zstd/enc_better.go | 44 +- .../klauspost/compress/zstd/enc_dfast.go | 38 +- .../klauspost/compress/zstd/enc_fast.go | 36 +- .../klauspost/compress/zstd/encoder.go | 29 + .../compress/zstd/encoder_options.go | 45 +- .../klauspost/compress/zstd/framedec.go | 5 +- .../compress/zstd/fse_decoder_amd64.go | 1 - .../compress/zstd/fse_decoder_generic.go | 1 - .../klauspost/compress/zstd/fse_encoder.go | 2 +- .../zstd/internal/xxhash/xxhash_other.go | 1 - .../klauspost/compress/zstd/matchlen_amd64.go | 1 - .../compress/zstd/matchlen_generic.go | 1 - .../klauspost/compress/zstd/seqdec.go | 5 +- .../klauspost/compress/zstd/seqdec_amd64.go | 11 +- .../klauspost/compress/zstd/seqdec_generic.go | 1 - .../klauspost/compress/zstd/simple_go124.go | 56 + .../klauspost/compress/zstd/snappy.go | 2 +- .../github.com/klauspost/compress/zstd/zip.go | 2 +- .../klauspost/compress/zstd/zstd.go | 4 +- .../github.com/klauspost/cpuid/v2/README.md | 9 +- .../github.com/klauspost/cpuid/v2/cpuid.go | 119 +- .../klauspost/cpuid/v2/detect_x86.go | 4 + .../klauspost/cpuid/v2/featureid_string.go | 445 +- .../klauspost/cpuid/v2/os_darwin_arm64.go | 80 +- .../vendor/github.com/libdns/libdns/README.md | 25 +- .../vendor/github.com/libdns/libdns/libdns.go | 109 +- .../vendor/github.com/libdns/libdns/record.go | 41 +- .../github.com/libdns/libdns/rrtypes.go | 77 +- .../mattn/go-colorable/colorable_appengine.go | 38 - .../mattn/go-colorable/colorable_others.go | 4 +- .../mattn/go-colorable/colorable_windows.go | 22 +- .../github.com/mholt/acmez/v3/README.md | 3 +- .../github.com/mholt/acmez/v3/acme/account.go | 11 +- .../github.com/mholt/acmez/v3/acme/ari.go | 7 +- .../mholt/acmez/v3/acme/certificate.go | 2 +- .../mholt/acmez/v3/acme/challenge.go | 17 + .../github.com/mholt/acmez/v3/acme/client.go | 2 +- .../github.com/mholt/acmez/v3/acme/http.go | 2 +- .../github.com/mholt/acmez/v3/acme/jws.go | 2 +- .../github.com/mholt/acmez/v3/acme/order.go | 2 +- .../github.com/mholt/acmez/v3/acme/problem.go | 1 + .../github.com/mholt/acmez/v3/client.go | 17 +- .../vendor/github.com/mholt/acmez/v3/csr.go | 2 +- .../github.com/mholt/acmez/v3/tlsalpn01.go | 29 +- .../vendor/github.com/miekg/dns/README.md | 313 +- .../vendor/github.com/miekg/dns/client.go | 10 +- .../vendor/github.com/miekg/dns/edns.go | 178 +- .../vendor/github.com/miekg/dns/msg.go | 55 +- .../vendor/github.com/miekg/dns/reverse.go | 5 +- .../vendor/github.com/miekg/dns/scan.go | 19 +- .../vendor/github.com/miekg/dns/scan_rr.go | 10 + .../vendor/github.com/miekg/dns/server.go | 6 +- .../vendor/github.com/miekg/dns/svcb.go | 70 +- .../vendor/github.com/miekg/dns/types.go | 92 +- .../vendor/github.com/miekg/dns/udp.go | 4 +- .../dns/{udp_windows.go => udp_no_control.go} | 6 +- .../vendor/github.com/miekg/dns/update.go | 7 + .../vendor/github.com/miekg/dns/version.go | 2 +- .../vendor/github.com/miekg/dns/xfr.go | 7 +- .../vendor/github.com/miekg/dns/zduplicate.go | 17 + .../vendor/github.com/miekg/dns/zmsg.go | 439 +- .../vendor/github.com/miekg/dns/ztypes.go | 15 + .../vendor/github.com/onsi/ginkgo/v2/LICENSE | 20 - .../onsi/ginkgo/v2/config/deprecated.go | 69 - .../ginkgo/v2/formatter/colorable_others.go | 41 - .../ginkgo/v2/formatter/colorable_windows.go | 809 - .../onsi/ginkgo/v2/formatter/formatter.go | 230 - .../ginkgo/v2/ginkgo/build/build_command.go | 63 - .../onsi/ginkgo/v2/ginkgo/command/abort.go | 61 - .../onsi/ginkgo/v2/ginkgo/command/command.go | 50 - .../onsi/ginkgo/v2/ginkgo/command/program.go | 182 - .../ginkgo/generators/boostrap_templates.go | 48 - .../v2/ginkgo/generators/bootstrap_command.go | 133 - .../v2/ginkgo/generators/generate_command.go | 264 - .../ginkgo/generators/generate_templates.go | 43 - .../v2/ginkgo/generators/generators_common.go | 76 - .../onsi/ginkgo/v2/ginkgo/internal/compile.go | 161 - .../ginkgo/internal/profiles_and_reports.go | 237 - .../onsi/ginkgo/v2/ginkgo/internal/run.go | 355 - .../ginkgo/v2/ginkgo/internal/test_suite.go | 284 - .../onsi/ginkgo/v2/ginkgo/internal/utils.go | 86 - .../v2/ginkgo/internal/verify_version.go | 54 - .../ginkgo/v2/ginkgo/labels/labels_command.go | 123 - .../github.com/onsi/ginkgo/v2/ginkgo/main.go | 58 - .../onsi/ginkgo/v2/ginkgo/outline/ginkgo.go | 301 - .../onsi/ginkgo/v2/ginkgo/outline/import.go | 58 - .../onsi/ginkgo/v2/ginkgo/outline/outline.go | 110 - .../v2/ginkgo/outline/outline_command.go | 98 - .../onsi/ginkgo/v2/ginkgo/run/run_command.go | 232 - .../v2/ginkgo/unfocus/unfocus_command.go | 186 - .../onsi/ginkgo/v2/ginkgo/watch/delta.go | 22 - .../ginkgo/v2/ginkgo/watch/delta_tracker.go | 75 - .../ginkgo/v2/ginkgo/watch/dependencies.go | 92 - .../ginkgo/v2/ginkgo/watch/package_hash.go | 108 - .../ginkgo/v2/ginkgo/watch/package_hashes.go | 85 - .../onsi/ginkgo/v2/ginkgo/watch/suite.go | 87 - .../ginkgo/v2/ginkgo/watch/watch_command.go | 192 - .../interrupt_handler/interrupt_handler.go | 177 - .../sigquit_swallower_unix.go | 15 - .../sigquit_swallower_windows.go | 8 - .../parallel_support/client_server.go | 72 - .../internal/parallel_support/http_client.go | 169 - .../internal/parallel_support/http_server.go | 242 - .../internal/parallel_support/rpc_client.go | 136 - .../internal/parallel_support/rpc_server.go | 75 - .../parallel_support/server_handler.go | 234 - .../ginkgo/v2/reporters/default_reporter.go | 759 - .../v2/reporters/deprecated_reporter.go | 149 - .../onsi/ginkgo/v2/reporters/json_report.go | 69 - .../onsi/ginkgo/v2/reporters/junit_report.go | 388 - .../onsi/ginkgo/v2/reporters/reporter.go | 29 - .../ginkgo/v2/reporters/teamcity_report.go | 105 - .../onsi/ginkgo/v2/types/code_location.go | 159 - .../github.com/onsi/ginkgo/v2/types/config.go | 758 - .../onsi/ginkgo/v2/types/deprecated_types.go | 141 - .../ginkgo/v2/types/deprecation_support.go | 177 - .../onsi/ginkgo/v2/types/enum_support.go | 43 - .../github.com/onsi/ginkgo/v2/types/errors.go | 639 - .../onsi/ginkgo/v2/types/file_filter.go | 106 - .../github.com/onsi/ginkgo/v2/types/flags.go | 489 - .../onsi/ginkgo/v2/types/label_filter.go | 358 - .../onsi/ginkgo/v2/types/report_entry.go | 190 - .../github.com/onsi/ginkgo/v2/types/types.go | 914 - .../onsi/ginkgo/v2/types/version.go | 3 - .../client_golang/prometheus/desc.go | 3 +- .../prometheus/internal/difflib.go | 4 +- .../prometheus/internal/go_runtime_metrics.go | 2 +- .../client_golang/prometheus/labels.go | 3 +- .../client_golang/prometheus/metric.go | 25 +- .../prometheus/process_collector_darwin.go | 6 +- .../process_collector_mem_nocgo_darwin.go | 2 +- .../process_collector_procfsenabled.go | 8 +- .../prometheus/promhttp/instrument_server.go | 2 +- .../client_golang/prometheus/vec.go | 10 +- .../client_golang/prometheus/wrap.go | 36 +- .../prometheus/common/expfmt/decode.go | 53 +- .../prometheus/common/expfmt/encode.go | 10 +- .../prometheus/common/expfmt/expfmt.go | 13 +- .../prometheus/common/expfmt/fuzz.go | 10 +- .../common/expfmt/openmetrics_create.go | 70 +- .../prometheus/common/expfmt/text_create.go | 66 +- .../prometheus/common/expfmt/text_parse.go | 146 +- .../prometheus/common/model/alert.go | 2 +- .../prometheus/common/model/labels.go | 36 +- .../prometheus/common/model/labelset.go | 10 +- .../prometheus/common/model/metric.go | 224 +- .../prometheus/common/model/time.go | 37 +- .../prometheus/common/model/value.go | 15 +- .../common/model/value_histogram.go | 10 +- .../prometheus/common/model/value_type.go | 4 +- .../otlptranslator}/.gitignore | 10 + .../prometheus/otlptranslator/.golangci.yml | 104 + .../otlptranslator/CODE_OF_CONDUCT.md | 3 + .../prometheus/otlptranslator}/LICENSE | 0 .../prometheus/otlptranslator/MAINTAINERS.md | 4 + .../prometheus/otlptranslator/README.md | 120 + .../prometheus/otlptranslator/SECURITY.md | 6 + .../prometheus/otlptranslator/constants.go | 38 + .../prometheus/otlptranslator/doc.go | 24 + .../prometheus/otlptranslator/label_namer.go | 100 + .../prometheus/otlptranslator/metric_namer.go | 361 + .../prometheus/otlptranslator/metric_type.go | 36 + .../prometheus/otlptranslator/strategy.go | 86 + .../prometheus/otlptranslator/strconv.go | 116 + .../prometheus/otlptranslator/unit_namer.go | 129 + .../prometheus/procfs/.golangci.yml | 77 +- .../github.com/prometheus/procfs/Makefile | 2 +- .../prometheus/procfs/Makefile.common | 266 +- .../github.com/prometheus/procfs/README.md | 6 +- .../github.com/prometheus/procfs/arp.go | 13 +- .../github.com/prometheus/procfs/buddyinfo.go | 10 +- .../github.com/prometheus/procfs/cmdline.go | 2 +- .../github.com/prometheus/procfs/cpuinfo.go | 5 +- .../prometheus/procfs/cpuinfo_armx.go | 4 +- .../prometheus/procfs/cpuinfo_loong64.go | 3 +- .../prometheus/procfs/cpuinfo_mipsx.go | 4 +- .../prometheus/procfs/cpuinfo_others.go | 3 +- .../prometheus/procfs/cpuinfo_ppcx.go | 4 +- .../prometheus/procfs/cpuinfo_riscvx.go | 4 +- .../prometheus/procfs/cpuinfo_s390x.go | 3 +- .../prometheus/procfs/cpuinfo_x86.go | 4 +- .../github.com/prometheus/procfs/crypto.go | 2 +- .../github.com/prometheus/procfs/doc.go | 2 +- .../vendor/github.com/prometheus/procfs/fs.go | 12 +- .../prometheus/procfs/fs_statfs_notype.go | 7 +- .../prometheus/procfs/fs_statfs_type.go | 3 +- .../github.com/prometheus/procfs/fscache.go | 15 +- .../prometheus/procfs/internal/fs/fs.go | 5 +- .../prometheus/procfs/internal/util/parse.go | 16 +- .../procfs/internal/util/readfile.go | 2 +- .../procfs/internal/util/sysreadfile.go | 24 +- .../internal/util/sysreadfile_compat.go | 3 +- .../procfs/internal/util/valueparser.go | 2 +- .../github.com/prometheus/procfs/ipvs.go | 2 +- .../prometheus/procfs/kernel_hung.go | 44 + .../prometheus/procfs/kernel_random.go | 3 +- .../github.com/prometheus/procfs/loadavg.go | 2 +- .../github.com/prometheus/procfs/mdstat.go | 121 +- .../github.com/prometheus/procfs/meminfo.go | 35 +- .../github.com/prometheus/procfs/mountinfo.go | 23 +- .../prometheus/procfs/mountstats.go | 31 +- .../prometheus/procfs/net_conntrackstat.go | 2 +- .../github.com/prometheus/procfs/net_dev.go | 2 +- .../prometheus/procfs/net_dev_snmp6.go | 99 + .../prometheus/procfs/net_ip_socket.go | 10 +- .../prometheus/procfs/net_protocols.go | 25 +- .../github.com/prometheus/procfs/net_route.go | 2 +- .../prometheus/procfs/net_sockstat.go | 5 +- .../prometheus/procfs/net_softnet.go | 2 +- .../github.com/prometheus/procfs/net_tcp.go | 10 +- .../prometheus/procfs/net_tls_stat.go | 2 +- .../github.com/prometheus/procfs/net_udp.go | 2 +- .../github.com/prometheus/procfs/net_unix.go | 10 +- .../prometheus/procfs/net_wireless.go | 2 +- .../github.com/prometheus/procfs/net_xfrm.go | 2 +- .../github.com/prometheus/procfs/netstat.go | 2 +- .../prometheus/procfs/nfnetlink_queue.go | 85 + .../github.com/prometheus/procfs/proc.go | 12 +- .../prometheus/procfs/proc_cgroup.go | 4 +- .../prometheus/procfs/proc_cgroups.go | 8 +- .../prometheus/procfs/proc_environ.go | 2 +- .../prometheus/procfs/proc_fdinfo.go | 13 +- .../prometheus/procfs/proc_interrupts.go | 4 +- .../github.com/prometheus/procfs/proc_io.go | 4 +- .../prometheus/procfs/proc_limits.go | 7 +- .../github.com/prometheus/procfs/proc_maps.go | 4 +- .../prometheus/procfs/proc_netstat.go | 226 +- .../github.com/prometheus/procfs/proc_ns.go | 2 +- .../github.com/prometheus/procfs/proc_psi.go | 2 +- .../prometheus/procfs/proc_smaps.go | 7 +- .../github.com/prometheus/procfs/proc_snmp.go | 122 +- .../prometheus/procfs/proc_snmp6.go | 152 +- .../github.com/prometheus/procfs/proc_stat.go | 14 +- .../prometheus/procfs/proc_statm.go | 117 + .../prometheus/procfs/proc_status.go | 70 +- .../github.com/prometheus/procfs/proc_sys.go | 4 +- .../github.com/prometheus/procfs/schedstat.go | 2 +- .../github.com/prometheus/procfs/slab.go | 2 +- .../github.com/prometheus/procfs/softirqs.go | 24 +- .../github.com/prometheus/procfs/stat.go | 5 +- .../github.com/prometheus/procfs/swaps.go | 2 +- .../github.com/prometheus/procfs/thread.go | 2 +- .../vendor/github.com/prometheus/procfs/vm.go | 3 +- .../github.com/prometheus/procfs/zoneinfo.go | 9 +- .../github.com/quic-go/qpack/.gitmodules | 4 +- .../github.com/quic-go/qpack/.golangci.yml | 19 +- .../vendor/github.com/quic-go/qpack/README.md | 6 +- .../github.com/quic-go/qpack/decoder.go | 260 +- .../github.com/quic-go/qpack/static_table.go | 2 +- .../vendor/github.com/quic-go/qpack/varint.go | 11 +- .../github.com/quic-go/quic-go/.golangci.yml | 132 +- .../github.com/quic-go/quic-go/Changelog.md | 109 - .../github.com/quic-go/quic-go/README.md | 13 +- .../github.com/quic-go/quic-go/SECURITY.md | 17 +- .../github.com/quic-go/quic-go/client.go | 27 +- .../github.com/quic-go/quic-go/codecov.yml | 5 +- .../github.com/quic-go/quic-go/config.go | 39 +- .../quic-go/quic-go/conn_id_generator.go | 134 +- .../quic-go/quic-go/conn_id_manager.go | 90 +- .../github.com/quic-go/quic-go/connection.go | 2521 +- .../quic-go/quic-go/connection_logging.go | 321 +- .../quic-go/quic-go/connection_timer.go | 51 - .../quic-go/quic-go/crypto_stream.go | 182 +- .../quic-go/quic-go/crypto_stream_manager.go | 20 +- .../github.com/quic-go/quic-go/errors.go | 82 +- .../quic-go/quic-go/frame_sorter.go | 37 + .../github.com/quic-go/quic-go/framer.go | 18 +- .../github.com/quic-go/quic-go/http3/body.go | 20 +- .../quic-go/quic-go/http3/capsule.go | 17 +- .../quic-go/quic-go/http3/client.go | 370 +- .../github.com/quic-go/quic-go/http3/conn.go | 462 +- .../quic-go/quic-go/http3/datagram.go | 98 - .../quic-go/quic-go/http3/error_codes.go | 39 +- .../quic-go/quic-go/http3/frames.go | 216 +- .../quic-go/quic-go/http3/headers.go | 254 +- .../quic-go/quic-go/http3/http_stream.go | 294 - .../quic-go/quic-go/http3/mockgen.go | 7 +- .../github.com/quic-go/quic-go/http3/qlog.go | 56 + .../quic-go/quic-go/http3/qlog/event.go | 138 + .../quic-go/quic-go/http3/qlog/frame.go | 220 + .../quic-go/quic-go/http3/qlog/qlog_dir.go | 15 + .../quic-go/quic-go/http3/request_writer.go | 62 +- .../quic-go/quic-go/http3/response_writer.go | 93 +- .../quic-go/quic-go/http3/server.go | 511 +- .../quic-go/quic-go/http3/server_conn.go | 261 + .../quic-go/http3/state_tracking_stream.go | 93 +- .../quic-go/quic-go/http3/stream.go | 406 + .../github.com/quic-go/quic-go/http3/trace.go | 4 +- .../quic-go/quic-go/http3/transport.go | 172 +- .../github.com/quic-go/quic-go/interface.go | 253 +- .../internal/ackhandler/ack_eliciting.go | 13 + .../quic-go/internal/ackhandler/ackhandler.go | 24 - .../quic-go/internal/ackhandler/ecn.go | 98 +- .../quic-go/internal/ackhandler/interfaces.go | 39 +- .../ackhandler/lost_packet_tracker.go | 73 + .../quic-go/internal/ackhandler/mockgen.go | 5 +- .../quic-go/internal/ackhandler/packet.go | 26 +- .../ackhandler/received_packet_handler.go | 40 +- .../ackhandler/received_packet_history.go | 44 +- .../ackhandler/received_packet_tracker.go | 47 +- .../ackhandler/sent_packet_handler.go | 506 +- .../ackhandler/sent_packet_history.go | 138 +- .../quic-go/internal/congestion/bandwidth.go | 3 - .../quic-go/internal/congestion/clock.go | 10 +- .../quic-go/internal/congestion/cubic.go | 11 +- .../internal/congestion/cubic_sender.go | 68 +- .../quic-go/internal/congestion/interface.go | 11 +- .../quic-go/internal/congestion/pacer.go | 44 +- .../flowcontrol/base_flow_controller.go | 9 +- .../flowcontrol/connection_flow_controller.go | 14 +- .../quic-go/internal/flowcontrol/interface.go | 11 +- .../flowcontrol/stream_flow_controller.go | 10 +- .../quic-go/internal/handshake/aead.go | 2 +- .../internal/handshake/cipher_suite.go | 8 +- .../internal/handshake/crypto_setup.go | 175 +- .../internal/handshake/header_protector.go | 6 +- .../quic-go/internal/handshake/interface.go | 4 +- .../internal/handshake/session_ticket.go | 28 +- .../internal/handshake/token_generator.go | 8 +- .../internal/handshake/updatable_aead.go | 102 +- .../quic-go/quic-go/internal/monotime/time.go | 90 + .../internal/protocol/connection_id.go | 6 +- .../quic-go/internal/protocol/params.go | 15 +- .../quic-go/internal/protocol/protocol.go | 7 + .../quic-go/internal/protocol/stream.go | 26 + .../quic-go/internal/protocol/version.go | 35 +- .../internal/utils/buffered_write_closer.go | 2 +- .../quic-go/internal/utils/connstats.go | 14 + .../quic-go/quic-go/internal/utils/log.go | 14 +- .../quic-go/internal/utils/rtt_stats.go | 100 +- .../quic-go/quic-go/internal/utils/timer.go | 57 - .../quic-go/internal/wire/ack_frame.go | 77 +- .../internal/wire/ack_frequency_frame.go | 65 + .../internal/wire/connection_close_frame.go | 8 +- .../quic-go/internal/wire/crypto_frame.go | 2 +- .../internal/wire/data_blocked_frame.go | 2 +- .../quic-go/internal/wire/datagram_frame.go | 4 +- .../quic-go/internal/wire/extended_header.go | 2 - .../quic-go/quic-go/internal/wire/frame.go | 12 + .../quic-go/internal/wire/frame_parser.go | 251 +- .../quic-go/internal/wire/frame_type.go | 81 + .../internal/wire/handshake_done_frame.go | 2 +- .../internal/wire/immediate_ack_frame.go | 18 + .../quic-go/internal/wire/max_data_frame.go | 2 +- .../internal/wire/max_stream_data_frame.go | 2 +- .../internal/wire/max_streams_frame.go | 11 +- .../internal/wire/new_connection_id_frame.go | 4 +- .../quic-go/internal/wire/new_token_frame.go | 2 +- .../internal/wire/path_challenge_frame.go | 2 +- .../internal/wire/path_response_frame.go | 2 +- .../quic-go/internal/wire/ping_frame.go | 2 +- .../quic-go/quic-go/internal/wire/pool.go | 2 +- .../internal/wire/reset_stream_frame.go | 58 +- .../wire/retire_connection_id_frame.go | 2 +- .../internal/wire/stop_sending_frame.go | 2 +- .../quic-go/internal/wire/stream_frame.go | 2 +- .../internal/wire/streams_blocked_frame.go | 11 +- .../internal/wire/transport_parameters.go | 91 +- .../internal/wire/version_negotiation.go | 4 +- .../quic-go/logging/connection_tracer.go | 44 - .../logging/connection_tracer_multiplexer.go | 236 - .../quic-go/quic-go/logging/frame.go | 66 - .../quic-go/logging/generate_multiplexer.go | 161 - .../quic-go/quic-go/logging/interface.go | 111 - .../quic-go/quic-go/logging/multiplexer.tmpl | 21 - .../quic-go/quic-go/logging/packet_header.go | 24 - .../quic-go/quic-go/logging/tracer.go | 14 - .../quic-go/logging/tracer_multiplexer.go | 51 - .../quic-go/quic-go/logging/types.go | 130 - .../github.com/quic-go/quic-go/mockgen.go | 51 +- .../quic-go/quic-go/mtu_discoverer.go | 37 +- .../github.com/quic-go/quic-go/oss-fuzz.sh | 6 +- .../quic-go/quic-go/packet_handler_map.go | 228 - .../quic-go/quic-go/packet_packer.go | 260 +- .../quic-go/quic-go/packet_unpacker.go | 9 +- .../quic-go/quic-go/path_manager.go | 129 +- .../quic-go/quic-go/path_manager_outgoing.go | 314 + .../quic-go/quic-go/qlog/connection_tracer.go | 461 - .../github.com/quic-go/quic-go/qlog/event.go | 1121 +- .../github.com/quic-go/quic-go/qlog/frame.go | 554 +- .../quic-go/quic-go/qlog/packet_header.go | 207 +- .../quic-go/quic-go/qlog/qlog_dir.go | 40 +- .../github.com/quic-go/quic-go/qlog/trace.go | 101 - .../github.com/quic-go/quic-go/qlog/tracer.go | 60 - .../github.com/quic-go/quic-go/qlog/types.go | 452 +- .../github.com/quic-go/quic-go/qlog/writer.go | 98 - .../quic-go/qlogwriter/jsontext/encoder.go | 324 + .../quic-go/quic-go/qlogwriter/trace.go | 124 + .../quic-go/quic-go/qlogwriter/writer.go | 229 + .../quic-go/quic-go/quicvarint/io.go | 36 +- .../quic-go/quic-go/quicvarint/varint.go | 68 +- .../quic-go/quic-go/receive_stream.go | 255 +- .../quic-go/quic-go/retransmission_queue.go | 158 +- .../github.com/quic-go/quic-go/send_stream.go | 426 +- .../github.com/quic-go/quic-go/server.go | 411 +- .../vendor/github.com/quic-go/quic-go/sni.go | 136 + .../github.com/quic-go/quic-go/stream.go | 165 +- .../github.com/quic-go/quic-go/streams_map.go | 274 +- .../quic-go/quic-go/streams_map_incoming.go | 106 +- .../quic-go/quic-go/streams_map_outgoing.go | 138 +- .../github.com/quic-go/quic-go/sys_conn.go | 34 +- .../quic-go/quic-go/sys_conn_helper_darwin.go | 2 +- .../quic-go/quic-go/sys_conn_helper_linux.go | 2 +- .../quic-go/quic-go/sys_conn_oob.go | 19 +- .../github.com/quic-go/quic-go/tools.go | 8 - .../github.com/quic-go/quic-go/transport.go | 290 +- .../vendor/github.com/rs/xid/.gitignore | 3 + .../vendor/github.com/rs/xid/README.md | 10 +- .../vendor/github.com/rs/xid/hostid_darwin.go | 29 +- .../github.com/rs/xid/hostid_windows.go | 20 +- .../traefik/vendor/github.com/rs/xid/id.go | 13 +- .../github.com/slackhq/nebula/cert/Makefile | 2 +- .../github.com/slackhq/nebula/cert/README.md | 19 +- .../github.com/slackhq/nebula/cert/asn1.go | 52 + .../github.com/slackhq/nebula/cert/ca.go | 134 - .../github.com/slackhq/nebula/cert/ca_pool.go | 314 + .../github.com/slackhq/nebula/cert/cert.go | 666 +- .../github.com/slackhq/nebula/cert/cert.pb.go | 298 - .../github.com/slackhq/nebula/cert/cert_v1.go | 502 + .../slackhq/nebula/cert/cert_v1.pb.go | 620 + .../nebula/cert/{cert.proto => cert_v1.proto} | 27 +- .../slackhq/nebula/cert/cert_v2.asn1 | 37 + .../github.com/slackhq/nebula/cert/cert_v2.go | 742 + .../github.com/slackhq/nebula/cert/crypto.go | 300 + .../github.com/slackhq/nebula/cert/errors.go | 50 +- .../slackhq/nebula/cert/p256/p256.go | 122 + .../github.com/slackhq/nebula/cert/pem.go | 191 + .../github.com/slackhq/nebula/cert/sign.go | 170 + .../smallstep/certificates/acme/wire/id.go | 91 + .../smallstep/certificates/api/log/log.go | 34 +- .../certificates/api/render/render.go | 22 +- .../certificates/authority/admin/db.go | 2 +- .../authority/admin/db/nosql/admin.go | 2 +- .../authority/admin/db/nosql/policy.go | 2 +- .../authority/admin/db/nosql/provisioner.go | 2 +- .../certificates/authority/admin/errors.go | 4 +- .../authority/administrator/collection.go | 2 +- .../certificates/authority/admins.go | 2 +- .../certificates/authority/authority.go | 90 +- .../certificates/authority/authorize.go | 55 +- .../certificates/authority/config/config.go | 4 +- .../certificates/authority/export.go | 8 +- .../certificates/authority/http_client.go | 56 + .../certificates/authority/linkedca.go | 26 +- .../smallstep/certificates/authority/meter.go | 36 +- .../certificates/authority/options.go | 20 +- .../certificates/authority/policy.go | 2 +- .../certificates/authority/policy/engine.go | 6 +- .../certificates/authority/policy/policy.go | 6 +- .../authority/poolhttp/poolhttp.go | 94 + .../authority/provisioner/acme.go | 75 +- .../certificates/authority/provisioner/aws.go | 4 +- .../provisioner/aws_certificates.pem | 452 +- .../authority/provisioner/azure.go | 8 +- .../authority/provisioner/claims.go | 24 +- .../authority/provisioner/collection.go | 8 +- .../authority/provisioner/controller.go | 53 +- .../certificates/authority/provisioner/gcp.go | 159 +- .../provisioner/gcp/projectvalidator.go | 84 + .../certificates/authority/provisioner/jwk.go | 25 +- .../authority/provisioner/k8sSA.go | 4 +- .../authority/provisioner/keystore.go | 58 +- .../authority/provisioner/method.go | 14 + .../authority/provisioner/nebula.go | 144 +- .../authority/provisioner/oidc.go | 28 +- .../authority/provisioner/options.go | 18 +- .../authority/provisioner/provisioner.go | 51 +- .../authority/provisioner/scep.go | 68 +- .../authority/provisioner/sign_options.go | 94 +- .../authority/provisioner/sign_ssh_options.go | 62 +- .../authority/provisioner/ssh_options.go | 3 +- .../authority/provisioner/sshpop.go | 12 +- .../authority/provisioner/timeduration.go | 11 + .../authority/provisioner/webhook.go | 101 +- .../provisioner/wire/dpop_options.go | 49 + .../provisioner/wire/oidc_options.go | 179 + .../provisioner/wire/wire_options.go | 51 + .../certificates/authority/provisioner/x5c.go | 25 +- .../certificates/authority/provisioners.go | 47 +- .../smallstep/certificates/authority/root.go | 23 + .../smallstep/certificates/authority/ssh.go | 51 +- .../smallstep/certificates/authority/tls.go | 69 +- .../certificates/cas/apiv1/services.go | 10 +- .../certificates/cas/softcas/softcas.go | 7 + .../smallstep/certificates/db/db.go | 9 +- .../smallstep/certificates/errs/error.go | 67 +- .../certificates/internal/cast/cast.go | 108 + .../internal/httptransport/httptransport.go | 37 + .../smallstep/certificates/policy/engine.go | 2 +- .../smallstep/certificates/scep/authority.go | 18 +- .../certificates/scep/provisioner.go | 2 +- .../smallstep/certificates/scep/scep.go | 9 + .../certificates/templates/templates.go | 31 +- .../certificates/templates/values.go | 4 +- .../smallstep/certificates/webhook/types.go | 16 +- .../github.com/smallstep/cli-utils/LICENSE | 201 + .../smallstep}/cli-utils/command/command.go | 5 +- .../smallstep}/cli-utils/errs/errs.go | 6 +- .../smallstep}/cli-utils/fileutil/file.go | 0 .../smallstep}/cli-utils/fileutil/write.go | 5 +- .../cli-utils/pkg/blackfriday/LICENSE.txt | 0 .../cli-utils/pkg/blackfriday/README.md | 0 .../cli-utils/pkg/blackfriday/block.go | 2 +- .../cli-utils/pkg/blackfriday/doc.go | 0 .../cli-utils/pkg/blackfriday/esc.go | 0 .../cli-utils/pkg/blackfriday/html.go | 2 +- .../cli-utils/pkg/blackfriday/inline.go | 2 +- .../cli-utils/pkg/blackfriday/markdown.go | 2 +- .../cli-utils/pkg/blackfriday/node.go | 0 .../cli-utils/pkg/blackfriday/smartypants.go | 2 +- .../smallstep}/cli-utils/step/config.go | 0 .../smallstep}/cli-utils/step/context.go | 5 +- .../smallstep}/cli-utils/ui/options.go | 14 +- .../smallstep}/cli-utils/ui/templates.go | 0 .../smallstep}/cli-utils/ui/ui.go | 27 +- .../smallstep}/cli-utils/ui/ui_other.go | 0 .../smallstep}/cli-utils/ui/ui_windows.go | 0 .../smallstep}/cli-utils/ui/validators.go | 0 .../smallstep}/cli-utils/usage/css.go | 0 .../smallstep}/cli-utils/usage/help.go | 0 .../smallstep}/cli-utils/usage/html.go | 3 +- .../smallstep}/cli-utils/usage/printer.go | 3 +- .../smallstep}/cli-utils/usage/renderer.go | 19 +- .../smallstep}/cli-utils/usage/report.go | 4 +- .../smallstep}/cli-utils/usage/usage.go | 0 .../smallstep}/linkedca/.gitignore | 0 .../smallstep}/linkedca/CODEOWNERS | 0 .../github.com/smallstep/linkedca/LICENSE | 201 + .../smallstep}/linkedca/Makefile | 36 +- .../smallstep}/linkedca/README.md | 0 .../github.com/smallstep/linkedca/acme.pb.go | 243 + .../smallstep}/linkedca/admin.pb.go | 126 +- .../smallstep/linkedca/config.pb.go | 1878 + .../smallstep}/linkedca/context.go | 0 .../github.com/smallstep/linkedca/eab.pb.go | 193 + .../smallstep/linkedca/majordomo.pb.go | 2725 ++ .../smallstep}/linkedca/majordomo_grpc.pb.go | 287 +- .../smallstep}/linkedca/policy.go | 0 .../smallstep/linkedca/policy.pb.go | 583 + .../smallstep/linkedca/provisioners.pb.go | 2497 ++ .../github.com/smallstep/linkedca/tools.go | 9 + .../github.com/smallstep/nosql/.gitignore | 5 +- .../smallstep/nosql/badger/v1/badger.go | 4 +- .../smallstep/nosql/badger/v1/nobadger.go | 1 - .../smallstep/nosql/badger/v2/badger.go | 4 +- .../smallstep/nosql/badger/v2/nobadger.go | 1 - .../github.com/smallstep/nosql/bolt/bbolt.go | 4 +- .../smallstep/nosql/bolt/nobbolt.go | 1 - .../smallstep/nosql/database/notsupported.go | 1 - .../github.com/smallstep/nosql/mysql/mysql.go | 9 +- .../smallstep/nosql/mysql/nomysql.go | 1 - .../nosql/postgresql/nopostgresql.go | 1 - .../smallstep/nosql/postgresql/postgresql.go | 13 +- .../github.com/smallstep/pkcs7/.gitignore | 4 + .../github.com/smallstep/pkcs7/README.md | 28 +- .../vendor/github.com/smallstep/pkcs7/ber.go | 21 +- .../github.com/smallstep/pkcs7/encrypt.go | 3 +- .../pkcs7/internal/legacy/x509/debug.go | 14 + .../pkcs7/internal/legacy/x509/doc.go | 14 + .../pkcs7/internal/legacy/x509/oid.go | 377 + .../pkcs7/internal/legacy/x509/parser.go | 1027 + .../pkcs7/internal/legacy/x509/pkcs1.go | 15 + .../pkcs7/internal/legacy/x509/verify.go | 193 + .../pkcs7/internal/legacy/x509/x509.go | 488 + .../github.com/smallstep/pkcs7/pkcs7.go | 53 +- .../vendor/github.com/smallstep/pkcs7/sign.go | 47 +- .../github.com/smallstep/pkcs7/verify.go | 65 +- .../smallstep/pkcs7/verify_test_dsa.go | 182 - .../vendor/github.com/smallstep/scep/scep.go | 47 +- .../smallstep/scep/x509util/x509util.go | 2 +- .../github.com/spf13/cobra/.golangci.yml | 35 +- .../vendor/github.com/spf13/cobra/README.md | 24 +- .../vendor/github.com/spf13/cobra/SECURITY.md | 105 + .../vendor/github.com/spf13/cobra/command.go | 23 +- .../github.com/spf13/cobra/completions.go | 19 +- .../github.com/spf13/cobra/doc/man_docs.go | 4 +- .../github.com/spf13/cobra/doc/md_docs.go | 8 +- .../github.com/spf13/cobra/doc/rest_docs.go | 8 +- .../github.com/spf13/cobra/doc/yaml_docs.go | 4 +- .../vendor/github.com/spf13/pflag/README.md | 27 + .../github.com/spf13/pflag/bool_func.go | 40 + .../vendor/github.com/spf13/pflag/count.go | 2 +- .../vendor/github.com/spf13/pflag/errors.go | 149 + .../vendor/github.com/spf13/pflag/flag.go | 121 +- .../vendor/github.com/spf13/pflag/func.go | 37 + .../github.com/spf13/pflag/golangflag.go | 56 + .../github.com/spf13/pflag/ipnet_slice.go | 2 +- .../spf13/pflag/string_to_string.go | 10 +- .../vendor/github.com/spf13/pflag/text.go | 81 + .../vendor/github.com/spf13/pflag/time.go | 124 + .../github.com/stoewer/go-strcase/.gitignore | 17 - .../stoewer/go-strcase/.golangci.yml | 26 - .../github.com/stoewer/go-strcase/LICENSE | 21 - .../github.com/stoewer/go-strcase/README.md | 50 - .../github.com/stoewer/go-strcase/camel.go | 37 - .../github.com/stoewer/go-strcase/doc.go | 8 - .../github.com/stoewer/go-strcase/helper.go | 71 - .../github.com/stoewer/go-strcase/kebab.go | 14 - .../github.com/stoewer/go-strcase/snake.go | 58 - .../go-winio/.gitattributes | 0 .../go-winio/.gitignore | 0 .../go-winio/.golangci.yml | 28 +- .../go-winio/CODEOWNERS | 0 .../{Microsoft => tailscale}/go-winio/LICENSE | 0 .../go-winio/README.md | 8 +- .../go-winio/SECURITY.md | 0 .../go-winio/backup.go | 33 +- .../{Microsoft => tailscale}/go-winio/doc.go | 0 .../{Microsoft => tailscale}/go-winio/ea.go | 0 .../{Microsoft => tailscale}/go-winio/file.go | 47 +- .../go-winio/fileinfo.go | 0 .../go-winio/hvsock.go | 45 +- .../tailscale/go-winio/internal/fs/doc.go | 2 + .../tailscale/go-winio/internal/fs/fs.go | 262 + .../go-winio/internal/fs/security.go | 12 + .../go-winio/internal/fs/zsyscall_windows.go | 64 + .../go-winio/internal/socket/rawaddr.go | 0 .../go-winio/internal/socket/socket.go | 8 +- .../internal/socket/zsyscall_windows.go | 2 +- .../go-winio/internal/stringbuffer/wstring.go | 132 + .../{Microsoft => tailscale}/go-winio/pipe.go | 137 +- .../go-winio/pkg/guid/guid.go | 0 .../go-winio/pkg/guid/guid_nonwindows.go | 0 .../go-winio/pkg/guid/guid_windows.go | 0 .../go-winio/pkg/guid/variant_string.go | 0 .../go-winio/privilege.go | 9 +- .../go-winio/reparse.go | 0 .../{Microsoft => tailscale}/go-winio/sd.go | 37 +- .../go-winio/syscall.go | 2 +- .../go-winio/zsyscall_windows.go | 169 +- .../internal/safesocket/pipe_windows.go | 131 +- .../internal/safesocket/zsyscall_windows.go | 62 + .../vendor/go.etcd.io/bbolt/.gitignore | 2 + .../vendor/go.etcd.io/bbolt/.go-version | 1 + .../traefik/vendor/go.etcd.io/bbolt/Makefile | 65 +- .../traefik/vendor/go.etcd.io/bbolt/OWNERS | 10 + .../traefik/vendor/go.etcd.io/bbolt/README.md | 91 +- .../vendor/go.etcd.io/bbolt/bolt_386.go | 7 - .../{bolt_unix_solaris.go => bolt_aix.go} | 6 +- .../vendor/go.etcd.io/bbolt/bolt_amd64.go | 7 - .../vendor/go.etcd.io/bbolt/bolt_android.go | 92 + .../vendor/go.etcd.io/bbolt/bolt_arm.go | 7 - .../vendor/go.etcd.io/bbolt/bolt_arm64.go | 10 - .../vendor/go.etcd.io/bbolt/bolt_loong64.go | 10 - .../vendor/go.etcd.io/bbolt/bolt_mips64x.go | 10 - .../vendor/go.etcd.io/bbolt/bolt_mipsx.go | 10 - .../vendor/go.etcd.io/bbolt/bolt_ppc.go | 10 - .../vendor/go.etcd.io/bbolt/bolt_ppc64.go | 10 - .../vendor/go.etcd.io/bbolt/bolt_ppc64le.go | 10 - .../vendor/go.etcd.io/bbolt/bolt_riscv64.go | 10 - .../vendor/go.etcd.io/bbolt/bolt_s390x.go | 10 - .../{bolt_unix_aix.go => bolt_solaris.go} | 7 +- .../vendor/go.etcd.io/bbolt/bolt_unix.go | 10 +- .../vendor/go.etcd.io/bbolt/bolt_windows.go | 9 +- .../vendor/go.etcd.io/bbolt/boltsync_unix.go | 1 - .../traefik/vendor/go.etcd.io/bbolt/bucket.go | 484 +- .../traefik/vendor/go.etcd.io/bbolt/cursor.go | 110 +- plugins/traefik/vendor/go.etcd.io/bbolt/db.go | 473 +- .../traefik/vendor/go.etcd.io/bbolt/errors.go | 76 +- .../vendor/go.etcd.io/bbolt/errors/errors.go | 84 + .../vendor/go.etcd.io/bbolt/freelist.go | 405 - .../vendor/go.etcd.io/bbolt/freelist_hmap.go | 178 - .../bbolt/internal/common/bolt_386.go | 7 + .../bbolt/internal/common/bolt_amd64.go | 7 + .../bbolt/internal/common/bolt_arm.go | 7 + .../bbolt/internal/common/bolt_arm64.go | 9 + .../bbolt/internal/common/bolt_loong64.go | 9 + .../bbolt/internal/common/bolt_mips64x.go | 9 + .../bbolt/internal/common/bolt_mipsx.go | 9 + .../bbolt/internal/common/bolt_ppc.go | 9 + .../bbolt/internal/common/bolt_ppc64.go | 9 + .../bbolt/internal/common/bolt_ppc64le.go | 9 + .../bbolt/internal/common/bolt_riscv64.go | 9 + .../bbolt/internal/common/bolt_s390x.go | 9 + .../bbolt/internal/common/bucket.go | 54 + .../go.etcd.io/bbolt/internal/common/inode.go | 115 + .../go.etcd.io/bbolt/internal/common/meta.go | 161 + .../go.etcd.io/bbolt/internal/common/page.go | 391 + .../go.etcd.io/bbolt/internal/common/types.go | 37 + .../bbolt/{ => internal/common}/unsafe.go | 22 +- .../go.etcd.io/bbolt/internal/common/utils.go | 64 + .../bbolt/internal/common/verify.go | 67 + .../bbolt/internal/freelist/array.go | 108 + .../bbolt/internal/freelist/freelist.go | 82 + .../bbolt/internal/freelist/hashmap.go | 292 + .../bbolt/internal/freelist/shared.go | 310 + .../traefik/vendor/go.etcd.io/bbolt/logger.go | 113 + .../vendor/go.etcd.io/bbolt/mlock_unix.go | 1 - .../traefik/vendor/go.etcd.io/bbolt/node.go | 252 +- .../traefik/vendor/go.etcd.io/bbolt/page.go | 214 - plugins/traefik/vendor/go.etcd.io/bbolt/tx.go | 316 +- .../vendor/go.etcd.io/bbolt/tx_check.go | 206 +- .../auto/sdk/CONTRIBUTING.md | 27 + .../go.opentelemetry.io/auto/sdk/LICENSE | 201 + .../auto/sdk/VERSIONING.md | 15 + .../go.opentelemetry.io/auto/sdk/doc.go | 14 + .../auto/sdk/internal/telemetry/attr.go | 58 + .../auto/sdk/internal/telemetry/doc.go | 8 + .../auto/sdk/internal/telemetry/id.go | 103 + .../auto/sdk/internal/telemetry/number.go | 67 + .../auto/sdk/internal/telemetry/resource.go | 66 + .../auto/sdk/internal/telemetry/scope.go | 67 + .../auto/sdk/internal/telemetry/span.go | 472 + .../auto/sdk/internal/telemetry/status.go | 42 + .../auto/sdk/internal/telemetry/traces.go | 189 + .../auto/sdk/internal/telemetry/value.go | 450 + .../go.opentelemetry.io/auto/sdk/limit.go | 94 + .../go.opentelemetry.io/auto/sdk/span.go | 447 + .../go.opentelemetry.io/auto/sdk/tracer.go | 141 + .../auto/sdk/tracer_provider.go | 33 + .../contrib/bridges/prometheus/BENCHMARKS.md | 24 + .../contrib/bridges/prometheus/LICENSE | 231 + .../contrib/bridges/prometheus/config.go | 47 + .../contrib/bridges/prometheus/doc.go | 22 + .../contrib/bridges/prometheus/producer.go | 404 + .../contrib/bridges/prometheus/version.go | 7 + .../contrib/exporters/autoexport/LICENSE | 231 + .../contrib/exporters/autoexport/doc.go | 7 + .../contrib/exporters/autoexport/logs.go | 93 + .../contrib/exporters/autoexport/metrics.go | 308 + .../contrib/exporters/autoexport/noop.go | 87 + .../contrib/exporters/autoexport/registry.go | 67 + .../contrib/exporters/autoexport/signal.go | 61 + .../contrib/exporters/autoexport/spans.go | 98 + .../instrumentation/net/http/otelhttp/LICENSE | 231 + .../net/http/otelhttp/common.go | 27 + .../net/http/otelhttp/config.go | 201 + .../instrumentation/net/http/otelhttp/doc.go | 6 + .../net/http/otelhttp/handler.go | 221 + .../otelhttp/internal/request/body_wrapper.go | 80 + .../net/http/otelhttp/internal/request/gen.go | 10 + .../internal/request/resp_writer_wrapper.go | 122 + .../http/otelhttp/internal/semconv/client.go | 287 + .../net/http/otelhttp/internal/semconv/gen.go | 15 + .../http/otelhttp/internal/semconv/server.go | 403 + .../http/otelhttp/internal/semconv/util.go | 127 + .../net/http/otelhttp/labeler.go | 58 + .../net/http/otelhttp/start_time_context.go | 29 + .../net/http/otelhttp/transport.go | 282 + .../net/http/otelhttp/version.go | 7 + .../go.opentelemetry.io/otel/.clomonitor.yml | 3 + .../go.opentelemetry.io/otel/.codespellignore | 11 + .../go.opentelemetry.io/otel/.codespellrc | 10 + .../go.opentelemetry.io/otel/.gitattributes | 3 + .../go.opentelemetry.io/otel/.gitignore | 15 + .../go.opentelemetry.io/otel/.golangci.yml | 279 + .../go.opentelemetry.io/otel/.lycheeignore | 13 + .../otel/.markdownlint.yaml | 29 + .../go.opentelemetry.io/otel/CHANGELOG.md | 3739 ++ .../go.opentelemetry.io/otel/CODEOWNERS | 17 + .../go.opentelemetry.io/otel/CONTRIBUTING.md | 1157 + .../vendor/go.opentelemetry.io/otel/LICENSE | 231 + .../vendor/go.opentelemetry.io/otel/Makefile | 330 + .../vendor/go.opentelemetry.io/otel/README.md | 115 + .../go.opentelemetry.io/otel/RELEASING.md | 220 + .../otel/SECURITY-INSIGHTS.yml | 203 + .../go.opentelemetry.io/otel/VERSIONING.md | 224 + .../otel/attribute/README.md | 3 + .../go.opentelemetry.io/otel/attribute/doc.go | 5 + .../otel/attribute/encoder.go | 135 + .../otel/attribute/filter.go | 49 + .../otel/attribute/hash.go | 94 + .../otel/attribute/internal/attribute.go | 75 + .../otel/attribute/internal/xxhash/xxhash.go | 64 + .../otel/attribute/iterator.go | 151 + .../go.opentelemetry.io/otel/attribute/key.go | 123 + .../go.opentelemetry.io/otel/attribute/kv.go | 75 + .../otel/attribute/rawhelpers.go | 37 + .../go.opentelemetry.io/otel/attribute/set.go | 436 + .../otel/attribute/type_string.go | 32 + .../otel/attribute/value.go | 292 + .../otel/baggage/README.md | 3 + .../otel/baggage/baggage.go | 1075 + .../otel/baggage/context.go | 28 + .../go.opentelemetry.io/otel/baggage/doc.go | 9 + .../go.opentelemetry.io/otel/codes/README.md | 3 + .../go.opentelemetry.io/otel/codes/codes.go | 106 + .../go.opentelemetry.io/otel/codes/doc.go | 10 + .../otel/dependencies.Dockerfile | 4 + .../vendor/go.opentelemetry.io/otel/doc.go | 25 + .../go.opentelemetry.io/otel/error_handler.go | 27 + .../otlp/otlplog/otlploggrpc/LICENSE | 231 + .../otlp/otlplog/otlploggrpc/README.md | 3 + .../otlp/otlplog/otlploggrpc/client.go | 284 + .../otlp/otlplog/otlploggrpc/config.go | 676 + .../exporters/otlp/otlplog/otlploggrpc/doc.go | 63 + .../otlp/otlplog/otlploggrpc/exporter.go | 94 + .../otlp/otlplog/otlploggrpc/internal/gen.go | 20 + .../internal/observ/instrumentation.go | 313 + .../otlploggrpc/internal/observ/target.go | 143 + .../otlploggrpc/internal/partialsuccess.go | 43 + .../otlploggrpc/internal/retry/retry.go | 146 + .../otlploggrpc/internal/transform/log.go | 393 + .../otlplog/otlploggrpc/internal/version.go | 8 + .../otlplog/otlploggrpc/internal/x/README.md | 36 + .../otlploggrpc/internal/x/features.go | 23 + .../otlp/otlplog/otlploggrpc/internal/x/x.go | 58 + .../otlp/otlplog/otlploggrpc/version.go | 9 + .../otlp/otlplog/otlploghttp/LICENSE | 231 + .../otlp/otlplog/otlploghttp/README.md | 3 + .../otlp/otlplog/otlploghttp/client.go | 399 + .../otlp/otlplog/otlploghttp/config.go | 685 + .../exporters/otlp/otlplog/otlploghttp/doc.go | 68 + .../otlp/otlplog/otlploghttp/exporter.go | 73 + .../otlp/otlplog/otlploghttp/internal/gen.go | 17 + .../otlploghttp/internal/observ/doc.go | 6 + .../internal/observ/instrumentation.go | 365 + .../otlploghttp/internal/partialsuccess.go | 42 + .../otlploghttp/internal/retry/retry.go | 146 + .../otlploghttp/internal/transform/log.go | 393 + .../otlplog/otlploghttp/internal/version.go | 7 + .../otlplog/otlploghttp/internal/x/README.md | 36 + .../otlplog/otlploghttp/internal/x/observ.go | 22 + .../otlp/otlplog/otlploghttp/internal/x/x.go | 58 + .../otlp/otlplog/otlploghttp/version.go | 9 + .../otlp/otlpmetric/otlpmetricgrpc/LICENSE | 231 + .../otlp/otlpmetric/otlpmetricgrpc/README.md | 3 + .../otlp/otlpmetric/otlpmetricgrpc/client.go | 205 + .../otlp/otlpmetric/otlpmetricgrpc/config.go | 267 + .../otlp/otlpmetric/otlpmetricgrpc/doc.go | 84 + .../otlpmetric/otlpmetricgrpc/exporter.go | 158 + .../internal/envconfig/envconfig.go | 217 + .../otlpmetric/otlpmetricgrpc/internal/gen.go | 32 + .../internal/oconf/envconfig.go | 209 + .../otlpmetricgrpc/internal/oconf/options.go | 383 + .../internal/oconf/optiontypes.go | 47 + .../otlpmetricgrpc/internal/oconf/tls.go | 38 + .../otlpmetricgrpc/internal/partialsuccess.go | 67 + .../otlpmetricgrpc/internal/retry/retry.go | 146 + .../internal/transform/attribute.go | 145 + .../internal/transform/error.go | 103 + .../internal/transform/metricdata.go | 356 + .../otlp/otlpmetric/otlpmetricgrpc/version.go | 9 + .../otlp/otlpmetric/otlpmetrichttp/LICENSE | 231 + .../otlp/otlpmetric/otlpmetrichttp/README.md | 3 + .../otlp/otlpmetric/otlpmetrichttp/client.go | 379 + .../otlp/otlpmetric/otlpmetrichttp/config.go | 240 + .../otlp/otlpmetric/otlpmetrichttp/doc.go | 87 + .../otlpmetric/otlpmetrichttp/exporter.go | 153 + .../internal/envconfig/envconfig.go | 217 + .../otlpmetric/otlpmetrichttp/internal/gen.go | 32 + .../internal/oconf/envconfig.go | 209 + .../otlpmetrichttp/internal/oconf/options.go | 383 + .../internal/oconf/optiontypes.go | 47 + .../otlpmetrichttp/internal/oconf/tls.go | 38 + .../otlpmetrichttp/internal/partialsuccess.go | 67 + .../otlpmetrichttp/internal/retry/retry.go | 146 + .../internal/transform/attribute.go | 145 + .../internal/transform/error.go | 103 + .../internal/transform/metricdata.go | 356 + .../otlp/otlpmetric/otlpmetrichttp/version.go | 9 + .../otel/exporters/otlp/otlptrace/LICENSE | 231 + .../otel/exporters/otlp/otlptrace/README.md | 3 + .../otel/exporters/otlp/otlptrace/clients.go | 43 + .../otel/exporters/otlp/otlptrace/doc.go | 10 + .../otel/exporters/otlp/otlptrace/exporter.go | 105 + .../internal/tracetransform/attribute.go | 151 + .../tracetransform/instrumentation.go | 21 + .../internal/tracetransform/resource.go | 18 + .../otlptrace/internal/tracetransform/span.go | 221 + .../otlp/otlptrace/otlptracegrpc/LICENSE | 231 + .../otlp/otlptrace/otlptracegrpc/README.md | 3 + .../otlp/otlptrace/otlptracegrpc/client.go | 323 + .../otlp/otlptrace/otlptracegrpc/doc.go | 65 + .../otlp/otlptrace/otlptracegrpc/exporter.go | 20 + .../otlptracegrpc/internal/counter/counter.go | 31 + .../internal/envconfig/envconfig.go | 217 + .../otlptrace/otlptracegrpc/internal/gen.go | 34 + .../otlptracegrpc/internal/observ/doc.go | 6 + .../internal/observ/instrumentation.go | 350 + .../otlptracegrpc/internal/observ/target.go | 143 + .../internal/otlpconfig/envconfig.go | 150 + .../internal/otlpconfig/options.go | 360 + .../internal/otlpconfig/optiontypes.go | 40 + .../otlptracegrpc/internal/otlpconfig/tls.go | 26 + .../otlptracegrpc/internal/partialsuccess.go | 67 + .../otlptracegrpc/internal/retry/retry.go | 146 + .../otlptracegrpc/internal/version.go | 8 + .../otlptracegrpc/internal/x/README.md | 36 + .../otlptracegrpc/internal/x/observ.go | 22 + .../otlptrace/otlptracegrpc/internal/x/x.go | 58 + .../otlp/otlptrace/otlptracegrpc/options.go | 211 + .../otlp/otlptrace/otlptracehttp/LICENSE | 231 + .../otlp/otlptrace/otlptracehttp/README.md | 3 + .../otlp/otlptrace/otlptracehttp/client.go | 449 + .../otlp/otlptrace/otlptracehttp/doc.go | 68 + .../otlp/otlptrace/otlptracehttp/exporter.go | 20 + .../otlptracehttp/internal/counter/counter.go | 31 + .../internal/envconfig/envconfig.go | 217 + .../otlptrace/otlptracehttp/internal/gen.go | 31 + .../internal/observ/instrumentation.go | 405 + .../internal/otlpconfig/envconfig.go | 150 + .../internal/otlpconfig/options.go | 360 + .../internal/otlpconfig/optiontypes.go | 40 + .../otlptracehttp/internal/otlpconfig/tls.go | 26 + .../otlptracehttp/internal/partialsuccess.go | 67 + .../otlptracehttp/internal/retry/retry.go | 146 + .../otlptracehttp/internal/version.go | 8 + .../otlptracehttp/internal/x/observ.go | 22 + .../otlptrace/otlptracehttp/internal/x/x.go | 58 + .../otlp/otlptrace/otlptracehttp/options.go | 171 + .../otel/exporters/otlp/otlptrace/version.go | 9 + .../otel/exporters/prometheus/LICENSE | 231 + .../otel/exporters/prometheus/README.md | 3 + .../otel/exporters/prometheus/config.go | 198 + .../otel/exporters/prometheus/doc.go | 11 + .../otel/exporters/prometheus/errors.go | 16 + .../otel/exporters/prometheus/exporter.go | 825 + .../prometheus/internal/counter/counter.go | 31 + .../otel/exporters/prometheus/internal/gen.go | 12 + .../internal/observ/instrumentation.go | 256 + .../exporters/prometheus/internal/version.go | 9 + .../exporters/prometheus/internal/x/README.md | 37 + .../prometheus/internal/x/features.go | 22 + .../otel/exporters/prometheus/internal/x/x.go | 58 + .../otel/exporters/stdout/stdoutlog/LICENSE | 231 + .../otel/exporters/stdout/stdoutlog/README.md | 3 + .../otel/exporters/stdout/stdoutlog/config.go | 85 + .../otel/exporters/stdout/stdoutlog/doc.go | 12 + .../exporters/stdout/stdoutlog/exporter.go | 72 + .../otel/exporters/stdout/stdoutlog/record.go | 132 + .../exporters/stdout/stdoutmetric/LICENSE | 231 + .../exporters/stdout/stdoutmetric/README.md | 3 + .../exporters/stdout/stdoutmetric/config.go | 132 + .../otel/exporters/stdout/stdoutmetric/doc.go | 12 + .../exporters/stdout/stdoutmetric/encoder.go | 31 + .../exporters/stdout/stdoutmetric/exporter.go | 206 + .../stdoutmetric/internal/counter/counter.go | 31 + .../stdout/stdoutmetric/internal/gen.go | 12 + .../internal/observ/instrumentation.go | 220 + .../stdout/stdoutmetric/internal/version.go | 8 + .../stdout/stdoutmetric/internal/x/README.md | 36 + .../stdoutmetric/internal/x/features.go | 22 + .../stdout/stdoutmetric/internal/x/x.go | 58 + .../otel/exporters/stdout/stdouttrace/LICENSE | 231 + .../exporters/stdout/stdouttrace/README.md | 3 + .../exporters/stdout/stdouttrace/config.go | 85 + .../otel/exporters/stdout/stdouttrace/doc.go | 9 + .../stdouttrace/internal/counter/counter.go | 31 + .../stdout/stdouttrace/internal/gen.go | 12 + .../internal/observ/instrumentation.go | 230 + .../stdout/stdouttrace/internal/version.go | 8 + .../stdout/stdouttrace/internal/x/README.md | 36 + .../stdout/stdouttrace/internal/x/features.go | 23 + .../stdout/stdouttrace/internal/x/x.go | 58 + .../exporters/stdout/stdouttrace/trace.go | 121 + .../go.opentelemetry.io/otel/handler.go | 33 + .../otel/internal/baggage/baggage.go | 32 + .../otel/internal/baggage/context.go | 81 + .../internal/errorhandler/errorhandler.go | 96 + .../otel/internal/global/handler.go | 17 + .../otel/internal/global/instruments.go | 468 + .../otel/internal/global/internal_logging.go | 62 + .../otel/internal/global/meter.go | 625 + .../otel/internal/global/propagator.go | 71 + .../otel/internal/global/state.go | 169 + .../otel/internal/global/trace.go | 232 + .../otel/internal_logging.go | 15 + .../go.opentelemetry.io/otel/log/DESIGN.md | 634 + .../go.opentelemetry.io/otel/log/LICENSE | 231 + .../go.opentelemetry.io/otel/log/README.md | 3 + .../go.opentelemetry.io/otel/log/doc.go | 85 + .../otel/log/embedded/README.md | 3 + .../otel/log/embedded/embedded.go | 36 + .../go.opentelemetry.io/otel/log/keyvalue.go | 443 + .../otel/log/kind_string.go | 31 + .../go.opentelemetry.io/otel/log/logger.go | 181 + .../otel/log/noop/README.md | 3 + .../go.opentelemetry.io/otel/log/noop/noop.go | 50 + .../go.opentelemetry.io/otel/log/provider.go | 37 + .../go.opentelemetry.io/otel/log/record.go | 163 + .../go.opentelemetry.io/otel/log/severity.go | 64 + .../otel/log/severity_string.go | 48 + .../vendor/go.opentelemetry.io/otel/metric.go | 42 + .../go.opentelemetry.io/otel/metric/LICENSE | 231 + .../go.opentelemetry.io/otel/metric/README.md | 3 + .../otel/metric/asyncfloat64.go | 273 + .../otel/metric/asyncint64.go | 269 + .../go.opentelemetry.io/otel/metric/config.go | 111 + .../go.opentelemetry.io/otel/metric/doc.go | 177 + .../otel/metric/embedded/README.md | 3 + .../otel/metric/embedded/embedded.go | 243 + .../otel/metric/instrument.go | 376 + .../go.opentelemetry.io/otel/metric/meter.go | 340 + .../otel/metric/noop/README.md | 3 + .../otel/metric/noop/noop.go | 320 + .../otel/metric/syncfloat64.go | 274 + .../otel/metric/syncint64.go | 274 + .../go.opentelemetry.io/otel/propagation.go | 20 + .../otel/propagation/README.md | 3 + .../otel/propagation/baggage.go | 97 + .../otel/propagation/doc.go | 13 + .../otel/propagation/propagation.go | 168 + .../otel/propagation/trace_context.go | 155 + .../go.opentelemetry.io/otel/renovate.json | 35 + .../go.opentelemetry.io/otel/requirements.txt | 1 + .../go.opentelemetry.io/otel/sdk/LICENSE | 231 + .../go.opentelemetry.io/otel/sdk/README.md | 3 + .../otel/sdk/instrumentation/README.md | 3 + .../otel/sdk/instrumentation/doc.go | 13 + .../otel/sdk/instrumentation/library.go | 9 + .../otel/sdk/instrumentation/scope.go | 19 + .../otel/sdk/internal/x/README.md | 46 + .../otel/sdk/internal/x/features.go | 54 + .../otel/sdk/internal/x/x.go | 58 + .../otel/sdk/log/DESIGN.md | 176 + .../go.opentelemetry.io/otel/sdk/log/LICENSE | 231 + .../otel/sdk/log/README.md | 3 + .../go.opentelemetry.io/otel/sdk/log/batch.go | 496 + .../go.opentelemetry.io/otel/sdk/log/doc.go | 39 + .../otel/sdk/log/exporter.go | 326 + .../otel/sdk/log/instrumentation.go | 39 + .../otel/sdk/log/internal/observ/doc.go | 6 + .../internal/observ/simple_log_processor.go | 128 + .../otel/sdk/log/internal/x/README.md | 34 + .../otel/sdk/log/internal/x/features.go | 23 + .../otel/sdk/log/internal/x/x.go | 58 + .../otel/sdk/log/logger.go | 185 + .../otel/sdk/log/processor.go | 96 + .../otel/sdk/log/provider.go | 269 + .../otel/sdk/log/record.go | 744 + .../go.opentelemetry.io/otel/sdk/log/ring.go | 82 + .../otel/sdk/log/setting.go | 119 + .../otel/sdk/log/simple.go | 103 + .../otel/sdk/metric/LICENSE | 231 + .../otel/sdk/metric/README.md | 3 + .../otel/sdk/metric/aggregation.go | 189 + .../otel/sdk/metric/cache.go | 83 + .../otel/sdk/metric/config.go | 208 + .../otel/sdk/metric/doc.go | 87 + .../otel/sdk/metric/env.go | 39 + .../otel/sdk/metric/exemplar.go | 77 + .../otel/sdk/metric/exemplar/README.md | 3 + .../otel/sdk/metric/exemplar/doc.go | 6 + .../otel/sdk/metric/exemplar/exemplar.go | 29 + .../otel/sdk/metric/exemplar/filter.go | 34 + .../metric/exemplar/fixed_size_reservoir.go | 253 + .../metric/exemplar/histogram_reservoir.go | 82 + .../otel/sdk/metric/exemplar/reservoir.go | 40 + .../otel/sdk/metric/exemplar/storage.go | 102 + .../otel/sdk/metric/exemplar/value.go | 59 + .../otel/sdk/metric/exporter.go | 77 + .../otel/sdk/metric/instrument.go | 365 + .../otel/sdk/metric/instrumentkind_string.go | 31 + .../metric/internal/aggregate/aggregate.go | 162 + .../sdk/metric/internal/aggregate/atomic.go | 275 + .../otel/sdk/metric/internal/aggregate/doc.go | 7 + .../sdk/metric/internal/aggregate/drop.go | 27 + .../sdk/metric/internal/aggregate/exemplar.go | 43 + .../aggregate/exponential_histogram.go | 505 + .../internal/aggregate/filtered_reservoir.go | 73 + .../metric/internal/aggregate/histogram.go | 399 + .../metric/internal/aggregate/lastvalue.go | 220 + .../sdk/metric/internal/aggregate/limit.go | 42 + .../otel/sdk/metric/internal/aggregate/sum.go | 298 + .../metric/internal/observ/instrumentation.go | 168 + .../internal/reservoir/concurrent_safe.go | 11 + .../otel/sdk/metric/internal/reservoir/doc.go | 6 + .../otel/sdk/metric/internal/reuse_slice.go | 14 + .../otel/sdk/metric/manual_reader.go | 246 + .../otel/sdk/metric/meter.go | 773 + .../otel/sdk/metric/metricdata/README.md | 3 + .../otel/sdk/metric/metricdata/data.go | 297 + .../otel/sdk/metric/metricdata/temporality.go | 30 + .../metric/metricdata/temporality_string.go | 26 + .../otel/sdk/metric/periodic_reader.go | 411 + .../otel/sdk/metric/pipeline.go | 698 + .../otel/sdk/metric/provider.go | 145 + .../otel/sdk/metric/reader.go | 280 + .../otel/sdk/metric/version.go | 9 + .../otel/sdk/metric/view.go | 118 + .../otel/sdk/resource/README.md | 3 + .../otel/sdk/resource/auto.go | 92 + .../otel/sdk/resource/builtin.go | 116 + .../otel/sdk/resource/config.go | 203 + .../otel/sdk/resource/container.go | 89 + .../otel/sdk/resource/doc.go | 20 + .../otel/sdk/resource/env.go | 95 + .../otel/sdk/resource/host_id.go | 108 + .../otel/sdk/resource/host_id_bsd.go | 11 + .../otel/sdk/resource/host_id_darwin.go | 8 + .../otel/sdk/resource/host_id_exec.go | 18 + .../otel/sdk/resource/host_id_linux.go | 10 + .../otel/sdk/resource/host_id_readfile.go | 17 + .../otel/sdk/resource/host_id_unsupported.go | 18 + .../otel/sdk/resource/host_id_windows.go | 35 + .../otel/sdk/resource/os.go | 89 + .../otel/sdk/resource/os_release_darwin.go | 92 + .../otel/sdk/resource/os_release_unix.go | 142 + .../otel/sdk/resource/os_unix.go | 78 + .../otel/sdk/resource/os_unsupported.go | 14 + .../otel/sdk/resource/os_windows.go | 89 + .../otel/sdk/resource/process.go | 173 + .../otel/sdk/resource/resource.go | 324 + .../otel/sdk/trace/README.md | 3 + .../otel/sdk/trace/batch_span_processor.go | 443 + .../go.opentelemetry.io/otel/sdk/trace/doc.go | 13 + .../otel/sdk/trace/event.go | 26 + .../otel/sdk/trace/evictedqueue.go | 64 + .../otel/sdk/trace/id_generator.go | 69 + .../otel/sdk/trace/internal/env/env.go | 168 + .../internal/observ/batch_span_processor.go | 119 + .../otel/sdk/trace/internal/observ/doc.go | 6 + .../internal/observ/simple_span_processor.go | 97 + .../otel/sdk/trace/internal/observ/tracer.go | 231 + .../otel/sdk/trace/link.go | 23 + .../otel/sdk/trace/provider.go | 503 + .../otel/sdk/trace/sampler_env.go | 96 + .../otel/sdk/trace/sampling.go | 336 + .../otel/sdk/trace/simple_span_processor.go | 150 + .../otel/sdk/trace/snapshot.go | 133 + .../otel/sdk/trace/span.go | 959 + .../otel/sdk/trace/span_exporter.go | 36 + .../otel/sdk/trace/span_limits.go | 114 + .../otel/sdk/trace/span_processor.go | 61 + .../otel/sdk/trace/tracer.go | 188 + .../otel/sdk/trace/tracetest/README.md | 3 + .../otel/sdk/trace/tracetest/exporter.go | 74 + .../otel/sdk/trace/tracetest/recorder.go | 94 + .../otel/sdk/trace/tracetest/span.go | 166 + .../go.opentelemetry.io/otel/sdk/version.go | 10 + .../otel/semconv/v1.26.0/README.md | 3 + .../otel/semconv/v1.26.0/attribute_group.go | 8996 ++++ .../otel/semconv/v1.26.0/doc.go | 9 + .../otel/semconv/v1.26.0/exception.go | 9 + .../otel/semconv/v1.26.0/metric.go | 1307 + .../otel/semconv/v1.26.0/schema.go | 9 + .../otel/semconv/v1.37.0/MIGRATION.md | 41 + .../otel/semconv/v1.37.0/README.md | 3 + .../otel/semconv/v1.37.0/attribute_group.go | 15193 +++++++ .../otel/semconv/v1.37.0/doc.go | 9 + .../otel/semconv/v1.37.0/error_type.go | 56 + .../otel/semconv/v1.37.0/exception.go | 9 + .../otel/semconv/v1.37.0/schema.go | 9 + .../otel/semconv/v1.39.0/MIGRATION.md | 78 + .../otel/semconv/v1.39.0/README.md | 3 + .../otel/semconv/v1.39.0/attribute_group.go | 16239 +++++++ .../otel/semconv/v1.39.0/doc.go | 9 + .../otel/semconv/v1.39.0/error_type.go | 56 + .../otel/semconv/v1.39.0/exception.go | 9 + .../otel/semconv/v1.39.0/httpconv/metric.go | 1767 + .../otel/semconv/v1.39.0/schema.go | 9 + .../otel/semconv/v1.40.0/MIGRATION.md | 27 + .../otel/semconv/v1.40.0/README.md | 3 + .../otel/semconv/v1.40.0/attribute_group.go | 16861 ++++++++ .../otel/semconv/v1.40.0/doc.go | 9 + .../otel/semconv/v1.40.0/error_type.go | 66 + .../otel/semconv/v1.40.0/exception.go | 9 + .../otel/semconv/v1.40.0/otelconv/metric.go | 2222 + .../otel/semconv/v1.40.0/schema.go | 9 + .../vendor/go.opentelemetry.io/otel/trace.go | 36 + .../go.opentelemetry.io/otel/trace/LICENSE | 231 + .../go.opentelemetry.io/otel/trace/README.md | 3 + .../go.opentelemetry.io/otel/trace/auto.go | 662 + .../go.opentelemetry.io/otel/trace/config.go | 362 + .../go.opentelemetry.io/otel/trace/context.go | 50 + .../go.opentelemetry.io/otel/trace/doc.go | 119 + .../otel/trace/embedded/README.md | 3 + .../otel/trace/embedded/embedded.go | 45 + .../go.opentelemetry.io/otel/trace/hex.go | 38 + .../otel/trace/internal/telemetry/attr.go | 58 + .../otel/trace/internal/telemetry/doc.go | 8 + .../otel/trace/internal/telemetry/id.go | 103 + .../otel/trace/internal/telemetry/number.go | 67 + .../otel/trace/internal/telemetry/resource.go | 66 + .../otel/trace/internal/telemetry/scope.go | 67 + .../otel/trace/internal/telemetry/span.go | 472 + .../otel/trace/internal/telemetry/status.go | 42 + .../otel/trace/internal/telemetry/traces.go | 189 + .../otel/trace/internal/telemetry/value.go | 453 + .../otel/trace/nonrecording.go | 16 + .../go.opentelemetry.io/otel/trace/noop.go | 105 + .../otel/trace/noop/README.md | 3 + .../otel/trace/noop/noop.go | 112 + .../otel/trace/provider.go | 59 + .../go.opentelemetry.io/otel/trace/span.go | 181 + .../go.opentelemetry.io/otel/trace/trace.go | 389 + .../go.opentelemetry.io/otel/trace/tracer.go | 37 + .../otel/trace/tracestate.go | 333 + .../otel/verify_released_changelog.sh | 42 + .../go.opentelemetry.io/otel/version.go | 9 + .../go.opentelemetry.io/otel/versions.yaml | 69 + .../go.opentelemetry.io/proto/otlp/LICENSE | 201 + .../otlp/collector/logs/v1/logs_service.pb.go | 367 + .../collector/logs/v1/logs_service.pb.gw.go | 171 + .../collector/logs/v1/logs_service_grpc.pb.go | 105 + .../metrics/v1/metrics_service.pb.go | 371 + .../metrics/v1/metrics_service.pb.gw.go | 171 + .../metrics/v1/metrics_service_grpc.pb.go | 105 + .../collector/trace/v1/trace_service.pb.go | 367 + .../collector/trace/v1/trace_service.pb.gw.go | 171 + .../trace/v1/trace_service_grpc.pb.go | 105 + .../proto/otlp/common/v1/common.pb.go | 808 + .../proto/otlp/logs/v1/logs.pb.go | 870 + .../proto/otlp/metrics/v1/metrics.pb.go | 2559 ++ .../proto/otlp/resource/v1/resource.pb.go | 214 + .../proto/otlp/trace/v1/trace.pb.go | 1285 + .../go.step.sm/crypto/fipsutil/fipsutil.go | 49 + .../crypto/fipsutil/fipsutil_other.go | 19 + .../internal/bcrypt_pbkdf/bcrypt_pbkdf.go | 7 +- .../crypto/internal/templates/funcmap.go | 142 +- .../crypto/internal/termutil/termutil.go | 82 + .../crypto/internal/utils/asn1/asn1.go | 33 + .../crypto/internal/utils/convert/convert.go | 76 + .../crypto/internal/utils/{ => file}/io.go | 2 +- .../vendor/go.step.sm/crypto/jose/encrypt.go | 1 + .../vendor/go.step.sm/crypto/jose/generate.go | 1 + .../vendor/go.step.sm/crypto/jose/options.go | 4 +- .../vendor/go.step.sm/crypto/jose/parse.go | 37 + .../vendor/go.step.sm/crypto/jose/types.go | 9 +- .../vendor/go.step.sm/crypto/jose/validate.go | 3 +- .../vendor/go.step.sm/crypto/jose/x25519.go | 1 + .../vendor/go.step.sm/crypto/keyutil/key.go | 7 +- .../go.step.sm/crypto/kms/apiv1/options.go | 39 +- .../go.step.sm/crypto/kms/apiv1/requests.go | 41 + .../vendor/go.step.sm/crypto/kms/kms.go | 1 + .../go.step.sm/crypto/kms/softkms/softkms.go | 34 +- .../crypto/kms/sshagentkms/no_sshagentkms.go | 2 +- .../crypto/kms/sshagentkms/sshagentkms.go | 3 +- .../vendor/go.step.sm/crypto/kms/uri/uri.go | 150 +- .../vendor/go.step.sm/crypto/pemutil/pem.go | 284 +- .../vendor/go.step.sm/crypto/pemutil/pkcs8.go | 4 +- .../vendor/go.step.sm/crypto/pemutil/ssh.go | 13 +- .../go.step.sm/crypto/sshutil/certificate.go | 21 +- .../go.step.sm/crypto/sshutil/fingerprint.go | 5 +- .../go.step.sm/crypto/sshutil/sshutil.go | 18 +- .../go.step.sm/crypto/x509util/algorithms.go | 8 +- .../go.step.sm/crypto/x509util/certificate.go | 13 +- .../crypto/x509util/certificate_request.go | 157 +- .../go.step.sm/crypto/x509util/extensions.go | 265 +- .../crypto/x509util/marshal_utils.go | 39 + .../go.step.sm/crypto/x509util/utils.go | 62 +- .../vendor/go.step.sm/linkedca/config.pb.go | 2222 - .../vendor/go.step.sm/linkedca/eab.pb.go | 226 - .../go.step.sm/linkedca/majordomo.pb.go | 2890 -- .../vendor/go.step.sm/linkedca/policy.pb.go | 727 - .../go.step.sm/linkedca/provisioners.pb.go | 2926 -- .../go.uber.org/mock/mockgen/deprecated.go | 41 - .../go.uber.org/mock/mockgen/generic.go | 103 - .../vendor/go.uber.org/mock/mockgen/gob.go | 21 - .../go.uber.org/mock/mockgen/mockgen.go | 906 - .../go.uber.org/mock/mockgen/model/model.go | 533 - .../go.uber.org/mock/mockgen/package_mode.go | 358 - .../vendor/go.uber.org/mock/mockgen/parse.go | 805 - .../vendor/go.uber.org/zap/.golangci.yml | 2 +- .../vendor/go.uber.org/zap/CHANGELOG.md | 10 + .../vendor/go.uber.org/zap/CODE_OF_CONDUCT.md | 4 +- .../traefik/vendor/go.uber.org/zap/LICENSE | 2 +- .../traefik/vendor/go.uber.org/zap/Makefile | 2 +- .../traefik/vendor/go.uber.org/zap/field.go | 10 + .../vendor/go.uber.org/zap/http_handler.go | 2 +- .../traefik/vendor/go.uber.org/zap/logger.go | 6 +- .../traefik/vendor/go.uber.org/zap/options.go | 6 +- .../traefik/vendor/go.uber.org/zap/sink.go | 2 +- .../zap/zapcore/buffered_write_syncer.go | 23 +- .../zap/zapcore/console_encoder.go | 2 +- .../vendor/go.uber.org/zap/zapcore/entry.go | 14 +- .../go.uber.org/zap/zapcore/lazy_with.go | 35 +- .../vendor/go.uber.org/zap/zapcore/level.go | 14 +- .../vendor/go.yaml.in/yaml/v2/.travis.yml | 17 + .../traefik/vendor/go.yaml.in/yaml/v2/LICENSE | 201 + .../yaml/v2/LICENSE.libyaml} | 27 +- .../traefik/vendor/go.yaml.in/yaml/v2/NOTICE | 13 + .../vendor/go.yaml.in/yaml/v2/README.md | 131 + .../traefik/vendor/go.yaml.in/yaml/v2/apic.go | 744 + .../vendor/go.yaml.in/yaml/v2/decode.go | 815 + .../vendor/go.yaml.in/yaml/v2/emitterc.go | 1685 + .../vendor/go.yaml.in/yaml/v2/encode.go | 390 + .../vendor/go.yaml.in/yaml/v2/parserc.go | 1095 + .../vendor/go.yaml.in/yaml/v2/readerc.go | 412 + .../vendor/go.yaml.in/yaml/v2/resolve.go | 258 + .../vendor/go.yaml.in/yaml/v2/scannerc.go | 2711 ++ .../vendor/go.yaml.in/yaml/v2/sorter.go | 113 + .../vendor/go.yaml.in/yaml/v2/writerc.go | 26 + .../traefik/vendor/go.yaml.in/yaml/v2/yaml.go | 478 + .../vendor/go.yaml.in/yaml/v2/yamlh.go | 739 + .../vendor/go.yaml.in/yaml/v2/yamlprivateh.go | 173 + .../traefik/vendor/go.yaml.in/yaml/v3/LICENSE | 50 + .../traefik/vendor/go.yaml.in/yaml/v3/NOTICE | 13 + .../vendor/go.yaml.in/yaml/v3/README.md | 171 + .../traefik/vendor/go.yaml.in/yaml/v3/apic.go | 747 + .../vendor/go.yaml.in/yaml/v3/decode.go | 1018 + .../vendor/go.yaml.in/yaml/v3/emitterc.go | 2054 + .../vendor/go.yaml.in/yaml/v3/encode.go | 577 + .../vendor/go.yaml.in/yaml/v3/parserc.go | 1274 + .../vendor/go.yaml.in/yaml/v3/readerc.go | 434 + .../vendor/go.yaml.in/yaml/v3/resolve.go | 326 + .../vendor/go.yaml.in/yaml/v3/scannerc.go | 3040 ++ .../vendor/go.yaml.in/yaml/v3/sorter.go | 134 + .../vendor/go.yaml.in/yaml/v3/writerc.go | 48 + .../traefik/vendor/go.yaml.in/yaml/v3/yaml.go | 703 + .../vendor/go.yaml.in/yaml/v3/yamlh.go | 811 + .../vendor/go.yaml.in/yaml/v3/yamlprivateh.go | 198 + .../golang.org/x/crypto/argon2/argon2.go | 287 + .../golang.org/x/crypto/argon2/blake2b.go | 53 + .../x/crypto/argon2/blamka_amd64.go | 60 + .../golang.org/x/crypto/argon2/blamka_amd64.s | 2791 ++ .../x/crypto/argon2/blamka_generic.go | 163 + .../golang.org/x/crypto/argon2/blamka_ref.go | 15 + .../golang.org/x/crypto/bcrypt/bcrypt.go | 2 +- .../golang.org/x/crypto/blake2b/blake2b.go | 291 + .../x/crypto/blake2b/blake2bAVX2_amd64.go | 37 + .../x/crypto/blake2b/blake2bAVX2_amd64.s | 4559 ++ .../x/crypto/blake2b/blake2b_amd64.s | 1441 + .../x/crypto/blake2b/blake2b_generic.go | 182 + .../blake2b/blake2b_ref.go} | 8 +- .../golang.org/x/crypto/blake2b/blake2x.go | 185 + .../golang.org/x/crypto/blake2b/go125.go | 11 + .../golang.org/x/crypto/blake2b/register.go | 30 + .../x/crypto/chacha20/chacha_arm64.s | 2 +- .../chacha20poly1305/chacha20poly1305.go | 3 + .../chacha20poly1305_amd64.go | 10 +- .../chacha20poly1305_generic.go | 10 +- .../chacha20poly1305/fips140only_compat.go | 9 + .../chacha20poly1305/fips140only_go1.26.go | 11 + .../chacha20poly1305/xchacha20poly1305.go | 3 + .../golang.org/x/crypto/cryptobyte/asn1.go | 2 +- .../x/crypto/curve25519/curve25519.go | 13 +- .../golang.org/x/crypto/ed25519/ed25519.go | 11 +- .../x/crypto/internal/poly1305/mac_noasm.go | 2 +- .../poly1305/{sum_amd64.go => sum_asm.go} | 2 +- .../x/crypto/internal/poly1305/sum_loong64.s | 123 + .../x/crypto/internal/poly1305/sum_ppc64x.go | 47 - .../x/crypto/salsa20/salsa/hsalsa20.go | 4 + .../golang.org/x/crypto/scrypt/scrypt.go | 3 + .../golang.org/x/crypto/ssh/agent/client.go | 28 +- .../golang.org/x/crypto/ssh/agent/keyring.go | 2 +- .../golang.org/x/crypto/ssh/agent/server.go | 9 +- .../vendor/golang.org/x/crypto/ssh/certs.go | 67 +- .../vendor/golang.org/x/crypto/ssh/cipher.go | 82 +- .../vendor/golang.org/x/crypto/ssh/client.go | 1 + .../golang.org/x/crypto/ssh/client_auth.go | 34 +- .../vendor/golang.org/x/crypto/ssh/common.go | 477 +- .../golang.org/x/crypto/ssh/connection.go | 12 + .../vendor/golang.org/x/crypto/ssh/doc.go | 11 + .../golang.org/x/crypto/ssh/handshake.go | 36 +- .../vendor/golang.org/x/crypto/ssh/kex.go | 155 +- .../vendor/golang.org/x/crypto/ssh/keys.go | 97 +- .../vendor/golang.org/x/crypto/ssh/mac.go | 42 +- .../golang.org/x/crypto/ssh/messages.go | 8 +- .../vendor/golang.org/x/crypto/ssh/mlkem.go | 168 + .../vendor/golang.org/x/crypto/ssh/server.go | 46 +- .../vendor/golang.org/x/crypto/ssh/ssh_gss.go | 8 +- .../golang.org/x/crypto/ssh/streamlocal.go | 4 +- .../vendor/golang.org/x/crypto/ssh/tcpip.go | 124 +- .../golang.org/x/crypto/ssh/transport.go | 19 +- .../x/crypto/x509roots/fallback/bundle.go | 3776 -- .../x509roots/fallback/bundle/bundle.der | Bin 0 -> 153631 bytes .../x509roots/fallback/bundle/bundle.go | 879 + .../crypto/x509roots/fallback/bundle/roots.go | 73 + .../x/crypto/x509roots/fallback/fallback.go | 24 +- .../traefik/vendor/golang.org/x/exp/LICENSE | 4 +- .../x/exp/constraints/constraints.go | 50 - .../vendor/golang.org/x/exp/rand/exp.go | 221 - .../vendor/golang.org/x/exp/rand/normal.go | 156 - .../vendor/golang.org/x/exp/rand/rand.go | 372 - .../vendor/golang.org/x/exp/rand/rng.go | 91 - .../vendor/golang.org/x/exp/rand/zipf.go | 77 - .../vendor/golang.org/x/exp/slices/cmp.go | 44 - .../vendor/golang.org/x/exp/slices/slices.go | 447 +- .../vendor/golang.org/x/exp/slices/sort.go | 166 +- .../golang.org/x/exp/slices/zsortanyfunc.go | 479 - .../golang.org/x/exp/slices/zsortordered.go | 481 - .../x/mod/internal/lazyregexp/lazyre.go | 78 - .../vendor/golang.org/x/mod/modfile/print.go | 184 - .../vendor/golang.org/x/mod/modfile/read.go | 964 - .../vendor/golang.org/x/mod/modfile/rule.go | 1836 - .../vendor/golang.org/x/mod/modfile/work.go | 335 - .../vendor/golang.org/x/mod/module/module.go | 841 - .../vendor/golang.org/x/mod/module/pseudo.go | 250 - .../vendor/golang.org/x/mod/semver/semver.go | 34 +- .../vendor/golang.org/x/net/html/escape.go | 2 +- .../vendor/golang.org/x/net/html/iter.go | 2 - .../vendor/golang.org/x/net/html/node.go | 1 + .../golang.org/x/net/html/nodetype_string.go | 31 + .../vendor/golang.org/x/net/html/parse.go | 57 +- .../vendor/golang.org/x/net/html/render.go | 2 +- .../x/net/http2/client_priority_go126.go | 20 + .../x/net/http2/client_priority_go127.go | 13 + .../vendor/golang.org/x/net/http2/config.go | 63 +- .../golang.org/x/net/http2/config_go124.go | 61 - .../golang.org/x/net/http2/config_go125.go | 15 + .../golang.org/x/net/http2/config_go126.go | 15 + .../x/net/http2/config_pre_go124.go | 16 - .../vendor/golang.org/x/net/http2/frame.go | 295 +- .../vendor/golang.org/x/net/http2/gotrack.go | 17 +- .../vendor/golang.org/x/net/http2/h2c/h2c.go | 234 - .../golang.org/x/net/http2/hpack/tables.go | 13 +- .../vendor/golang.org/x/net/http2/http2.go | 53 +- .../vendor/golang.org/x/net/http2/server.go | 231 +- .../vendor/golang.org/x/net/http2/timer.go | 20 - .../golang.org/x/net/http2/transport.go | 374 +- .../golang.org/x/net/http2/writesched.go | 73 +- ...rity.go => writesched_priority_rfc7540.go} | 118 +- .../net/http2/writesched_priority_rfc9218.go | 224 + .../x/net/http2/writesched_random.go | 2 + .../x/net/http2/writesched_roundrobin.go | 2 +- .../x/net/internal/httpcommon/request.go | 4 +- .../x/net/internal/httpsfv/httpsfv.go | 665 + .../golang.org/x/net/internal/socket/empty.s | 2 +- .../internal/socket/msghdr_solaris_64bit.go | 7 +- .../x/net/internal/socket/socket.go | 5 +- .../golang.org/x/net/internal/socket/sys.go | 23 - .../x/net/internal/socket/sys_posix.go | 10 +- .../vendor/golang.org/x/net/ipv4/header.go | 18 +- .../x/net/ipv6/control_rfc2292_unix.go | 3 +- .../x/net/ipv6/control_rfc3542_unix.go | 9 +- .../vendor/golang.org/x/net/trace/events.go | 4 +- .../vendor/golang.org/x/oauth2/.travis.yml | 13 + .../golang.org/x/oauth2/CONTRIBUTING.md | 26 + .../vendor/golang.org/x/oauth2/LICENSE | 27 + .../vendor/golang.org/x/oauth2/README.md | 35 + .../x/oauth2/authhandler/authhandler.go | 94 + .../vendor/golang.org/x/oauth2/deviceauth.go | 227 + .../golang.org/x/oauth2/google/appengine.go | 40 + .../golang.org/x/oauth2/google/default.go | 440 + .../vendor/golang.org/x/oauth2/google/doc.go | 53 + .../golang.org/x/oauth2/google/error.go | 64 + .../x/oauth2/google/externalaccount/aws.go | 575 + .../google/externalaccount/basecredentials.go | 517 + .../externalaccount/executablecredsource.go | 312 + .../google/externalaccount/filecredsource.go | 60 + .../x/oauth2/google/externalaccount/header.go | 64 + .../programmaticrefreshcredsource.go | 21 + .../google/externalaccount/urlcredsource.go | 78 + .../golang.org/x/oauth2/google/google.go | 309 + .../externalaccountauthorizeduser.go | 114 + .../internal/impersonate/impersonate.go | 104 + .../google/internal/stsexchange/clientauth.go | 45 + .../internal/stsexchange/sts_exchange.go | 124 + .../vendor/golang.org/x/oauth2/google/jwt.go | 102 + .../vendor/golang.org/x/oauth2/google/sdk.go | 201 + .../golang.org/x/oauth2/internal/doc.go | 6 + .../golang.org/x/oauth2/internal/oauth2.go | 37 + .../golang.org/x/oauth2/internal/token.go | 356 + .../golang.org/x/oauth2/internal/transport.go | 28 + .../vendor/golang.org/x/oauth2/jws/jws.go | 198 + .../vendor/golang.org/x/oauth2/jwt/jwt.go | 182 + .../vendor/golang.org/x/oauth2/oauth2.go | 423 + .../vendor/golang.org/x/oauth2/pkce.go | 69 + .../vendor/golang.org/x/oauth2/token.go | 213 + .../vendor/golang.org/x/oauth2/transport.go | 75 + .../golang.org/x/sync/errgroup/errgroup.go | 127 +- .../golang.org/x/sync/semaphore/semaphore.go | 160 + .../x/sync/singleflight/singleflight.go | 14 +- .../x/sys/cpu/asm_darwin_arm64_gc.s | 12 + .../vendor/golang.org/x/sys/cpu/cpu.go | 23 + .../vendor/golang.org/x/sys/cpu/cpu_arm64.go | 9 +- .../vendor/golang.org/x/sys/cpu/cpu_arm64.s | 12 +- .../golang.org/x/sys/cpu/cpu_darwin_arm64.go | 67 + .../x/sys/cpu/cpu_darwin_arm64_other.go | 31 + .../golang.org/x/sys/cpu/cpu_gccgo_arm64.go | 1 + .../golang.org/x/sys/cpu/cpu_linux_loong64.go | 22 + .../golang.org/x/sys/cpu/cpu_linux_noinit.go | 2 +- .../golang.org/x/sys/cpu/cpu_linux_riscv64.go | 23 + .../golang.org/x/sys/cpu/cpu_loong64.go | 38 + .../vendor/golang.org/x/sys/cpu/cpu_loong64.s | 13 + .../golang.org/x/sys/cpu/cpu_other_arm64.go | 6 +- .../golang.org/x/sys/cpu/cpu_riscv64.go | 12 + .../vendor/golang.org/x/sys/cpu/cpu_x86.go | 174 +- .../vendor/golang.org/x/sys/cpu/parse.go | 4 +- .../x/sys/cpu/syscall_darwin_arm64_gc.go | 54 + .../golang.org/x/sys/plan9/pwd_go15_plan9.go | 21 - .../golang.org/x/sys/plan9/pwd_plan9.go | 14 +- .../golang.org/x/sys/plan9/syscall_plan9.go | 8 +- .../golang.org/x/sys/unix/affinity_linux.go | 9 +- .../vendor/golang.org/x/sys/unix/fdset.go | 4 +- .../golang.org/x/sys/unix/ifreq_linux.go | 4 +- .../golang.org/x/sys/unix/ioctl_signed.go | 11 +- .../golang.org/x/sys/unix/ioctl_unsigned.go | 11 +- .../vendor/golang.org/x/sys/unix/mkall.sh | 1 + .../vendor/golang.org/x/sys/unix/mkerrors.sh | 8 +- .../golang.org/x/sys/unix/syscall_darwin.go | 93 + .../golang.org/x/sys/unix/syscall_linux.go | 52 +- .../golang.org/x/sys/unix/syscall_netbsd.go | 17 + .../golang.org/x/sys/unix/syscall_solaris.go | 10 +- .../golang.org/x/sys/unix/syscall_unix.go | 10 +- .../golang.org/x/sys/unix/zerrors_linux.go | 424 +- .../x/sys/unix/zerrors_linux_386.go | 5 + .../x/sys/unix/zerrors_linux_amd64.go | 5 + .../x/sys/unix/zerrors_linux_arm.go | 5 + .../x/sys/unix/zerrors_linux_arm64.go | 5 + .../x/sys/unix/zerrors_linux_loong64.go | 5 + .../x/sys/unix/zerrors_linux_mips.go | 5 + .../x/sys/unix/zerrors_linux_mips64.go | 5 + .../x/sys/unix/zerrors_linux_mips64le.go | 5 + .../x/sys/unix/zerrors_linux_mipsle.go | 5 + .../x/sys/unix/zerrors_linux_ppc.go | 5 + .../x/sys/unix/zerrors_linux_ppc64.go | 5 + .../x/sys/unix/zerrors_linux_ppc64le.go | 5 + .../x/sys/unix/zerrors_linux_riscv64.go | 5 + .../x/sys/unix/zerrors_linux_s390x.go | 5 + .../x/sys/unix/zerrors_linux_sparc64.go | 5 + .../x/sys/unix/zsyscall_darwin_amd64.go | 84 + .../x/sys/unix/zsyscall_darwin_amd64.s | 20 + .../x/sys/unix/zsyscall_darwin_arm64.go | 84 + .../x/sys/unix/zsyscall_darwin_arm64.s | 20 + .../golang.org/x/sys/unix/zsyscall_linux.go | 10 + .../x/sys/unix/zsyscall_solaris_amd64.go | 8 +- .../x/sys/unix/zsysnum_linux_386.go | 1 + .../x/sys/unix/zsysnum_linux_amd64.go | 1 + .../x/sys/unix/zsysnum_linux_arm.go | 1 + .../x/sys/unix/zsysnum_linux_arm64.go | 1 + .../x/sys/unix/zsysnum_linux_loong64.go | 1 + .../x/sys/unix/zsysnum_linux_mips.go | 1 + .../x/sys/unix/zsysnum_linux_mips64.go | 1 + .../x/sys/unix/zsysnum_linux_mips64le.go | 1 + .../x/sys/unix/zsysnum_linux_mipsle.go | 1 + .../x/sys/unix/zsysnum_linux_ppc.go | 1 + .../x/sys/unix/zsysnum_linux_ppc64.go | 1 + .../x/sys/unix/zsysnum_linux_ppc64le.go | 1 + .../x/sys/unix/zsysnum_linux_riscv64.go | 1 + .../x/sys/unix/zsysnum_linux_s390x.go | 1 + .../x/sys/unix/zsysnum_linux_sparc64.go | 1 + .../golang.org/x/sys/unix/ztypes_linux.go | 434 +- .../golang.org/x/sys/unix/ztypes_linux_386.go | 18 +- .../x/sys/unix/ztypes_linux_amd64.go | 16 + .../golang.org/x/sys/unix/ztypes_linux_arm.go | 20 +- .../x/sys/unix/ztypes_linux_arm64.go | 16 + .../x/sys/unix/ztypes_linux_loong64.go | 16 + .../x/sys/unix/ztypes_linux_mips.go | 18 +- .../x/sys/unix/ztypes_linux_mips64.go | 16 + .../x/sys/unix/ztypes_linux_mips64le.go | 16 + .../x/sys/unix/ztypes_linux_mipsle.go | 18 +- .../golang.org/x/sys/unix/ztypes_linux_ppc.go | 20 +- .../x/sys/unix/ztypes_linux_ppc64.go | 16 + .../x/sys/unix/ztypes_linux_ppc64le.go | 16 + .../x/sys/unix/ztypes_linux_riscv64.go | 16 + .../x/sys/unix/ztypes_linux_s390x.go | 16 + .../x/sys/unix/ztypes_linux_sparc64.go | 16 + .../x/sys/unix/ztypes_netbsd_arm.go | 2 +- .../golang.org/x/sys/windows/aliases.go | 1 + .../golang.org/x/sys/windows/dll_windows.go | 37 +- .../golang.org/x/sys/windows/registry/key.go | 227 + .../x/sys/windows/registry/mksyscall.go | 9 + .../x/sys/windows/registry/syscall.go | 32 + .../x/sys/windows/registry/value.go | 390 + .../sys/windows/registry/zsyscall_windows.go | 117 + .../x/sys/windows/security_windows.go | 55 +- .../golang.org/x/sys/windows/svc/service.go | 20 +- .../x/sys/windows/syscall_windows.go | 38 +- .../golang.org/x/sys/windows/types_windows.go | 422 + .../x/sys/windows/zsyscall_windows.go | 1035 +- .../vendor/golang.org/x/term/term_windows.go | 4 +- .../vendor/golang.org/x/term/terminal.go | 118 +- .../golang.org/x/text/cases/tables10.0.0.go | 2255 - .../golang.org/x/text/cases/tables11.0.0.go | 2316 - .../golang.org/x/text/cases/tables12.0.0.go | 2359 -- .../golang.org/x/text/cases/tables15.0.0.go | 2 +- .../{tables13.0.0.go => tables17.0.0.go} | 1473 +- .../golang.org/x/text/cases/tables9.0.0.go | 2215 - .../x/text/message/catalog/catalog.go | 2 +- .../golang.org/x/text/message/catalog/dict.go | 6 +- .../golang.org/x/text/message/catalog/go19.go | 15 - .../x/text/message/catalog/gopre19.go | 23 - .../x/text/secure/bidirule/bidirule.go | 4 + .../x/text/secure/bidirule/bidirule9.0.0.go | 14 - .../x/text/secure/precis/tables10.0.0.go | 3889 -- .../x/text/secure/precis/tables11.0.0.go | 4016 -- .../x/text/secure/precis/tables12.0.0.go | 4118 -- .../x/text/secure/precis/tables13.0.0.go | 4152 -- .../x/text/secure/precis/tables15.0.0.go | 2 +- .../x/text/secure/precis/tables17.0.0.go | 4486 ++ .../x/text/secure/precis/tables9.0.0.go | 3790 -- .../golang.org/x/text/unicode/bidi/core.go | 11 +- .../x/text/unicode/bidi/tables10.0.0.go | 1815 - .../x/text/unicode/bidi/tables11.0.0.go | 1887 - .../x/text/unicode/bidi/tables12.0.0.go | 1923 - .../x/text/unicode/bidi/tables13.0.0.go | 1955 - .../x/text/unicode/bidi/tables15.0.0.go | 2 +- .../x/text/unicode/bidi/tables17.0.0.go | 2135 + .../x/text/unicode/bidi/tables9.0.0.go | 1781 - .../x/text/unicode/norm/forminfo.go | 26 +- .../x/text/unicode/norm/tables10.0.0.go | 7657 ---- .../x/text/unicode/norm/tables11.0.0.go | 7693 ---- .../x/text/unicode/norm/tables12.0.0.go | 7710 ---- .../x/text/unicode/norm/tables15.0.0.go | 2820 +- .../norm/{tables13.0.0.go => tables17.0.0.go} | 6716 +-- .../x/text/unicode/norm/tables9.0.0.go | 7637 ---- .../golang.org/x/text/width/tables10.0.0.go | 1328 - .../golang.org/x/text/width/tables11.0.0.go | 1340 - .../golang.org/x/text/width/tables12.0.0.go | 1360 - .../golang.org/x/text/width/tables15.0.0.go | 2 +- .../{tables13.0.0.go => tables17.0.0.go} | 533 +- .../golang.org/x/text/width/tables9.0.0.go | 1296 - .../vendor/golang.org/x/time/rate/rate.go | 2 +- .../golang.org/x/time/rate/sometimes.go | 4 +- .../x/tools/cmd/stringer/stringer.go | 736 - .../x/tools/go/ast/astutil/enclosing.go | 654 - .../x/tools/go/ast/astutil/imports.go | 490 - .../x/tools/go/ast/astutil/rewrite.go | 486 - .../golang.org/x/tools/go/ast/astutil/util.go | 13 - .../{internal/astutil => go/ast}/edge/edge.go | 0 .../x/tools/go/ast/inspector/cursor.go | 551 + .../x/tools/go/ast/inspector/inspector.go | 53 +- .../x/tools/go/ast/inspector/iter.go | 36 +- .../x/tools/go/ast/inspector/typeof.go | 3 - .../x/tools/go/ast/inspector/walk.go | 2 +- .../x/tools/go/gcexportdata/gcexportdata.go | 5 +- .../golang.org/x/tools/go/packages/doc.go | 2 + .../x/tools/go/packages/external.go | 2 +- .../golang.org/x/tools/go/packages/golist.go | 59 +- .../x/tools/go/packages/golist_overlay.go | 2 +- .../x/tools/go/packages/packages.go | 74 +- .../golang.org/x/tools/go/packages/visit.go | 85 +- .../x/tools/go/types/objectpath/objectpath.go | 23 +- .../x/tools/go/types/typeutil/callee.go | 84 +- .../x/tools/go/types/typeutil/map.go | 22 +- .../golang.org/x/tools/imports/forward.go | 77 - .../x/tools/internal/aliases/aliases.go | 30 +- .../x/tools/internal/aliases/aliases_go122.go | 80 - .../x/tools/internal/event/core/event.go | 28 +- .../x/tools/internal/event/core/export.go | 15 +- .../x/tools/internal/event/keys/keys.go | 439 +- .../x/tools/internal/event/label/label.go | 30 +- .../x/tools/internal/gcimporter/bimport.go | 2 +- .../x/tools/internal/gcimporter/iexport.go | 82 +- .../x/tools/internal/gcimporter/iimport.go | 65 +- .../internal/gcimporter/iimport_go122.go | 53 - .../gcimporter/{ureader_yes.go => ureader.go} | 114 +- .../x/tools/internal/gocommand/invoke.go | 2 +- .../x/tools/internal/gocommand/version.go | 3 + .../x/tools/internal/gopathwalk/walk.go | 337 - .../x/tools/internal/imports/fix.go | 1900 - .../x/tools/internal/imports/imports.go | 359 - .../x/tools/internal/imports/mod.go | 840 - .../x/tools/internal/imports/mod_cache.go | 331 - .../x/tools/internal/imports/sortimports.go | 297 - .../x/tools/internal/imports/source.go | 63 - .../x/tools/internal/imports/source_env.go | 129 - .../tools/internal/imports/source_modindex.go | 103 - .../x/tools/internal/modindex/directories.go | 135 - .../x/tools/internal/modindex/index.go | 266 - .../x/tools/internal/modindex/lookup.go | 178 - .../x/tools/internal/modindex/modindex.go | 164 - .../x/tools/internal/modindex/symbols.go | 218 - .../x/tools/internal/modindex/types.go | 25 - .../internal/packagesinternal/packages.go | 9 +- .../x/tools/internal/pkgbits/decoder.go | 2 +- .../x/tools/internal/pkgbits/version.go | 17 + .../x/tools/internal/stdlib/deps.go | 780 +- .../x/tools/internal/stdlib/import.go | 8 + .../x/tools/internal/stdlib/manifest.go | 35278 ++++++++-------- .../x/tools/internal/stdlib/stdlib.go | 10 +- .../x/tools/internal/typeparams/coretype.go | 8 +- .../x/tools/internal/typeparams/free.go | 6 +- .../x/tools/internal/typeparams/normalize.go | 6 +- .../x/tools/internal/typeparams/termlist.go | 12 +- .../x/tools/internal/typeparams/typeterm.go | 3 + .../internal/typesinternal/classify_call.go | 137 + .../x/tools/internal/typesinternal/element.go | 4 +- .../x/tools/internal/typesinternal/fx.go | 88 + .../x/tools/internal/typesinternal/isnamed.go | 71 + .../tools/internal/typesinternal/qualifier.go | 8 + .../x/tools/internal/typesinternal/types.go | 179 +- .../x/tools/internal/typesinternal/varkind.go | 39 +- .../internal/typesinternal/varkind_go124.go | 39 + .../tools/internal/typesinternal/zerovalue.go | 31 +- .../x/tools/internal/versions/features.go | 8 +- .../mock => google.golang.org/api}/AUTHORS | 5 +- .../vendor/google.golang.org/api/CONTRIBUTORS | 56 + .../vendor/google.golang.org/api/LICENSE | 27 + .../v1/cloudresourcemanager-api.json | 2311 + .../v1/cloudresourcemanager-gen.go | 6405 +++ .../api/googleapi/googleapi.go | 552 + .../api/googleapi/transport/apikey.go | 44 + .../google.golang.org/api/googleapi/types.go | 202 + .../google.golang.org/api/internal/cba.go | 294 + .../api/internal/cert/default_cert.go | 58 + .../api/internal/cert/enterprise_cert.go | 54 + .../api/internal/cert/secureconnect_cert.go | 122 + .../api/internal/conn_pool.go | 30 + .../credentialstype/credentialstype.go | 113 + .../google.golang.org/api/internal/creds.go | 341 + .../api/internal/gensupport/buffer.go | 92 + .../api/internal/gensupport/doc.go | 10 + .../api/internal/gensupport/error.go | 24 + .../api/internal/gensupport/json.go | 236 + .../api/internal/gensupport/jsonfloat.go | 47 + .../api/internal/gensupport/media.go | 334 + .../api/internal/gensupport/params.go | 78 + .../api/internal/gensupport/resumable.go | 356 + .../api/internal/gensupport/retry.go | 123 + .../api/internal/gensupport/send.go | 241 + .../api/internal/gensupport/version.go | 53 + .../api/internal/impersonate/impersonate.go | 127 + .../google.golang.org/api/internal/s2a.go | 136 + .../api/internal/settings.go | 303 + .../internal/third_party/uritemplates/LICENSE | 27 + .../third_party/uritemplates/METADATA | 14 + .../third_party/uritemplates/uritemplates.go | 248 + .../third_party/uritemplates/utils.go | 17 + .../google.golang.org/api/internal/version.go | 8 + .../option/internaloption/internaloption.go | 337 + .../option/internaloption/unsaferesolver.go | 106 + .../google.golang.org/api/option/option.go | 537 + .../api/transport/http/dial.go | 324 + .../api/expr/v1alpha1/checked.pb.go | 2 +- .../googleapis/api/expr/v1alpha1/eval.pb.go | 2 +- .../api/expr/v1alpha1/explain.pb.go | 2 +- .../googleapis/api/expr/v1alpha1/syntax.pb.go | 2 +- .../googleapis/api/expr/v1alpha1/value.pb.go | 2 +- .../googleapis/api/httpbody/httpbody.pb.go | 235 + .../genproto/googleapis/rpc/code/code.pb.go | 336 + .../rpc/errdetails/error_details.pb.go | 1473 + .../googleapis/rpc/status/status.pb.go | 7 +- .../google.golang.org/grpc/CONTRIBUTING.md | 186 +- .../google.golang.org/grpc/MAINTAINERS.md | 8 +- .../vendor/google.golang.org/grpc/README.md | 1 + .../grpc/attributes/attributes.go | 77 +- .../grpc/balancer/balancer.go | 152 +- .../grpc/balancer/base/balancer.go | 16 +- .../endpointsharding/endpointsharding.go | 388 + .../balancer/pickfirst/internal/internal.go | 37 + .../grpc/balancer/pickfirst/pickfirst.go | 918 +- .../grpc/balancer/roundrobin/roundrobin.go | 65 +- .../grpc/balancer/subconn.go | 120 + .../grpc/balancer_wrapper.go | 204 +- .../grpc_binarylog_v1/binarylog.pb.go | 481 +- .../google.golang.org/grpc/clientconn.go | 328 +- .../grpc/cmd/protoc-gen-go-grpc/LICENSE | 202 + .../grpc/cmd/protoc-gen-go-grpc/README.md | 28 + .../grpc/cmd/protoc-gen-go-grpc/grpc.go | 634 + .../grpc/cmd/protoc-gen-go-grpc/main.go | 76 + .../protoc-gen-go-grpc_test.sh | 50 + .../vendor/google.golang.org/grpc/codec.go | 2 +- .../grpc/credentials/credentials.go | 62 +- .../grpc/credentials/insecure/insecure.go | 8 +- .../google.golang.org/grpc/credentials/tls.go | 83 +- .../google.golang.org/grpc/dialoptions.go | 91 +- .../grpc/encoding/encoding.go | 24 +- .../grpc/encoding/gzip/gzip.go | 120 + .../grpc/encoding/internal/internal.go | 28 + .../grpc/encoding/proto/proto.go | 20 +- .../grpc/experimental/stats/metricregistry.go | 99 +- .../grpc/experimental/stats/metrics.go | 139 +- .../grpc/grpclog/internal/loggerv2.go | 107 +- .../grpc/health/grpc_health_v1/health.pb.go | 350 + .../health/grpc_health_v1/health_grpc.pb.go | 290 + .../google.golang.org/grpc/interceptor.go | 12 +- .../grpc/internal/backoff/backoff.go | 2 +- .../balancer/gracefulswitch/config.go | 2 + .../balancer/gracefulswitch/gracefulswitch.go | 32 +- .../grpc/internal/balancer/weight/weight.go | 66 + .../grpc/internal/buffer/unbounded.go | 1 + .../grpc/internal/channelz/channel.go | 15 + .../grpc/internal/channelz/server.go | 2 + .../grpc/internal/channelz/socket.go | 7 + .../grpc/internal/channelz/subchannel.go | 2 + .../grpc/internal/channelz/trace.go | 21 +- .../grpc/internal/credentials/credentials.go | 14 - .../grpc/internal/envconfig/envconfig.go | 94 +- .../grpc/internal/envconfig/xds.go | 26 + .../grpc/internal/experimental.go | 7 + .../internal/grpcsync/callback_serializer.go | 24 +- .../grpc/internal/grpcsync/event.go | 19 +- .../grpc/internal/grpcutil/method.go | 2 +- .../grpc/internal/idle/idle.go | 81 +- .../grpc/internal/internal.go | 123 +- .../grpc/internal/mem/buffer_pool.go | 338 + .../grpc/internal/metadata/metadata.go | 26 +- .../proxyattributes/proxyattributes.go | 54 + .../delegatingresolver/delegatingresolver.go | 477 + .../internal/resolver/dns/dns_resolver.go | 82 +- .../internal/stats/metrics_recorder_list.go | 80 + .../grpc/internal/stats/stats.go | 70 + .../grpc/internal/status/status.go | 43 +- .../grpc/internal/transport/client_stream.go | 156 + .../grpc/internal/transport/controlbuf.go | 126 +- .../grpc/internal/transport/defaults.go | 1 + .../grpc/internal/transport/flowcontrol.go | 32 +- .../grpc/internal/transport/handler_server.go | 82 +- .../grpc/internal/transport/http2_client.go | 444 +- .../grpc/internal/transport/http2_server.go | 293 +- .../grpc/internal/transport/http_util.go | 176 +- .../grpc/internal/transport/proxy.go | 62 +- .../grpc/internal/transport/server_stream.go | 189 + .../grpc/internal/transport/transport.go | 444 +- .../google.golang.org/grpc/mem/buffer_pool.go | 164 +- .../grpc/mem/buffer_slice.go | 163 +- .../google.golang.org/grpc/mem/buffers.go | 97 +- .../google.golang.org/grpc/picker_wrapper.go | 42 +- .../google.golang.org/grpc/preloader.go | 7 +- .../google.golang.org/grpc/resolver/map.go | 192 +- .../grpc/resolver/resolver.go | 31 +- .../grpc/resolver_wrapper.go | 37 +- .../vendor/google.golang.org/grpc/rpc_util.go | 266 +- .../vendor/google.golang.org/grpc/server.go | 267 +- .../google.golang.org/grpc/service_config.go | 22 +- .../google.golang.org/grpc/stats/handlers.go | 9 + .../google.golang.org/grpc/stats/metrics.go | 81 + .../google.golang.org/grpc/stats/stats.go | 129 +- .../vendor/google.golang.org/grpc/stream.go | 592 +- .../vendor/google.golang.org/grpc/version.go | 2 +- .../cmd/protoc-gen-go/internal_gengo/init.go | 167 + .../internal_gengo/init_opaque.go | 33 + .../cmd/protoc-gen-go/internal_gengo/main.go | 933 + .../protoc-gen-go/internal_gengo/opaque.go | 1220 + .../protoc-gen-go/internal_gengo/reflect.go | 361 + .../internal_gengo/well_known_types.go | 1094 + .../protobuf/cmd/protoc-gen-go/main.go | 60 + .../protobuf/compiler/protogen/protogen.go | 1617 + .../compiler/protogen/protogen_apilevel.go | 173 + .../compiler/protogen/protogen_opaque.go | 110 + .../protobuf/encoding/protowire/wire.go | 26 +- .../editiondefaults/editions_defaults.binpb | Bin 146 -> 154 bytes .../internal/editionssupport/editions.go | 2 +- .../protobuf/internal/encoding/tag/tag.go | 11 +- .../protobuf/internal/encoding/text/decode.go | 115 +- .../protobuf/internal/filedesc/desc.go | 53 +- .../protobuf/internal/filedesc/desc_init.go | 14 + .../protobuf/internal/filedesc/desc_lazy.go | 42 +- .../protobuf/internal/filedesc/editions.go | 15 +- .../protobuf/internal/filedesc/presence.go | 33 + .../protobuf/internal/genid/api_gen.go | 6 + .../protobuf/internal/genid/descriptor_gen.go | 91 +- .../protobuf/internal/impl/codec_map.go | 6 + .../internal/impl/codec_message_opaque.go | 3 +- .../protobuf/internal/impl/decode.go | 3 +- .../protobuf/internal/impl/message_opaque.go | 45 +- .../protobuf/internal/impl/presence.go | 3 - .../protobuf/internal/impl/validate.go | 26 + .../protobuf/internal/msgfmt/format.go | 261 + .../protobuf/internal/version/version.go | 2 +- .../protobuf/proto/decode.go | 10 +- .../protobuf/reflect/protodesc/desc.go | 29 +- .../protobuf/reflect/protodesc/desc_init.go | 2 + .../protobuf/reflect/protodesc/editions.go | 4 +- .../protobuf/reflect/protodesc/proto.go | 37 +- .../protobuf/reflect/protopath/path.go | 122 + .../protobuf/reflect/protopath/step.go | 241 + .../protobuf/reflect/protorange/range.go | 316 + .../reflect/protoreflect/source_gen.go | 8 + .../types/descriptorpb/descriptor.pb.go | 656 +- .../types/known/fieldmaskpb/field_mask.pb.go | 560 + .../types/known/timestamppb/timestamp.pb.go | 13 +- .../protobuf/types/pluginpb/plugin.pb.go | 583 + plugins/traefik/vendor/modules.txt | 659 +- 2791 files changed, 383342 insertions(+), 223483 deletions(-) create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/CHANGES.md rename plugins/traefik/vendor/{github.com/google/pprof => cloud.google.com/go/auth}/LICENSE (100%) create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/README.md create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/auth.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/compute.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/detect.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/doc.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/filetypes.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/aws_provider.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/executable_provider.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/externalaccount.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/file_provider.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/info.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/programmatic_provider.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/url_provider.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/x509_provider.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccountuser/externalaccountuser.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/gdch/gdch.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/idtoken.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/stsexchange/sts_exchange.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/credentials/selfsignedjwt.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/httptransport/httptransport.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/httptransport/transport.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/credsfile/credsfile.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/credsfile/filetype.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/credsfile/parse.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/internal.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/jwt/jwt.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/retry/retry.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cba.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/default_cert.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/enterprise_cert.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/secureconnect_cert.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/workload_cert.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/headers/headers.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/s2a.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/transport.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/trustboundary/external_accounts_config_providers.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/trustboundary/trust_boundary.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/internal/version.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/oauth2adapt/CHANGES.md rename plugins/traefik/vendor/{go.uber.org/mock => cloud.google.com/go/auth/oauth2adapt}/LICENSE (100%) create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/oauth2adapt/oauth2adapt.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/auth/threelegged.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/compute/metadata/CHANGES.md create mode 100644 plugins/traefik/vendor/cloud.google.com/go/compute/metadata/LICENSE create mode 100644 plugins/traefik/vendor/cloud.google.com/go/compute/metadata/README.md create mode 100644 plugins/traefik/vendor/cloud.google.com/go/compute/metadata/log.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/compute/metadata/metadata.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/compute/metadata/retry.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/compute/metadata/retry_linux.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/compute/metadata/syscheck.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/compute/metadata/syscheck_linux.go create mode 100644 plugins/traefik/vendor/cloud.google.com/go/compute/metadata/syscheck_windows.go create mode 100644 plugins/traefik/vendor/dario.cat/mergo/FUNDING.json create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/LICENSE create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/README.md create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/nat.go create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/nat_386.s create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/nat_amd64.s create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/nat_arm.s create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/nat_arm64.s create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/nat_asm.go create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/nat_loong64.s create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/nat_noasm.go create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/nat_ppc64x.s create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/nat_riscv64.s create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/nat_s390x.s create mode 100644 plugins/traefik/vendor/filippo.io/bigmod/nat_wasm.go delete mode 100644 plugins/traefik/vendor/filippo.io/edwards25519/field/fe_arm64.go delete mode 100644 plugins/traefik/vendor/filippo.io/edwards25519/field/fe_arm64.s delete mode 100644 plugins/traefik/vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go create mode 100644 plugins/traefik/vendor/filippo.io/edwards25519/pull.sh delete mode 100644 plugins/traefik/vendor/github.com/Microsoft/go-winio/tools.go create mode 100644 plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/mutex.go create mode 100644 plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/mutex_nomutex.go create mode 100644 plugins/traefik/vendor/github.com/caddyserver/caddy/v2/.pre-commit-config.yaml create mode 100644 plugins/traefik/vendor/github.com/caddyserver/caddy/v2/AGENTS.md create mode 100644 plugins/traefik/vendor/github.com/caddyserver/caddy/v2/internal/logbuffer.go create mode 100644 plugins/traefik/vendor/github.com/caddyserver/caddy/v2/internal/logmarshalers.go rename plugins/traefik/vendor/{go.uber.org/mock/mockgen/version.go => github.com/caddyserver/caddy/v2/listen_reuseUnixSocket.go} (60%) create mode 100644 plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen_reuseUnixSocket_windows.go create mode 100644 plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.editorconfig create mode 100644 plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.gitattributes create mode 100644 plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.golangci.yml create mode 100644 plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.ls-lint.yml create mode 100644 plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.markdownlint.yml create mode 100644 plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.yamllint.yml rename plugins/traefik/vendor/github.com/{go-kit/log => ccoveille/go-safecast/v2}/LICENSE (97%) create mode 100644 plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/README.md create mode 100644 plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/conversion.go create mode 100644 plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/doc.go create mode 100644 plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/errors.go create mode 100644 plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/parse.go create mode 100644 plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/types.go rename plugins/traefik/vendor/github.com/{jackc/pgx/v4 => cenkalti/backoff/v5}/.gitignore (94%) create mode 100644 plugins/traefik/vendor/github.com/cenkalti/backoff/v5/CHANGELOG.md create mode 100644 plugins/traefik/vendor/github.com/cenkalti/backoff/v5/LICENSE create mode 100644 plugins/traefik/vendor/github.com/cenkalti/backoff/v5/README.md create mode 100644 plugins/traefik/vendor/github.com/cenkalti/backoff/v5/backoff.go create mode 100644 plugins/traefik/vendor/github.com/cenkalti/backoff/v5/error.go create mode 100644 plugins/traefik/vendor/github.com/cenkalti/backoff/v5/exponential.go create mode 100644 plugins/traefik/vendor/github.com/cenkalti/backoff/v5/retry.go create mode 100644 plugins/traefik/vendor/github.com/cenkalti/backoff/v5/ticker.go create mode 100644 plugins/traefik/vendor/github.com/cenkalti/backoff/v5/timer.go create mode 100644 plugins/traefik/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/arm64.go create mode 100644 plugins/traefik/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/arm64.s create mode 100644 plugins/traefik/vendor/github.com/coreos/go-oidc/v3/LICENSE create mode 100644 plugins/traefik/vendor/github.com/coreos/go-oidc/v3/NOTICE create mode 100644 plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/jose.go create mode 100644 plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go create mode 100644 plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go create mode 100644 plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go delete mode 100644 plugins/traefik/vendor/github.com/darkweak/souin/api/main.go delete mode 100644 plugins/traefik/vendor/github.com/darkweak/souin/api/prometheus/prometheus.go delete mode 100644 plugins/traefik/vendor/github.com/darkweak/souin/api/souin.go delete mode 100644 plugins/traefik/vendor/github.com/darkweak/souin/api/types.go create mode 100644 plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/debug/debug.go delete mode 100644 plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/abstractProvider.go delete mode 100644 plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/cacheProvider.go create mode 100644 plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/defaultProvider.go create mode 100644 plugins/traefik/vendor/github.com/felixge/httpsnoop/.gitignore create mode 100644 plugins/traefik/vendor/github.com/felixge/httpsnoop/LICENSE.txt create mode 100644 plugins/traefik/vendor/github.com/felixge/httpsnoop/Makefile create mode 100644 plugins/traefik/vendor/github.com/felixge/httpsnoop/README.md create mode 100644 plugins/traefik/vendor/github.com/felixge/httpsnoop/capture_metrics.go create mode 100644 plugins/traefik/vendor/github.com/felixge/httpsnoop/docs.go create mode 100644 plugins/traefik/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go create mode 100644 plugins/traefik/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/.gitignore delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/.travis.yml delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/Gopkg.lock delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/Gopkg.toml delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/LICENSE delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/Makefile delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/README.md delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_array.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_bool.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_embedded_json.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_interface.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number_float.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number_int.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number_uint.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_object.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_pool.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_slice.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_sqlnull.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_stream.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_stream_pool.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_string.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_string_unicode.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_time.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/decode_unsafe.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_array.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_bool.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_builder.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_embedded_json.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_interface.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_null.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number_float.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number_int.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number_uint.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_object.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_pool.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_slice.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_sqlnull.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_stream.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_stream_pool.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_string.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/encode_time.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/errors.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/gojay.go delete mode 100644 plugins/traefik/vendor/github.com/francoispqt/gojay/gojay.png create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/.gitignore create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/.golangci.yml create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/.travis.yml create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/LICENSE create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/README.md create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/SECURITY.md create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/asymmetric.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/cbc_hmac.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/concat_kdf.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/ecdh_es.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/key_wrap.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/crypter.go rename plugins/traefik/vendor/{google.golang.org/grpc/internal/grpcsync/oncefunc.go => github.com/go-jose/go-jose/v4/doc.go} (55%) create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/encoding.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/LICENSE create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/README.md create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/decode.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/encode.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/indent.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/scanner.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/stream.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/tags.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/jwe.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/jwk.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/jws.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/opaque.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/shared.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/signing.go create mode 100644 plugins/traefik/vendor/github.com/go-jose/go-jose/v4/symmetric.go delete mode 100644 plugins/traefik/vendor/github.com/go-kit/kit/log/level/doc.go delete mode 100644 plugins/traefik/vendor/github.com/go-kit/kit/log/level/level.go delete mode 100644 plugins/traefik/vendor/github.com/go-kit/log/README.md delete mode 100644 plugins/traefik/vendor/github.com/go-kit/log/doc.go delete mode 100644 plugins/traefik/vendor/github.com/go-kit/log/json_logger.go delete mode 100644 plugins/traefik/vendor/github.com/go-kit/log/level/doc.go delete mode 100644 plugins/traefik/vendor/github.com/go-kit/log/level/level.go delete mode 100644 plugins/traefik/vendor/github.com/go-kit/log/log.go delete mode 100644 plugins/traefik/vendor/github.com/go-kit/log/logfmt_logger.go delete mode 100644 plugins/traefik/vendor/github.com/go-kit/log/nop_logger.go delete mode 100644 plugins/traefik/vendor/github.com/go-kit/log/staticcheck.conf delete mode 100644 plugins/traefik/vendor/github.com/go-kit/log/stdlib.go delete mode 100644 plugins/traefik/vendor/github.com/go-kit/log/sync.go delete mode 100644 plugins/traefik/vendor/github.com/go-kit/log/value.go delete mode 100644 plugins/traefik/vendor/github.com/go-logfmt/logfmt/.gitignore delete mode 100644 plugins/traefik/vendor/github.com/go-logfmt/logfmt/CHANGELOG.md delete mode 100644 plugins/traefik/vendor/github.com/go-logfmt/logfmt/LICENSE delete mode 100644 plugins/traefik/vendor/github.com/go-logfmt/logfmt/README.md delete mode 100644 plugins/traefik/vendor/github.com/go-logfmt/logfmt/decode.go delete mode 100644 plugins/traefik/vendor/github.com/go-logfmt/logfmt/doc.go delete mode 100644 plugins/traefik/vendor/github.com/go-logfmt/logfmt/encode.go delete mode 100644 plugins/traefik/vendor/github.com/go-logfmt/logfmt/jsonstring.go create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/.golangci.yaml create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/CHANGELOG.md create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/CONTRIBUTING.md create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/LICENSE create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/README.md create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/SECURITY.md create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/context.go create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/context_noslog.go create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/context_slog.go create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/discard.go create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/funcr/funcr.go create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/funcr/slogsink.go create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/logr.go create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/sloghandler.go create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/slogr.go create mode 100644 plugins/traefik/vendor/github.com/go-logr/logr/slogsink.go rename plugins/traefik/vendor/{go.step.sm/cli-utils => github.com/go-logr/stdr}/LICENSE (100%) create mode 100644 plugins/traefik/vendor/github.com/go-logr/stdr/README.md create mode 100644 plugins/traefik/vendor/github.com/go-logr/stdr/stdr.go delete mode 100644 plugins/traefik/vendor/github.com/go-sql-driver/mysql/atomic_bool.go delete mode 100644 plugins/traefik/vendor/github.com/go-sql-driver/mysql/atomic_bool_go118.go create mode 100644 plugins/traefik/vendor/github.com/go-sql-driver/mysql/compress.go delete mode 100644 plugins/traefik/vendor/github.com/go-sql-driver/mysql/fuzz.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/.editorconfig delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/.gitattributes delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/.gitignore delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/CHANGELOG.md delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/LICENSE.txt delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/README.md delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/Taskfile.yml delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/crypto.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/date.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/defaults.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/dict.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/doc.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/functions.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/list.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/network.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/numeric.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/reflect.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/regex.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/strings.go delete mode 100644 plugins/traefik/vendor/github.com/go-task/slim-sprig/url.go create mode 100644 plugins/traefik/vendor/github.com/google/cel-go/cel/fieldpaths.go create mode 100644 plugins/traefik/vendor/github.com/google/cel-go/cel/prompt.go create mode 100644 plugins/traefik/vendor/github.com/google/cel-go/cel/templates/authoring.tmpl create mode 100644 plugins/traefik/vendor/github.com/google/cel-go/common/types/format.go create mode 100644 plugins/traefik/vendor/github.com/google/cel-go/ext/extension_option_factory.go create mode 100644 plugins/traefik/vendor/github.com/google/cel-go/ext/formatting_v2.go create mode 100644 plugins/traefik/vendor/github.com/google/cel-go/ext/regex.go delete mode 100644 plugins/traefik/vendor/github.com/google/pprof/AUTHORS delete mode 100644 plugins/traefik/vendor/github.com/google/pprof/CONTRIBUTORS delete mode 100644 plugins/traefik/vendor/github.com/google/pprof/profile/encode.go delete mode 100644 plugins/traefik/vendor/github.com/google/pprof/profile/filter.go delete mode 100644 plugins/traefik/vendor/github.com/google/pprof/profile/index.go delete mode 100644 plugins/traefik/vendor/github.com/google/pprof/profile/legacy_java_profile.go delete mode 100644 plugins/traefik/vendor/github.com/google/pprof/profile/legacy_profile.go delete mode 100644 plugins/traefik/vendor/github.com/google/pprof/profile/merge.go delete mode 100644 plugins/traefik/vendor/github.com/google/pprof/profile/profile.go delete mode 100644 plugins/traefik/vendor/github.com/google/pprof/profile/proto.go delete mode 100644 plugins/traefik/vendor/github.com/google/pprof/profile/prune.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/.gitignore create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/CODE_OF_CONDUCT.md create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/CONTRIBUTING.md create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/LICENSE.md create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/README.md create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/fallback/s2a_fallback.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/authinfo/authinfo.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/handshaker/handshaker.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/handshaker/service/service.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/proto/common_go_proto/common.pb.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/proto/s2a_context_go_proto/s2a_context.pb.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a.pb.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a_grpc.pb.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/proto/v2/common_go_proto/common.pb.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto/s2a_context.pb.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a.pb.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a_grpc.pb.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aeadcrypter.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aesgcm.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/chachapoly.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/common.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/ciphersuite.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/counter.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/expander.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/record/internal/halfconn/halfconn.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/record/record.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/record/ticketsender.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/tokenmanager/tokenmanager.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/v2/README.md create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/v2/certverifier/certverifier.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/v2/remotesigner/remotesigner.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/v2/s2av2.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/tlsconfigstore.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/retry/retry.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/s2a.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/s2a_options.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/s2a_utils.go create mode 100644 plugins/traefik/vendor/github.com/google/s2a-go/stream/s2a_stream.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/enterprise-certificate-proxy/LICENSE create mode 100644 plugins/traefik/vendor/github.com/googleapis/enterprise-certificate-proxy/client/client.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/enterprise-certificate-proxy/client/util/util.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/CHANGES.md create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/LICENSE create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/README.md create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/custom_error.pb.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/custom_error.proto create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/error.pb.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/error.proto create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/call_option.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/callctx/callctx.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/content_type.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/feature.go rename plugins/traefik/vendor/github.com/{jackc/pgx/v4/go_stdlib.go => googleapis/gax-go/v2/gax.go} (51%) create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/header.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/internal/version.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/internallog/internal/internal.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/internallog/internallog.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/invoke.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/proto_json_stream.go create mode 100644 plugins/traefik/vendor/github.com/googleapis/gax-go/v2/release-please-config.json create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/LICENSE create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/BUILD.bazel create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/compile.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/fuzz.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/parse.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/types.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/BUILD.bazel create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/context.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/convert.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/doc.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/errors.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/fieldmask.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_httpbodyproto.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_json.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_proto.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler_registry.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/proto2_convert.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/query.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/BUILD.bazel create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/doc.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/pattern.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/readerfactory.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/string_array_flag.go create mode 100644 plugins/traefik/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/trie.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/chunkreader/v2/.travis.yml delete mode 100644 plugins/traefik/vendor/github.com/jackc/chunkreader/v2/LICENSE delete mode 100644 plugins/traefik/vendor/github.com/jackc/chunkreader/v2/README.md delete mode 100644 plugins/traefik/vendor/github.com/jackc/chunkreader/v2/chunkreader.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgconn/.gitignore delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgconn/CHANGELOG.md delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgconn/LICENSE delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgconn/README.md delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgconn/doc.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgconn/errors.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgconn/pgconn.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgconn/stmtcache/lru.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgconn/stmtcache/stmtcache.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgio/.travis.yml delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgio/README.md delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgproto3/v2/.travis.yml delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgproto3/v2/LICENSE delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgproto3/v2/README.md delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgproto3/v2/chunkreader.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgproto3/v2/doc.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgproto3/v2/frontend.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgservicefile/.travis.yml delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/CHANGELOG.md delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/README.md delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/aclitem.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/aclitem_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/array_type.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/bit.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/bool.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/bool_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/box.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/bpchar.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/bpchar_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/bytea.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/bytea_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/cid.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/cidr.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/cidr_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/circle.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/composite_fields.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/composite_type.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/convert.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/database_sql.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/date.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/date_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/daterange.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/enum_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/enum_type.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/float4.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/float4_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/float8.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/float8_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/generic_binary.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/generic_text.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/hstore.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/hstore_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/inet.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/inet_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/int2.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/int2_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/int4.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/int4_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/int4_multirange.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/int4range.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/int8.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/int8_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/int8_multirange.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/int8range.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/interval.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/json.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/json_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/jsonb.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/jsonb_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/line.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/lseg.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/ltree.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/macaddr.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/macaddr_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/multirange.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/name.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/num_multirange.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/numeric.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/numeric_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/numrange.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/oid.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/oid_value.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/path.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/pgtype.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/pguint32.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/point.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/polygon.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/qchar.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/record.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/record_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/text.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/text_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/tid.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/time.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/timestamp.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/timestamp_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/timestamptz.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/timestamptz_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/tsrange.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/tsrange_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/tstzrange.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/tstzrange_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/typed_array.go.erb delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/typed_array_gen.sh delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/typed_multirange.go.erb delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/typed_multirange_gen.sh delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/typed_range.go.erb delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/typed_range_gen.sh delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/unknown.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/uuid.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/uuid_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/varbit.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/varchar.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/varchar_array.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgtype/xid.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/CHANGELOG.md delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/LICENSE delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/README.md delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/batch.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/conn.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/copy_from.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/doc.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/extended_query_builder.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/internal/sanitize/sanitize.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/logger.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/messages.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/rows.go delete mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v4/values.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/.gitignore create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/.golangci.yml create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/CHANGELOG.md create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/CLAUDE.md create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/CONTRIBUTING.md rename plugins/traefik/vendor/github.com/jackc/{pgtype => pgx/v5}/LICENSE (100%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/README.md create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/Rakefile create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/batch.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/conn.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/copy_from.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/derived_types.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/doc.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/extended_query_builder.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/internal/iobufpool/iobufpool.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/internal/pgio/README.md rename plugins/traefik/vendor/github.com/jackc/{ => pgx/v5/internal}/pgio/doc.go (100%) rename plugins/traefik/vendor/github.com/jackc/{ => pgx/v5/internal}/pgio/write.go (55%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/internal/sanitize/benchmark.sh create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/internal/sanitize/sanitize.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/internal/stmtcache/lru_cache.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/internal/stmtcache/stmtcache.go rename plugins/traefik/vendor/github.com/jackc/pgx/{v4 => v5}/large_objects.go (63%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/named_args.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgconn/README.md create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgconn/auth_oauth.go rename plugins/traefik/vendor/github.com/jackc/{ => pgx/v5}/pgconn/auth_scram.go (50%) rename plugins/traefik/vendor/github.com/jackc/{ => pgx/v5}/pgconn/config.go (66%) rename plugins/traefik/vendor/github.com/jackc/{pgconn/internal => pgx/v5/pgconn}/ctxwatch/context_watcher.go (51%) rename plugins/traefik/vendor/github.com/jackc/{ => pgx/v5}/pgconn/defaults.go (97%) rename plugins/traefik/vendor/github.com/jackc/{ => pgx/v5}/pgconn/defaults_windows.go (97%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgconn/doc.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgconn/errors.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgconn/internal/bgreader/bgreader.go rename plugins/traefik/vendor/github.com/jackc/{ => pgx/v5}/pgconn/krb5.go (91%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgconn/pgconn.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgproto3/README.md rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/authentication_cleartext_password.go (94%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/authentication_gss.go (96%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/authentication_gss_continue.go (96%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/authentication_md5_password.go (97%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/authentication_ok.go (94%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/authentication_sasl.go (84%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/authentication_sasl_continue.go (97%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/authentication_sasl_final.go (97%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/backend.go (60%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/backend_key_data.go (63%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/big_endian.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/bind.go (96%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/bind_complete.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/cancel_request.go (51%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader.go rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/close.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/close_complete.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/command_complete.go (90%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/copy_both_response.go (97%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/copy_data.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/copy_done.go (97%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/copy_fail.go (93%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/copy_in_response.go (97%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/copy_out_response.go (97%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/data_row.go (90%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/describe.go (100%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgproto3/doc.go rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/empty_query_response.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/error_response.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/execute.go (97%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/flush.go (100%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgproto3/frontend.go rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/function_call.go (81%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/function_call_response.go (93%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/gss_enc_request.go (93%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/gss_response.go (100%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgproto3/negotiate_protocol_version.go rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/no_data.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/notice_response.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/notification_response.go (90%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/parameter_description.go (95%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/parameter_status.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/parse.go (96%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/parse_complete.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/password_message.go (94%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/pgproto3.go (73%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/portal_suspended.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/query.go (93%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/ready_for_query.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/row_description.go (98%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/sasl_initial_response.go (88%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/sasl_response.go (89%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/ssl_request.go (93%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/startup_message.go (77%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/sync.go (100%) rename plugins/traefik/vendor/github.com/jackc/{pgproto3/v2 => pgx/v5/pgproto3}/terminate.go (100%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgproto3/trace.go rename plugins/traefik/vendor/github.com/jackc/{ => pgx/v5}/pgtype/array.go (61%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/array_codec.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/bits.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/bool.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/box.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/builtin_wrappers.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/bytea.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/circle.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/composite.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/convert.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/date.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/doc.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/enum_codec.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/float4.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/float8.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/hstore.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/inet.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/int.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/int.go.erb create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/int_test.go.erb create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/integration_benchmark_test.go.erb create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/integration_benchmark_test_gen.sh create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/interval.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/json.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/jsonb.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/line.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/lseg.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/ltree.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/macaddr.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/multirange.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/numeric.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/path.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/pgtype.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/pgtype_default.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/point.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/polygon.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/qchar.go rename plugins/traefik/vendor/github.com/jackc/{ => pgx/v5}/pgtype/range.go (74%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/range_codec.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/record_codec.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/register_default_pg_types.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/register_default_pg_types_disabled.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/text.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/text_format_only_codec.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/tid.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/time.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/timestamp.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/timestamptz.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/tsvector.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/uint32.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/uint64.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/uuid.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgtype/xml.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgxpool/batch_results.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgxpool/conn.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgxpool/doc.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgxpool/pool.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgxpool/rows.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgxpool/stat.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgxpool/tracer.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/pgxpool/tx.go create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/rows.go rename plugins/traefik/vendor/github.com/jackc/pgx/{v4 => v5}/stdlib/sql.go (64%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/test.sh create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/tracer.go rename plugins/traefik/vendor/github.com/jackc/pgx/{v4 => v5}/tx.go (68%) create mode 100644 plugins/traefik/vendor/github.com/jackc/pgx/v5/values.go create mode 100644 plugins/traefik/vendor/github.com/jackc/puddle/v2/CHANGELOG.md rename plugins/traefik/vendor/github.com/jackc/{pgio => puddle/v2}/LICENSE (96%) create mode 100644 plugins/traefik/vendor/github.com/jackc/puddle/v2/README.md create mode 100644 plugins/traefik/vendor/github.com/jackc/puddle/v2/context.go create mode 100644 plugins/traefik/vendor/github.com/jackc/puddle/v2/doc.go create mode 100644 plugins/traefik/vendor/github.com/jackc/puddle/v2/internal/genstack/gen_stack.go create mode 100644 plugins/traefik/vendor/github.com/jackc/puddle/v2/internal/genstack/stack.go create mode 100644 plugins/traefik/vendor/github.com/jackc/puddle/v2/log.go create mode 100644 plugins/traefik/vendor/github.com/jackc/puddle/v2/nanotime.go create mode 100644 plugins/traefik/vendor/github.com/jackc/puddle/v2/pool.go create mode 100644 plugins/traefik/vendor/github.com/jackc/puddle/v2/resource_list.go create mode 100644 plugins/traefik/vendor/github.com/klauspost/compress/zstd/simple_go124.go delete mode 100644 plugins/traefik/vendor/github.com/mattn/go-colorable/colorable_appengine.go rename plugins/traefik/vendor/github.com/miekg/dns/{udp_windows.go => udp_no_control.go} (85%) delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/LICENSE delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/config/deprecated.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/formatter/colorable_others.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/formatter/colorable_windows.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/abort.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/boostrap_templates.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/bootstrap_command.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generate_command.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generate_templates.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generators_common.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/compile.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/profiles_and_reports.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/test_suite.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/utils.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/verify_version.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/labels/labels_command.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/import.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline_command.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/unfocus/unfocus_command.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/delta.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/delta_tracker.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/dependencies.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/package_hash.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/package_hashes.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/suite.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/sigquit_swallower_unix.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/sigquit_swallower_windows.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_server.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/reporters/json_report.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/types/code_location.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/types/config.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/types/deprecated_types.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/types/enum_support.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/types/errors.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/types/file_filter.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/types/flags.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/types/label_filter.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/types/types.go delete mode 100644 plugins/traefik/vendor/github.com/onsi/ginkgo/v2/types/version.go rename plugins/traefik/vendor/github.com/{go-kit/log => prometheus/otlptranslator}/.gitignore (53%) create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/.golangci.yml create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/CODE_OF_CONDUCT.md rename plugins/traefik/vendor/{go.step.sm/linkedca => github.com/prometheus/otlptranslator}/LICENSE (100%) create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/MAINTAINERS.md create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/README.md create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/SECURITY.md create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/constants.go create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/doc.go create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/label_namer.go create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/metric_namer.go create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/metric_type.go create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/strategy.go create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/strconv.go create mode 100644 plugins/traefik/vendor/github.com/prometheus/otlptranslator/unit_namer.go create mode 100644 plugins/traefik/vendor/github.com/prometheus/procfs/kernel_hung.go create mode 100644 plugins/traefik/vendor/github.com/prometheus/procfs/net_dev_snmp6.go create mode 100644 plugins/traefik/vendor/github.com/prometheus/procfs/nfnetlink_queue.go create mode 100644 plugins/traefik/vendor/github.com/prometheus/procfs/proc_statm.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/Changelog.md delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/connection_timer.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/http3/datagram.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/http3/http_stream.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/http3/qlog.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/http3/qlog/event.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/http3/qlog/frame.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/http3/qlog/qlog_dir.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/http3/server_conn.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/http3/stream.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/internal/ackhandler/ackhandler.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/internal/ackhandler/lost_packet_tracker.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/internal/monotime/time.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/internal/utils/connstats.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/internal/utils/timer.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/internal/wire/ack_frequency_frame.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/internal/wire/frame_type.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/internal/wire/immediate_ack_frame.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/logging/connection_tracer.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/logging/connection_tracer_multiplexer.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/logging/frame.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/logging/generate_multiplexer.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/logging/interface.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/logging/multiplexer.tmpl delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/logging/packet_header.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/logging/tracer.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/logging/tracer_multiplexer.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/logging/types.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/packet_handler_map.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/path_manager_outgoing.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/qlog/connection_tracer.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/qlog/trace.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/qlog/tracer.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/qlog/writer.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/qlogwriter/jsontext/encoder.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/qlogwriter/trace.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/qlogwriter/writer.go create mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/sni.go delete mode 100644 plugins/traefik/vendor/github.com/quic-go/quic-go/tools.go create mode 100644 plugins/traefik/vendor/github.com/rs/xid/.gitignore create mode 100644 plugins/traefik/vendor/github.com/slackhq/nebula/cert/asn1.go delete mode 100644 plugins/traefik/vendor/github.com/slackhq/nebula/cert/ca.go create mode 100644 plugins/traefik/vendor/github.com/slackhq/nebula/cert/ca_pool.go delete mode 100644 plugins/traefik/vendor/github.com/slackhq/nebula/cert/cert.pb.go create mode 100644 plugins/traefik/vendor/github.com/slackhq/nebula/cert/cert_v1.go create mode 100644 plugins/traefik/vendor/github.com/slackhq/nebula/cert/cert_v1.pb.go rename plugins/traefik/vendor/github.com/slackhq/nebula/cert/{cert.proto => cert_v1.proto} (58%) create mode 100644 plugins/traefik/vendor/github.com/slackhq/nebula/cert/cert_v2.asn1 create mode 100644 plugins/traefik/vendor/github.com/slackhq/nebula/cert/cert_v2.go create mode 100644 plugins/traefik/vendor/github.com/slackhq/nebula/cert/crypto.go create mode 100644 plugins/traefik/vendor/github.com/slackhq/nebula/cert/p256/p256.go create mode 100644 plugins/traefik/vendor/github.com/slackhq/nebula/cert/pem.go create mode 100644 plugins/traefik/vendor/github.com/slackhq/nebula/cert/sign.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/certificates/acme/wire/id.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/certificates/authority/http_client.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/certificates/authority/poolhttp/poolhttp.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/certificates/authority/provisioner/gcp/projectvalidator.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/certificates/authority/provisioner/wire/dpop_options.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/certificates/authority/provisioner/wire/oidc_options.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/certificates/authority/provisioner/wire/wire_options.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/certificates/internal/cast/cast.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/certificates/internal/httptransport/httptransport.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/cli-utils/LICENSE rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/command/command.go (91%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/errs/errs.go (98%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/fileutil/file.go (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/fileutil/write.go (98%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/pkg/blackfriday/LICENSE.txt (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/pkg/blackfriday/README.md (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/pkg/blackfriday/block.go (99%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/pkg/blackfriday/doc.go (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/pkg/blackfriday/esc.go (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/pkg/blackfriday/html.go (99%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/pkg/blackfriday/inline.go (99%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/pkg/blackfriday/markdown.go (99%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/pkg/blackfriday/node.go (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/pkg/blackfriday/smartypants.go (99%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/step/config.go (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/step/context.go (99%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/ui/options.go (90%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/ui/templates.go (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/ui/ui.go (91%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/ui/ui_other.go (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/ui/ui_windows.go (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/ui/validators.go (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/usage/css.go (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/usage/help.go (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/usage/html.go (99%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/usage/printer.go (99%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/usage/renderer.go (95%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/usage/report.go (97%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/cli-utils/usage/usage.go (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/linkedca/.gitignore (100%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/linkedca/CODEOWNERS (100%) create mode 100644 plugins/traefik/vendor/github.com/smallstep/linkedca/LICENSE rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/linkedca/Makefile (65%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/linkedca/README.md (100%) create mode 100644 plugins/traefik/vendor/github.com/smallstep/linkedca/acme.pb.go rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/linkedca/admin.pb.go (60%) create mode 100644 plugins/traefik/vendor/github.com/smallstep/linkedca/config.pb.go rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/linkedca/context.go (100%) create mode 100644 plugins/traefik/vendor/github.com/smallstep/linkedca/eab.pb.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/linkedca/majordomo.pb.go rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/linkedca/majordomo_grpc.pb.go (73%) rename plugins/traefik/vendor/{go.step.sm => github.com/smallstep}/linkedca/policy.go (100%) create mode 100644 plugins/traefik/vendor/github.com/smallstep/linkedca/policy.pb.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/linkedca/provisioners.pb.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/linkedca/tools.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/debug.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/doc.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/oid.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/parser.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/pkcs1.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/verify.go create mode 100644 plugins/traefik/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/x509.go delete mode 100644 plugins/traefik/vendor/github.com/smallstep/pkcs7/verify_test_dsa.go create mode 100644 plugins/traefik/vendor/github.com/spf13/cobra/SECURITY.md create mode 100644 plugins/traefik/vendor/github.com/spf13/pflag/bool_func.go create mode 100644 plugins/traefik/vendor/github.com/spf13/pflag/errors.go create mode 100644 plugins/traefik/vendor/github.com/spf13/pflag/func.go create mode 100644 plugins/traefik/vendor/github.com/spf13/pflag/text.go create mode 100644 plugins/traefik/vendor/github.com/spf13/pflag/time.go delete mode 100644 plugins/traefik/vendor/github.com/stoewer/go-strcase/.gitignore delete mode 100644 plugins/traefik/vendor/github.com/stoewer/go-strcase/.golangci.yml delete mode 100644 plugins/traefik/vendor/github.com/stoewer/go-strcase/LICENSE delete mode 100644 plugins/traefik/vendor/github.com/stoewer/go-strcase/README.md delete mode 100644 plugins/traefik/vendor/github.com/stoewer/go-strcase/camel.go delete mode 100644 plugins/traefik/vendor/github.com/stoewer/go-strcase/doc.go delete mode 100644 plugins/traefik/vendor/github.com/stoewer/go-strcase/helper.go delete mode 100644 plugins/traefik/vendor/github.com/stoewer/go-strcase/kebab.go delete mode 100644 plugins/traefik/vendor/github.com/stoewer/go-strcase/snake.go rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/.gitattributes (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/.gitignore (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/.golangci.yml (85%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/CODEOWNERS (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/LICENSE (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/README.md (94%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/SECURITY.md (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/backup.go (91%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/doc.go (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/ea.go (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/file.go (84%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/fileinfo.go (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/hvsock.go (92%) create mode 100644 plugins/traefik/vendor/github.com/tailscale/go-winio/internal/fs/doc.go create mode 100644 plugins/traefik/vendor/github.com/tailscale/go-winio/internal/fs/fs.go create mode 100644 plugins/traefik/vendor/github.com/tailscale/go-winio/internal/fs/security.go create mode 100644 plugins/traefik/vendor/github.com/tailscale/go-winio/internal/fs/zsyscall_windows.go rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/internal/socket/rawaddr.go (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/internal/socket/socket.go (96%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/internal/socket/zsyscall_windows.go (96%) create mode 100644 plugins/traefik/vendor/github.com/tailscale/go-winio/internal/stringbuffer/wstring.go rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/pipe.go (73%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/pkg/guid/guid.go (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/pkg/guid/guid_nonwindows.go (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/pkg/guid/guid_windows.go (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/pkg/guid/variant_string.go (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/privilege.go (94%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/reparse.go (100%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/sd.go (71%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/syscall.go (54%) rename plugins/traefik/vendor/github.com/{Microsoft => tailscale}/go-winio/zsyscall_windows.go (60%) create mode 100644 plugins/traefik/vendor/github.com/tailscale/tscert/internal/safesocket/zsyscall_windows.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/.go-version create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/OWNERS delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_386.go rename plugins/traefik/vendor/go.etcd.io/bbolt/{bolt_unix_solaris.go => bolt_aix.go} (94%) delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_amd64.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_android.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_arm.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_arm64.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_loong64.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_mips64x.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_mipsx.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_ppc.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_ppc64.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_ppc64le.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_riscv64.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/bolt_s390x.go rename plugins/traefik/vendor/go.etcd.io/bbolt/{bolt_unix_aix.go => bolt_solaris.go} (95%) create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/errors/errors.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/freelist.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/freelist_hmap.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bolt_386.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bolt_amd64.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bolt_arm.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bolt_arm64.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bolt_loong64.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bolt_mips64x.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bolt_mipsx.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bolt_ppc.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bolt_ppc64.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bolt_ppc64le.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bolt_riscv64.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bolt_s390x.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/bucket.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/inode.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/meta.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/page.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/types.go rename plugins/traefik/vendor/go.etcd.io/bbolt/{ => internal/common}/unsafe.go (53%) create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/utils.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/common/verify.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/freelist/array.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/freelist/freelist.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/freelist/hashmap.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/internal/freelist/shared.go create mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/logger.go delete mode 100644 plugins/traefik/vendor/go.etcd.io/bbolt/page.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/CONTRIBUTING.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/VERSIONING.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/attr.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/id.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/number.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/resource.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/scope.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/span.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/status.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/traces.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/value.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/limit.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/span.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/tracer.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/auto/sdk/tracer_provider.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/bridges/prometheus/BENCHMARKS.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/bridges/prometheus/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/bridges/prometheus/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/bridges/prometheus/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/bridges/prometheus/producer.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/bridges/prometheus/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/exporters/autoexport/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/exporters/autoexport/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/exporters/autoexport/logs.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/exporters/autoexport/metrics.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/exporters/autoexport/noop.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/exporters/autoexport/registry.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/exporters/autoexport/signal.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/exporters/autoexport/spans.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/start_time_context.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/.clomonitor.yml create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/.codespellignore create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/.codespellrc create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/.gitattributes create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/.gitignore create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/.golangci.yml create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/.lycheeignore create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/.markdownlint.yaml create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/CHANGELOG.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/CODEOWNERS create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/Makefile create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/RELEASING.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/SECURITY-INSIGHTS.yml create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/VERSIONING.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/encoder.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/filter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/hash.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/internal/xxhash/xxhash.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/iterator.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/key.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/kv.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/rawhelpers.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/set.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/type_string.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/attribute/value.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/baggage/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/baggage/baggage.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/baggage/context.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/baggage/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/codes/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/codes/codes.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/codes/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/error_handler.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/client.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/gen.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/observ/instrumentation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/observ/target.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/partialsuccess.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/retry/retry.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/transform/log.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/x/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/x/features.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/internal/x/x.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/client.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/internal/gen.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/internal/observ/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/internal/observ/instrumentation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/internal/partialsuccess.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/internal/retry/retry.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/internal/transform/log.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/internal/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/internal/x/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/internal/x/observ.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/internal/x/x.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/client.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/envconfig/envconfig.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/gen.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/envconfig.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/options.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/optiontypes.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/tls.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/partialsuccess.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/retry/retry.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/error.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/metricdata.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/client.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/envconfig/envconfig.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/gen.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/envconfig.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/options.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/optiontypes.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/tls.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/partialsuccess.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/retry/retry.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/error.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/metricdata.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/clients.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/attribute.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/instrumentation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/resource.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/counter/counter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig/envconfig.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/gen.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/instrumentation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/target.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/envconfig.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/options.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/optiontypes.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/tls.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/partialsuccess.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry/retry.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x/observ.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x/x.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/options.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/client.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/counter/counter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/envconfig/envconfig.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/gen.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/observ/instrumentation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/envconfig.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/options.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/optiontypes.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/tls.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/partialsuccess.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/retry/retry.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/x/observ.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/x/x.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/options.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/errors.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/counter/counter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/gen.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/observ/instrumentation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/features.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/x.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutlog/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutlog/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutlog/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutlog/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutlog/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutlog/record.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/encoder.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/internal/counter/counter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/internal/gen.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/internal/observ/instrumentation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/internal/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/internal/x/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/internal/x/features.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/internal/x/x.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdouttrace/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdouttrace/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdouttrace/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdouttrace/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdouttrace/internal/counter/counter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdouttrace/internal/gen.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdouttrace/internal/observ/instrumentation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdouttrace/internal/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdouttrace/internal/x/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdouttrace/internal/x/features.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdouttrace/internal/x/x.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/exporters/stdout/stdouttrace/trace.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/handler.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/internal/baggage/context.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/internal/errorhandler/errorhandler.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/internal/global/handler.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/internal/global/instruments.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/internal/global/meter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/internal/global/propagator.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/internal/global/state.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/internal/global/trace.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/internal_logging.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/DESIGN.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/embedded/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/embedded/embedded.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/keyvalue.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/kind_string.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/logger.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/noop/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/noop/noop.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/provider.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/record.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/severity.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/log/severity_string.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/asyncint64.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/embedded/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/instrument.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/meter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/noop/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/noop/noop.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/metric/syncint64.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/propagation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/propagation/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/propagation/baggage.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/propagation/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/propagation/propagation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/propagation/trace_context.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/renovate.json create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/requirements.txt create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/instrumentation/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/instrumentation/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/instrumentation/scope.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/internal/x/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/internal/x/features.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/internal/x/x.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/DESIGN.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/batch.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/instrumentation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/internal/observ/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/internal/observ/simple_log_processor.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/internal/x/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/internal/x/features.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/internal/x/x.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/logger.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/processor.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/provider.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/record.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/ring.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/setting.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/log/simple.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/aggregation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/cache.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/env.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/exemplar.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/filter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/fixed_size_reservoir.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/histogram_reservoir.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/reservoir.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/storage.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/value.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/instrument.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/instrumentkind_string.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/aggregate.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/atomic.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/drop.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/exemplar.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/exponential_histogram.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/filtered_reservoir.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/histogram.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/lastvalue.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/limit.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/sum.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/observ/instrumentation.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/concurrent_safe.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reuse_slice.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/manual_reader.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/meter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/data.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/temporality.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/temporality_string.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/periodic_reader.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/pipeline.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/provider.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/reader.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/metric/view.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/container.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/env.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_bsd.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_darwin.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_exec.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_linux.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_unsupported.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_windows.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/os.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_darwin.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_unix.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/os_unix.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/os_unsupported.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/os_windows.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/process.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/event.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/evictedqueue.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/id_generator.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/internal/env/env.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/batch_span_processor.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/simple_span_processor.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/tracer.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/link.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/sampler_env.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/snapshot.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/span.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/span_limits.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/exporter.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/recorder.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/span.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/sdk/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.26.0/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.26.0/attribute_group.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.26.0/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.26.0/exception.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.26.0/metric.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.26.0/schema.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/MIGRATION.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/error_type.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/exception.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/schema.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/MIGRATION.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/attribute_group.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/error_type.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/exception.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/httpconv/metric.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/schema.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/MIGRATION.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/attribute_group.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/error_type.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/exception.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/otelconv/metric.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/schema.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/auto.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/config.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/context.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/embedded/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/hex.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/attr.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/doc.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/id.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/number.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/resource.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/scope.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/status.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/traces.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/value.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/nonrecording.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/noop.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/noop/README.md create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/noop/noop.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/provider.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/span.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/trace.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/tracer.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/trace/tracestate.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/verify_released_changelog.sh create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/version.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/otel/versions.yaml create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/LICENSE create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/collector/logs/v1/logs_service.pb.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/collector/logs/v1/logs_service.pb.gw.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/collector/logs/v1/logs_service_grpc.pb.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/collector/metrics/v1/metrics_service.pb.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/collector/metrics/v1/metrics_service.pb.gw.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/collector/metrics/v1/metrics_service_grpc.pb.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service.pb.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service.pb.gw.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service_grpc.pb.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/common/v1/common.pb.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/logs/v1/logs.pb.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/metrics/v1/metrics.pb.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/resource/v1/resource.pb.go create mode 100644 plugins/traefik/vendor/go.opentelemetry.io/proto/otlp/trace/v1/trace.pb.go create mode 100644 plugins/traefik/vendor/go.step.sm/crypto/fipsutil/fipsutil.go create mode 100644 plugins/traefik/vendor/go.step.sm/crypto/fipsutil/fipsutil_other.go create mode 100644 plugins/traefik/vendor/go.step.sm/crypto/internal/termutil/termutil.go create mode 100644 plugins/traefik/vendor/go.step.sm/crypto/internal/utils/asn1/asn1.go create mode 100644 plugins/traefik/vendor/go.step.sm/crypto/internal/utils/convert/convert.go rename plugins/traefik/vendor/go.step.sm/crypto/internal/utils/{ => file}/io.go (99%) delete mode 100644 plugins/traefik/vendor/go.step.sm/linkedca/config.pb.go delete mode 100644 plugins/traefik/vendor/go.step.sm/linkedca/eab.pb.go delete mode 100644 plugins/traefik/vendor/go.step.sm/linkedca/majordomo.pb.go delete mode 100644 plugins/traefik/vendor/go.step.sm/linkedca/policy.pb.go delete mode 100644 plugins/traefik/vendor/go.step.sm/linkedca/provisioners.pb.go delete mode 100644 plugins/traefik/vendor/go.uber.org/mock/mockgen/deprecated.go delete mode 100644 plugins/traefik/vendor/go.uber.org/mock/mockgen/generic.go delete mode 100644 plugins/traefik/vendor/go.uber.org/mock/mockgen/gob.go delete mode 100644 plugins/traefik/vendor/go.uber.org/mock/mockgen/mockgen.go delete mode 100644 plugins/traefik/vendor/go.uber.org/mock/mockgen/model/model.go delete mode 100644 plugins/traefik/vendor/go.uber.org/mock/mockgen/package_mode.go delete mode 100644 plugins/traefik/vendor/go.uber.org/mock/mockgen/parse.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/.travis.yml create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/LICENSE rename plugins/traefik/vendor/{github.com/go-kit/kit/LICENSE => go.yaml.in/yaml/v2/LICENSE.libyaml} (50%) create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/NOTICE create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/README.md create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/apic.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/decode.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/emitterc.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/encode.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/parserc.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/readerc.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/resolve.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/scannerc.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/sorter.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/writerc.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/yaml.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/yamlh.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v2/yamlprivateh.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/LICENSE create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/NOTICE create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/README.md create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/apic.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/decode.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/emitterc.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/encode.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/parserc.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/readerc.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/resolve.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/scannerc.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/sorter.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/writerc.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/yaml.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/yamlh.go create mode 100644 plugins/traefik/vendor/go.yaml.in/yaml/v3/yamlprivateh.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/argon2/argon2.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/argon2/blake2b.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/argon2/blamka_amd64.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/argon2/blamka_amd64.s create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/argon2/blamka_generic.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/argon2/blamka_ref.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/blake2b/blake2b.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go rename plugins/traefik/vendor/golang.org/x/{text/secure/bidirule/bidirule10.0.0.go => crypto/blake2b/blake2b_ref.go} (50%) create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/blake2b/blake2x.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/blake2b/go125.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/blake2b/register.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/chacha20poly1305/fips140only_compat.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/chacha20poly1305/fips140only_go1.26.go rename plugins/traefik/vendor/golang.org/x/crypto/internal/poly1305/{sum_amd64.go => sum_asm.go} (94%) create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.s delete mode 100644 plugins/traefik/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64x.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/ssh/mlkem.go delete mode 100644 plugins/traefik/vendor/golang.org/x/crypto/x509roots/fallback/bundle.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/x509roots/fallback/bundle/bundle.der create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/x509roots/fallback/bundle/bundle.go create mode 100644 plugins/traefik/vendor/golang.org/x/crypto/x509roots/fallback/bundle/roots.go delete mode 100644 plugins/traefik/vendor/golang.org/x/exp/constraints/constraints.go delete mode 100644 plugins/traefik/vendor/golang.org/x/exp/rand/exp.go delete mode 100644 plugins/traefik/vendor/golang.org/x/exp/rand/normal.go delete mode 100644 plugins/traefik/vendor/golang.org/x/exp/rand/rand.go delete mode 100644 plugins/traefik/vendor/golang.org/x/exp/rand/rng.go delete mode 100644 plugins/traefik/vendor/golang.org/x/exp/rand/zipf.go delete mode 100644 plugins/traefik/vendor/golang.org/x/exp/slices/cmp.go delete mode 100644 plugins/traefik/vendor/golang.org/x/exp/slices/zsortanyfunc.go delete mode 100644 plugins/traefik/vendor/golang.org/x/exp/slices/zsortordered.go delete mode 100644 plugins/traefik/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go delete mode 100644 plugins/traefik/vendor/golang.org/x/mod/modfile/print.go delete mode 100644 plugins/traefik/vendor/golang.org/x/mod/modfile/read.go delete mode 100644 plugins/traefik/vendor/golang.org/x/mod/modfile/rule.go delete mode 100644 plugins/traefik/vendor/golang.org/x/mod/modfile/work.go delete mode 100644 plugins/traefik/vendor/golang.org/x/mod/module/module.go delete mode 100644 plugins/traefik/vendor/golang.org/x/mod/module/pseudo.go create mode 100644 plugins/traefik/vendor/golang.org/x/net/html/nodetype_string.go create mode 100644 plugins/traefik/vendor/golang.org/x/net/http2/client_priority_go126.go create mode 100644 plugins/traefik/vendor/golang.org/x/net/http2/client_priority_go127.go delete mode 100644 plugins/traefik/vendor/golang.org/x/net/http2/config_go124.go create mode 100644 plugins/traefik/vendor/golang.org/x/net/http2/config_go125.go create mode 100644 plugins/traefik/vendor/golang.org/x/net/http2/config_go126.go delete mode 100644 plugins/traefik/vendor/golang.org/x/net/http2/config_pre_go124.go delete mode 100644 plugins/traefik/vendor/golang.org/x/net/http2/h2c/h2c.go delete mode 100644 plugins/traefik/vendor/golang.org/x/net/http2/timer.go rename plugins/traefik/vendor/golang.org/x/net/http2/{writesched_priority.go => writesched_priority_rfc7540.go} (75%) create mode 100644 plugins/traefik/vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go create mode 100644 plugins/traefik/vendor/golang.org/x/net/internal/httpsfv/httpsfv.go delete mode 100644 plugins/traefik/vendor/golang.org/x/net/internal/socket/sys.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/.travis.yml create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/CONTRIBUTING.md create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/LICENSE create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/README.md create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/authhandler/authhandler.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/deviceauth.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/appengine.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/default.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/doc.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/error.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/externalaccount/aws.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/externalaccount/basecredentials.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/externalaccount/executablecredsource.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/externalaccount/filecredsource.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/externalaccount/header.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/externalaccount/programmaticrefreshcredsource.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/externalaccount/urlcredsource.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/google.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/internal/externalaccountauthorizeduser/externalaccountauthorizeduser.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/internal/impersonate/impersonate.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/internal/stsexchange/clientauth.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/internal/stsexchange/sts_exchange.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/jwt.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/google/sdk.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/internal/doc.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/internal/oauth2.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/internal/token.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/internal/transport.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/jws/jws.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/jwt/jwt.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/oauth2.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/pkce.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/token.go create mode 100644 plugins/traefik/vendor/golang.org/x/oauth2/transport.go create mode 100644 plugins/traefik/vendor/golang.org/x/sync/semaphore/semaphore.go create mode 100644 plugins/traefik/vendor/golang.org/x/sys/cpu/asm_darwin_arm64_gc.s create mode 100644 plugins/traefik/vendor/golang.org/x/sys/cpu/cpu_darwin_arm64.go create mode 100644 plugins/traefik/vendor/golang.org/x/sys/cpu/cpu_darwin_arm64_other.go create mode 100644 plugins/traefik/vendor/golang.org/x/sys/cpu/cpu_linux_loong64.go create mode 100644 plugins/traefik/vendor/golang.org/x/sys/cpu/cpu_loong64.s create mode 100644 plugins/traefik/vendor/golang.org/x/sys/cpu/syscall_darwin_arm64_gc.go delete mode 100644 plugins/traefik/vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go create mode 100644 plugins/traefik/vendor/golang.org/x/sys/windows/registry/key.go create mode 100644 plugins/traefik/vendor/golang.org/x/sys/windows/registry/mksyscall.go create mode 100644 plugins/traefik/vendor/golang.org/x/sys/windows/registry/syscall.go create mode 100644 plugins/traefik/vendor/golang.org/x/sys/windows/registry/value.go create mode 100644 plugins/traefik/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/cases/tables10.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/cases/tables11.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/cases/tables12.0.0.go rename plugins/traefik/vendor/golang.org/x/text/cases/{tables13.0.0.go => tables17.0.0.go} (60%) delete mode 100644 plugins/traefik/vendor/golang.org/x/text/cases/tables9.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/message/catalog/go19.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/message/catalog/gopre19.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/secure/bidirule/bidirule9.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/secure/precis/tables10.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/secure/precis/tables11.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/secure/precis/tables12.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/secure/precis/tables13.0.0.go create mode 100644 plugins/traefik/vendor/golang.org/x/text/secure/precis/tables17.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/secure/precis/tables9.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/unicode/bidi/tables12.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go create mode 100644 plugins/traefik/vendor/golang.org/x/text/unicode/bidi/tables17.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/unicode/norm/tables11.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/unicode/norm/tables12.0.0.go rename plugins/traefik/vendor/golang.org/x/text/unicode/norm/{tables13.0.0.go => tables17.0.0.go} (53%) delete mode 100644 plugins/traefik/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/width/tables10.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/width/tables11.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/text/width/tables12.0.0.go rename plugins/traefik/vendor/golang.org/x/text/width/{tables13.0.0.go => tables17.0.0.go} (74%) delete mode 100644 plugins/traefik/vendor/golang.org/x/text/width/tables9.0.0.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/cmd/stringer/stringer.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/go/ast/astutil/imports.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/go/ast/astutil/util.go rename plugins/traefik/vendor/golang.org/x/tools/{internal/astutil => go/ast}/edge/edge.go (100%) create mode 100644 plugins/traefik/vendor/golang.org/x/tools/go/ast/inspector/cursor.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/imports/forward.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go rename plugins/traefik/vendor/golang.org/x/tools/internal/gcimporter/{ureader_yes.go => ureader.go} (88%) delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/gopathwalk/walk.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/imports/fix.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/imports/imports.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/imports/mod.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/imports/mod_cache.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/imports/sortimports.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/imports/source.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/imports/source_env.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/imports/source_modindex.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/modindex/directories.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/modindex/index.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/modindex/lookup.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/modindex/modindex.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/modindex/symbols.go delete mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/modindex/types.go create mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go create mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/typesinternal/fx.go create mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go create mode 100644 plugins/traefik/vendor/golang.org/x/tools/internal/typesinternal/varkind_go124.go rename plugins/traefik/vendor/{go.uber.org/mock => google.golang.org/api}/AUTHORS (72%) create mode 100644 plugins/traefik/vendor/google.golang.org/api/CONTRIBUTORS create mode 100644 plugins/traefik/vendor/google.golang.org/api/LICENSE create mode 100644 plugins/traefik/vendor/google.golang.org/api/cloudresourcemanager/v1/cloudresourcemanager-api.json create mode 100644 plugins/traefik/vendor/google.golang.org/api/cloudresourcemanager/v1/cloudresourcemanager-gen.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/googleapi/googleapi.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/googleapi/transport/apikey.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/googleapi/types.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/cba.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/cert/default_cert.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/cert/enterprise_cert.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/cert/secureconnect_cert.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/conn_pool.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/credentialstype/credentialstype.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/creds.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/gensupport/buffer.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/gensupport/doc.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/gensupport/error.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/gensupport/json.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/gensupport/jsonfloat.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/gensupport/media.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/gensupport/params.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/gensupport/resumable.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/gensupport/retry.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/gensupport/send.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/gensupport/version.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/impersonate/impersonate.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/s2a.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/settings.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/third_party/uritemplates/LICENSE create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/third_party/uritemplates/METADATA create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/third_party/uritemplates/uritemplates.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/third_party/uritemplates/utils.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/internal/version.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/option/internaloption/internaloption.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/option/internaloption/unsaferesolver.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/option/option.go create mode 100644 plugins/traefik/vendor/google.golang.org/api/transport/http/dial.go create mode 100644 plugins/traefik/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go create mode 100644 plugins/traefik/vendor/google.golang.org/genproto/googleapis/rpc/code/code.pb.go create mode 100644 plugins/traefik/vendor/google.golang.org/genproto/googleapis/rpc/errdetails/error_details.pb.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/balancer/pickfirst/internal/internal.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/balancer/subconn.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/LICENSE create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/README.md create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/grpc.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/main.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/protoc-gen-go-grpc_test.sh create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/encoding/gzip/gzip.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/encoding/internal/internal.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/internal/balancer/weight/weight.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/internal/proxyattributes/proxyattributes.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/internal/resolver/delegatingresolver/delegatingresolver.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/internal/stats/stats.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/internal/transport/client_stream.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/internal/transport/server_stream.go create mode 100644 plugins/traefik/vendor/google.golang.org/grpc/stats/metrics.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/init.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/init_opaque.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/opaque.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/reflect.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/well_known_types.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/main.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/compiler/protogen/protogen.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/compiler/protogen/protogen_apilevel.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/compiler/protogen/protogen_opaque.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/internal/filedesc/presence.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/internal/msgfmt/format.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/reflect/protopath/path.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/reflect/protopath/step.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/reflect/protorange/range.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go create mode 100644 plugins/traefik/vendor/google.golang.org/protobuf/types/pluginpb/plugin.pb.go diff --git a/plugins/traefik/go.mod b/plugins/traefik/go.mod index 12b97a6ad..cfd41869a 100644 --- a/plugins/traefik/go.mod +++ b/plugins/traefik/go.mod @@ -1,6 +1,6 @@ module github.com/darkweak/souin/plugins/traefik -go 1.25 +go 1.25.0 require ( github.com/akyoto/cache v1.0.6 @@ -9,94 +9,125 @@ require ( ) require ( - cel.dev/expr v0.19.1 // indirect - dario.cat/mergo v1.0.1 // indirect - filippo.io/edwards25519 v1.1.0 // indirect + cel.dev/expr v0.25.1 // indirect + cloud.google.com/go/auth v0.18.2 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + cloud.google.com/go/compute/metadata v0.9.0 // indirect + dario.cat/mergo v1.0.2 // indirect + filippo.io/bigmod v0.1.0 // indirect + filippo.io/edwards25519 v1.2.0 // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect - github.com/KimMachineGun/automemlimit v0.7.1 // indirect + github.com/KimMachineGun/automemlimit v0.7.5 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect - github.com/Microsoft/go-winio v0.6.0 // indirect - github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect - github.com/caddyserver/caddy/v2 v2.10.0 // indirect - github.com/caddyserver/certmagic v0.23.0 // indirect - github.com/caddyserver/zerossl v0.1.3 // indirect + github.com/caddyserver/caddy/v2 v2.11.3 // indirect + github.com/caddyserver/certmagic v0.25.3 // indirect + github.com/caddyserver/zerossl v0.1.5 // indirect + github.com/ccoveille/go-safecast/v2 v2.0.0 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/chzyer/readline v1.5.1 // indirect - github.com/cloudflare/circl v1.6.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect + github.com/cloudflare/circl v1.6.3 // indirect + github.com/coreos/go-oidc/v3 v3.17.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/darkweak/go-esi v0.0.5 // indirect github.com/darkweak/storages/core v0.0.18 // indirect github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect - github.com/francoispqt/gojay v1.2.13 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-jose/go-jose/v3 v3.0.4 // indirect - github.com/go-kit/kit v0.13.0 // indirect - github.com/go-kit/log v0.2.1 // indirect - github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-sql-driver/mysql v1.7.1 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect - github.com/google/cel-go v0.24.1 // indirect - github.com/google/pprof v0.0.0-20231212022811-ec68065c825e // indirect + github.com/go-jose/go-jose/v4 v4.1.4 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-sql-driver/mysql v1.9.3 // indirect + github.com/google/cel-go v0.28.0 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect + github.com/googleapis/gax-go/v2 v2.18.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgconn v1.14.3 // indirect - github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.3.3 // indirect - github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/jackc/pgtype v1.14.0 // indirect - github.com/jackc/pgx/v4 v4.18.3 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect - github.com/libdns/libdns v1.0.0-beta.1 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/pgx/v5 v5.9.2 // indirect + github.com/jackc/puddle/v2 v2.2.2 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/libdns/libdns v1.1.1 // indirect github.com/manifoldco/promptui v0.9.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/mholt/acmez/v3 v3.1.2 // indirect + github.com/mholt/acmez/v3 v3.1.6 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.15.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pierrec/lz4/v4 v4.1.23 // indirect - github.com/quic-go/qpack v0.5.1 // indirect - github.com/quic-go/quic-go v0.50.1 // indirect - github.com/rs/xid v1.5.0 // indirect + github.com/prometheus/otlptranslator v1.0.0 // indirect + github.com/quic-go/qpack v0.6.0 // indirect + github.com/quic-go/quic-go v0.59.1 // indirect + github.com/rs/xid v1.6.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect - github.com/slackhq/nebula v1.6.1 // indirect - github.com/smallstep/certificates v0.26.1 // indirect - github.com/smallstep/nosql v0.6.1 // indirect - github.com/smallstep/pkcs7 v0.0.0-20231024181729-3b98ecc1ca81 // indirect - github.com/smallstep/scep v0.0.0-20231024192529-aee96d7ad34d // indirect + github.com/slackhq/nebula v1.10.3 // indirect + github.com/smallstep/certificates v0.30.2 // indirect + github.com/smallstep/cli-utils v0.12.2 // indirect + github.com/smallstep/linkedca v0.25.0 // indirect + github.com/smallstep/nosql v0.8.0 // indirect + github.com/smallstep/pkcs7 v0.2.1 // indirect + github.com/smallstep/scep v0.0.0-20250318231241-a25cabb69492 // indirect github.com/smallstep/truststore v0.13.0 // indirect - github.com/spf13/cobra v1.9.1 // indirect - github.com/spf13/pflag v1.0.6 // indirect - github.com/stoewer/go-strcase v1.2.0 // indirect - github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53 // indirect - github.com/urfave/cli v1.22.14 // indirect + github.com/spf13/cobra v1.10.2 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 // indirect + github.com/tailscale/tscert v0.0.0-20251216020129-aea342f6d747 // indirect + github.com/urfave/cli v1.22.17 // indirect github.com/zeebo/blake3 v0.2.4 // indirect - go.etcd.io/bbolt v1.3.9 // indirect - go.step.sm/cli-utils v0.9.0 // indirect - go.step.sm/crypto v0.45.0 // indirect - go.step.sm/linkedca v0.20.1 // indirect + go.etcd.io/bbolt v1.4.3 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/bridges/prometheus v0.68.0 // indirect + go.opentelemetry.io/contrib/exporters/autoexport v0.65.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect + go.opentelemetry.io/otel v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.65.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.19.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.43.0 // indirect + go.opentelemetry.io/otel/log v0.19.0 // indirect + go.opentelemetry.io/otel/metric v1.43.0 // indirect + go.opentelemetry.io/otel/sdk v1.43.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.19.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.43.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect + go.step.sm/crypto v0.77.1 // indirect go.uber.org/automaxprocs v1.6.0 // indirect - go.uber.org/mock v0.5.0 // indirect - go.uber.org/zap v1.27.0 // indirect + go.uber.org/zap v1.27.1 // indirect go.uber.org/zap/exp v0.3.0 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/crypto/x509roots/fallback v0.0.0-20250305170421-49bf5b80c810 // indirect - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/term v0.30.0 // indirect - golang.org/x/time v0.11.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + go.yaml.in/yaml/v2 v2.4.4 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.50.0 // indirect + golang.org/x/crypto/x509roots/fallback v0.0.0-20260213171211-a408498e5541 // indirect + golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect + golang.org/x/oauth2 v0.36.0 // indirect + golang.org/x/term v0.42.0 // indirect + golang.org/x/time v0.15.0 // indirect + google.golang.org/api v0.271.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect howett.net/plist v1.0.0 // indirect ) @@ -109,23 +140,23 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/uuid v1.6.0 - github.com/klauspost/compress v1.18.0 // indirect - github.com/miekg/dns v1.1.63 // indirect + github.com/klauspost/compress v1.18.5 // indirect + github.com/miekg/dns v1.1.72 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.22.0 // indirect + github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.62.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/procfs v0.20.1 // indirect github.com/spf13/cast v1.7.0 go.uber.org/multierr v1.11.0 // indirect - golang.org/x/mod v0.24.0 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/sync v0.14.0 - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - golang.org/x/tools v0.31.0 // indirect - google.golang.org/grpc v1.67.1 // indirect - google.golang.org/protobuf v1.36.6 // indirect + golang.org/x/mod v0.35.0 // indirect + golang.org/x/net v0.53.0 // indirect + golang.org/x/sync v0.20.0 + golang.org/x/sys v0.43.0 // indirect + golang.org/x/text v0.36.0 // indirect + golang.org/x/tools v0.44.0 // indirect + google.golang.org/grpc v1.80.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 ) diff --git a/plugins/traefik/go.sum b/plugins/traefik/go.sum index b16d50452..771f80b4b 100644 --- a/plugins/traefik/go.sum +++ b/plugins/traefik/go.sum @@ -1,95 +1,90 @@ -cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4= -cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= -cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= -cloud.google.com/go/auth v0.4.1 h1:Z7YNIhlWRtrnKlZke7z3GMqzvuYzdc2z98F9D1NV5Hg= -cloud.google.com/go/auth v0.4.1/go.mod h1:QVBuVEKpCn4Zp58hzRGvL0tjRGU0YqdRTdCHM1IHnro= -cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= -cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= -cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= -cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= -cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0= -cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE= -cloud.google.com/go/kms v1.16.0 h1:1yZsRPhmargZOmY+fVAh8IKiR9HzCb0U1zsxb5g2nRY= -cloud.google.com/go/kms v1.16.0/go.mod h1:olQUXy2Xud+1GzYfiBO9N0RhjsJk5IJLU6n/ethLXVc= -cloud.google.com/go/longrunning v0.5.7 h1:WLbHekDbjK1fVFD3ibpFFVoyizlLRl73I7YKuAKilhU= -cloud.google.com/go/longrunning v0.5.7/go.mod h1:8GClkudohy1Fxm3owmBGid8W0pSgodEMwEAztp38Xng= -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= +cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= +cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= +cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM= +cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc= +cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU= +cloud.google.com/go/kms v1.26.0 h1:cK9mN2cf+9V63D3H1f6koxTatWy39aTI/hCjz1I+adU= +cloud.google.com/go/kms v1.26.0/go.mod h1:pHKOdFJm63hxBsiPkYtowZPltu9dW0MWvBa6IA4HM58= +cloud.google.com/go/longrunning v0.8.0 h1:LiKK77J3bx5gDLi4SMViHixjD2ohlkwBi+mKA7EhfW8= +cloud.google.com/go/longrunning v0.8.0/go.mod h1:UmErU2Onzi+fKDg2gR7dusz11Pe26aknR4kHmJJqIfk= +code.pfad.fr/check v1.1.0 h1:GWvjdzhSEgHvEHe2uJujDcpmZoySKuHQNrZMfzfO0bE= +code.pfad.fr/check v1.1.0/go.mod h1:NiUH13DtYsb7xp5wll0U4SXx7KhXQVCtRgdC96IPfoM= +dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= +dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= +filippo.io/bigmod v0.1.0 h1:UNzDk7y9ADKST+axd9skUpBQeW7fG2KrTZyOE4uGQy8= +filippo.io/bigmod v0.1.0/go.mod h1:OjOXDNlClLblvXdwgFFOQFJEocLhhtai8vGLy0JCZlI= +filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= +filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/KimMachineGun/automemlimit v0.7.1 h1:QcG/0iCOLChjfUweIMC3YL5Xy9C3VBeNmCZHrZfJMBw= -github.com/KimMachineGun/automemlimit v0.7.1/go.mod h1:QZxpHaGOQoYvFhv/r4u3U0JTC2ZcOwbSr11UZF46UBM= +github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/KimMachineGun/automemlimit v0.7.5 h1:RkbaC0MwhjL1ZuBKunGDjE/ggwAX43DwZrJqVwyveTk= +github.com/KimMachineGun/automemlimit v0.7.5/go.mod h1:QZxpHaGOQoYvFhv/r4u3U0JTC2ZcOwbSr11UZF46UBM= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= -github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= -github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= -github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/akyoto/cache v1.0.6 h1:5XGVVYoi2i+DZLLPuVIXtsNIJ/qaAM16XT0LaBaXd2k= github.com/akyoto/cache v1.0.6/go.mod h1:WfxTRqKhfgAG71Xh6E3WLpjhBtZI37O53G4h5s+3iM4= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= -github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= +github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b h1:uUXgbcPDK3KpW29o4iy7GtuappbWT0l5NaMo9H9pJDw= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA= -github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= -github.com/aws/aws-sdk-go-v2/config v1.27.13 h1:WbKW8hOzrWoOA/+35S5okqO/2Ap8hkkFUzoW8Hzq24A= -github.com/aws/aws-sdk-go-v2/config v1.27.13/go.mod h1:XLiyiTMnguytjRER7u5RIkhIqS8Nyz41SwAWb4xEjxs= -github.com/aws/aws-sdk-go-v2/credentials v1.17.13 h1:XDCJDzk/u5cN7Aple7D/MiAhx1Rjo/0nueJ0La8mRuE= -github.com/aws/aws-sdk-go-v2/credentials v1.17.13/go.mod h1:FMNcjQrmuBYvOTZDtOLCIu0esmxjF7RuA/89iSXWzQI= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 h1:FVJ0r5XTHSmIHJV6KuDmdYhEpvlHpiSd38RQWhut5J4= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1/go.mod h1:zusuAeqezXzAB24LGuzuekqMAEgWkVYukBec3kr3jUg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 h1:aw39xVGeRWlWx9EzGVnhOR4yOjQDHPQ6o6NmBlscyQg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5/go.mod h1:FSaRudD0dXiMPK2UjknVwwTYyZMRsHv3TtkabsZih5I= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 h1:PG1F3OD1szkuQPzDw3CIQsRIrtTlUC3lP84taWzHlq0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5/go.mod h1:jU1li6RFryMz+so64PpKtudI+QzbKoIEivqdf6LNpOc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 h1:ogRAwT1/gxJBcSWDMZlgyFUM962F51A5CRhDLbxLdmo= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7/go.mod h1:YCsIZhXfRPLFFCl5xxY+1T9RKzOKjCut+28JSX2DnAk= -github.com/aws/aws-sdk-go-v2/service/kms v1.31.1 h1:5wtyAwuUiJiM3DHYeGZmP5iMonM7DFBWAEaaVPHYZA0= -github.com/aws/aws-sdk-go-v2/service/kms v1.31.1/go.mod h1:2snWQJQUKsbN66vAawJuOGX7dr37pfOq9hb0tZDGIqQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.6 h1:o5cTaeunSpfXiLTIBx5xo2enQmiChtu1IBbzXnfU9Hs= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.6/go.mod h1:qGzynb/msuZIE8I75DVRCUXw3o3ZyBmUvMwQ2t/BrGM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.0 h1:Qe0r0lVURDDeBQJ4yP+BOrJkvkiCo/3FH/t+wY11dmw= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.0/go.mod h1:mUYPBhaF2lGiukDEjJX2BLRRKTmoUSitGDUgM4tRxak= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.7 h1:et3Ta53gotFR4ERLXXHIHl/Uuk1qYpP5uU7cvNql8ns= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.7/go.mod h1:FZf1/nKNEkHdGGJP/cI2MoIMquumuRK6ol3QQJNDxmw= -github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= -github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/aws/aws-sdk-go-v2 v1.41.4 h1:10f50G7WyU02T56ox1wWXq+zTX9I1zxG46HYuG1hH/k= +github.com/aws/aws-sdk-go-v2 v1.41.4/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= +github.com/aws/aws-sdk-go-v2/config v1.32.12 h1:O3csC7HUGn2895eNrLytOJQdoL2xyJy0iYXhoZ1OmP0= +github.com/aws/aws-sdk-go-v2/config v1.32.12/go.mod h1:96zTvoOFR4FURjI+/5wY1vc1ABceROO4lWgWJuxgy0g= +github.com/aws/aws-sdk-go-v2/credentials v1.19.12 h1:oqtA6v+y5fZg//tcTWahyN9PEn5eDU/Wpvc2+kJ4aY8= +github.com/aws/aws-sdk-go-v2/credentials v1.19.12/go.mod h1:U3R1RtSHx6NB0DvEQFGyf/0sbrpJrluENHdPy1j/3TE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20 h1:zOgq3uezl5nznfoK3ODuqbhVg1JzAGDUhXOsU0IDCAo= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20/go.mod h1:z/MVwUARehy6GAg/yQ1GO2IMl0k++cu1ohP9zo887wE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20 h1:CNXO7mvgThFGqOFgbNAP2nol2qAWBOGfqR/7tQlvLmc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20/go.mod h1:oydPDJKcfMhgfcgBUZaG+toBbwy8yPWubJXBVERtI4o= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 h1:tN6W/hg+pkM+tf9XDkWUbDEjGLb+raoBMFsTodcoYKw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20/go.mod h1:YJ898MhD067hSHA6xYCx5ts/jEd8BSOLtQDL3iZsvbc= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20 h1:2HvVAIq+YqgGotK6EkMf+KIEqTISmTYh5zLpYyeTo1Y= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20/go.mod h1:V4X406Y666khGa8ghKmphma/7C0DAtEQYhkq9z4vpbk= +github.com/aws/aws-sdk-go-v2/service/kms v1.50.3 h1:s/zDSG/a/Su9aX+v0Ld9cimUCdkr5FWPmBV8owaEbZY= +github.com/aws/aws-sdk-go-v2/service/kms v1.50.3/go.mod h1:/iSgiUor15ZuxFGQSTf3lA2FmKxFsQoc2tADOarQBSw= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.8 h1:0GFOLzEbOyZABS3PhYfBIx2rNBACYcKty+XGkTgw1ow= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.8/go.mod h1:LXypKvk85AROkKhOG6/YEcHFPoX+prKTowKnVdcaIxE= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.13 h1:kiIDLZ005EcKomYYITtfsjn7dtOwHDOFy7IbPXKek2o= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.13/go.mod h1:2h/xGEowcW/g38g06g3KpRWDlT+OTfxxI0o1KqayAB8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17 h1:jzKAXIlhZhJbnYwHbvUQZEB8KfgAEuG0dc08Bkda7NU= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17/go.mod h1:Al9fFsXjv4KfbzQHGe6V4NZSZQXecFcvaIF4e70FoRA= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.9 h1:Cng+OOwCHmFljXIxpEVXAGMnBia8MSU6Ch5i9PgBkcU= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.9/go.mod h1:LrlIndBDdjA/EeXeyNBle+gyCwTlizzW5ycgWnvIxkk= +github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= +github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/caddyserver/caddy/v2 v2.10.0 h1:fonubSaQKF1YANl8TXqGcn4IbIRUDdfAkpcsfI/vX5U= -github.com/caddyserver/caddy/v2 v2.10.0/go.mod h1:q+dgBS3xtIJJGYI2H5Nyh9+4BvhQQ9yCGmECv4Ubdjo= -github.com/caddyserver/certmagic v0.23.0 h1:CfpZ/50jMfG4+1J/u2LV6piJq4HOfO6ppOnOf7DkFEU= -github.com/caddyserver/certmagic v0.23.0/go.mod h1:9mEZIWqqWoI+Gf+4Trh04MOVPD0tGSxtqsxg87hAIH4= -github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= -github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= +github.com/caddyserver/caddy/v2 v2.11.3 h1:/vFbdjcs2DtzcWTIxHybf5R5TspYFFThlZffChyBFHg= +github.com/caddyserver/caddy/v2 v2.11.3/go.mod h1:J9qdmC4A1g+q8wBa+bEWOUgPJhUgs00juslRJGbGzlU= +github.com/caddyserver/certmagic v0.25.3 h1:mGf5ba8F7xA4c5jfDZZbK2buY1VEkbnwpMDixaju94A= +github.com/caddyserver/certmagic v0.25.3/go.mod h1:YVs43D5+H/Dckt4bTga1KSO/xYfFBfVZainGDywYPAA= +github.com/caddyserver/zerossl v0.1.5 h1:dkvOjBAEEtY6LIGAHei7sw2UgqSD6TrWweXpV7lvEvE= +github.com/caddyserver/zerossl v0.1.5/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= +github.com/ccoveille/go-safecast/v2 v2.0.0 h1:+5eyITXAUj3wMjad6cRVJKGnC7vDS55zk0INzJagub0= +github.com/ccoveille/go-safecast/v2 v2.0.0/go.mod h1:JIYA4CAR33blIDuE6fSwCp2sz1oOBahXnvmdBhOAABs= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -103,22 +98,17 @@ github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObk github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk= -github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= -github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= +github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc= +github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= +github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/darkweak/go-esi v0.0.5 h1:b9LHI8Tz46R+i6p8avKPHAIBRQUCZDebNmKm5w/Zrns= github.com/darkweak/go-esi v0.0.5/go.mod h1:koCJqwum1u6mslyZuq/Phm6hfG1K3ZK5Y7jrUBTH654= github.com/darkweak/storages/core v0.0.18 h1:qE9vQb31of3f1a4Zm9/uvnamyJdecRNvtK60A4DNWKE= @@ -142,198 +132,101 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= -github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= -github.com/go-kit/kit v0.4.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= -github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= -github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= +github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= -github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= -github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= -github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cel-go v0.24.1 h1:jsBCtxG8mM5wiUJDSGUqU0K7Mtr3w7Eyv00rw4DiZxI= -github.com/google/cel-go v0.24.1/go.mod h1:Hdf9TqOaTNSFQA1ybQaRqATVoK7m/zcf7IMhGXP5zI8= +github.com/google/cel-go v0.28.0 h1:KjSWstCpz/MN5t4a8gnGJNIYUsJRpdi/r97xWDphIQc= +github.com/google/cel-go v0.28.0/go.mod h1:X0bD6iVNR8pkROSOoHVdgTkzmRcosof7WQqCD6wcMc8= github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745 h1:heyoXNxkRT155x4jTAiSv5BVSVkueifPUm+Q8LUXMRo= github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745/go.mod h1:zN0wUQgV9LjwLZeFHnrAbQi8hzMVvEWePyk+MhPOk7k= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= -github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= -github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= -github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20231212022811-ec68065c825e h1:bwOy7hAFd0C91URzMIEBfr6BAz29yk7Qj0cy6S7DJlU= -github.com/google/pprof v0.0.0-20231212022811-ec68065c825e/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= -github.com/googleapis/gax-go/v2 v2.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw4Z96qg= -github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA6RlzjJaT4hi3kII+zYw8wmLb8= +github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= +github.com/googleapis/gax-go/v2 v2.18.0 h1:jxP5Uuo3bxm3M6gGtV94P4lliVetoCB4Wk2x8QA86LI= +github.com/googleapis/gax-go/v2 v2.18.0/go.mod h1:uSzZN4a356eRG985CzJ3WfbFSpqkLTjsnhWGJR6EwrE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= -github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= -github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= -github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= -github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= -github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= -github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= -github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w= -github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM= -github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= -github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= -github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= -github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= -github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= -github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= -github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= -github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= -github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag= -github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= -github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= -github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= -github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw= -github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= -github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= -github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= -github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= -github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA= -github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= -github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.9.2 h1:3ZhOzMWnR4yJ+RW1XImIPsD1aNSz4T4fyP7zlQb56hw= +github.com/jackc/pgx/v5 v5.9.2/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= -github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= +github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= -github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libdns/libdns v1.0.0-beta.1 h1:KIf4wLfsrEpXpZ3vmc/poM8zCATXT2klbdPe6hyOBjQ= -github.com/libdns/libdns v1.0.0-beta.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= -github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/letsencrypt/challtestsrv v1.4.2 h1:0ON3ldMhZyWlfVNYYpFuWRTmZNnyfiL9Hh5YzC3JVwU= +github.com/letsencrypt/challtestsrv v1.4.2/go.mod h1:GhqMqcSoeGpYd5zX5TgwA6er/1MbWzx/o7yuuVya+Wk= +github.com/letsencrypt/pebble/v2 v2.10.0 h1:Wq6gYXlsY6ubqI3hhxsTzdyotvfdjFBxuwYqCLCnj/U= +github.com/letsencrypt/pebble/v2 v2.10.0/go.mod h1:Sk8cmUIPcIdv2nINo+9PB4L+ZBhzY+F9A1a/h/xmWiQ= +github.com/libdns/libdns v1.1.1 h1:wPrHrXILoSHKWJKGd0EiAVmiJbFShguILTg9leS/P/U= +github.com/libdns/libdns v1.1.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/mholt/acmez/v3 v3.1.2 h1:auob8J/0FhmdClQicvJvuDavgd5ezwLBfKuYmynhYzc= -github.com/mholt/acmez/v3 v3.1.2/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= -github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs= +github.com/mholt/acmez/v3 v3.1.6 h1:eGVQNObP0pBN4sxqrXeg7MYqTOWyoiYpQqITVWlrevk= +github.com/mholt/acmez/v3 v3.1.6/go.mod h1:5nTPosTGosLxF3+LU4ygbgMRFDhbAVpqMI4+a4aHLBY= +github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI= +github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -342,17 +235,8 @@ github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= -github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= -github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= -github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= -github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -369,88 +253,55 @@ github.com/pquerna/cachecontrol v0.2.0 h1:vBXSNuE5MYP9IJ5kjsdo8uq+w41jSPgvba2DEn github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= -github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= -github.com/quic-go/quic-go v0.50.1 h1:unsgjFIUqW8a2oopkY7YNONpV1gYND6Nt9hnt1PN94Q= -github.com/quic-go/quic-go v0.50.1/go.mod h1:Vim6OmUvlYdwBhXP9ZVrtGmCMWa3wEqhq3NgYrI8b4E= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= -github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= +github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= +github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= +github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= +github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= +github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= +github.com/quic-go/quic-go v0.59.1 h1:0Gmua0HW1Tv7ANR7hUYwRyD0MG5OJfgvYSZasGZzBic= +github.com/quic-go/quic-go v0.59.1/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/jsonstore v1.1.0 h1:WZBDjgezFS34CHI+myb4s8GGpir3UMpy7vWoCeO0n6E= github.com/schollz/jsonstore v1.1.0/go.mod h1:15c6+9guw8vDRyozGjN3FoILt0wpruJk9Pi66vjaZfg= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= -github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= -github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/slackhq/nebula v1.6.1 h1:/OCTR3abj0Sbf2nGoLUrdDXImrCv0ZVFpVPP5qa0DsM= -github.com/slackhq/nebula v1.6.1/go.mod h1:UmkqnXe4O53QwToSl/gG7sM4BroQwAB7dd4hUaT6MlI= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= +github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +github.com/slackhq/nebula v1.10.3 h1:EstYj8ODEcv6T0R9X5BVq1zgWZnyU5gtPzk99QF1PMU= +github.com/slackhq/nebula v1.10.3/go.mod h1:IL5TUQm4x9IFx2kCKPYm1gP47pwd5b8QGnnBH2RHnvs= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1/1fApl1A+9VcBk+9dcqGfnePY87LY= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc= -github.com/smallstep/certificates v0.26.1 h1:FIUliEBcExSfJJDhRFA/s8aZgMIFuorexnRSKQd884o= -github.com/smallstep/certificates v0.26.1/go.mod h1:OQMrW39IrGKDViKSHrKcgSQArMZ8c7EcjhYKK7mYqis= -github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 h1:kjYvkvS/Wdy0PVRDUAA0gGJIVSEZYhiAJtfwYgOYoGA= -github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935/go.mod h1:vNAduivU014fubg6ewygkAvQC0IQVXqdc8vaGl/0er4= -github.com/smallstep/nosql v0.6.1 h1:X8IBZFTRIp1gmuf23ne/jlD/BWKJtDQbtatxEn7Et1Y= -github.com/smallstep/nosql v0.6.1/go.mod h1:vrN+CftYYNnDM+DQqd863ATynvYFm/6FuY9D4TeAm2Y= -github.com/smallstep/pkcs7 v0.0.0-20231024181729-3b98ecc1ca81 h1:B6cED3iLJTgxpdh4tuqByDjRRKan2EvtnOfHr2zHJVg= -github.com/smallstep/pkcs7 v0.0.0-20231024181729-3b98ecc1ca81/go.mod h1:SoUAr/4M46rZ3WaLstHxGhLEgoYIDRqxQEXLOmOEB0Y= -github.com/smallstep/scep v0.0.0-20231024192529-aee96d7ad34d h1:06LUHn4Ia2X6syjIaCMNaXXDNdU+1N/oOHynJbWgpXw= -github.com/smallstep/scep v0.0.0-20231024192529-aee96d7ad34d/go.mod h1:4d0ub42ut1mMtvGyMensjuHYEUpRrASvkzLEJvoRQcU= +github.com/smallstep/certificates v0.30.2 h1:1G3xBi8sJ740iA1mMPW2Svv7EIZKJ4Zf/iQtA5QlN0Y= +github.com/smallstep/certificates v0.30.2/go.mod h1:oyaE/aEYUGDr+YiCZLAxxP22bOQqcSHTeDgp8Vv2rlY= +github.com/smallstep/cli-utils v0.12.2 h1:lGzM9PJrH/qawbzMC/s2SvgLdJPKDWKwKzx9doCVO+k= +github.com/smallstep/cli-utils v0.12.2/go.mod h1:uCPqefO29goHLGqFnwk0i8W7XJu18X3WHQFRtOm/00Y= +github.com/smallstep/go-attestation v0.4.4-0.20241119153605-2306d5b464ca h1:VX8L0r8vybH0bPeaIxh4NQzafKQiqvlOn8pmOXbFLO4= +github.com/smallstep/go-attestation v0.4.4-0.20241119153605-2306d5b464ca/go.mod h1:vNAduivU014fubg6ewygkAvQC0IQVXqdc8vaGl/0er4= +github.com/smallstep/linkedca v0.25.0 h1:txT9QHGbCsJq0MhAghBq7qhurGY727tQuqUi+n4BVBo= +github.com/smallstep/linkedca v0.25.0/go.mod h1:Q3jVAauFKNlF86W5/RFtgQeyDKz98GL/KN3KG4mJOvc= +github.com/smallstep/nosql v0.8.0 h1:FBTCUfKPmWYbrozW+RBKu+fnvbn+zr5rVli/XB4Jp4A= +github.com/smallstep/nosql v0.8.0/go.mod h1:5dUpNotHLHhOUapP0PLBVVfp3tG1DFC31VRccg+Cqwo= +github.com/smallstep/pkcs7 v0.2.1 h1:6Kfzr/QizdIuB6LSv8y1LJdZ3aPSfTNhTLqAx9CTLfA= +github.com/smallstep/pkcs7 v0.2.1/go.mod h1:RcXHsMfL+BzH8tRhmrF1NkkpebKpq3JEM66cOFxanf0= +github.com/smallstep/scep v0.0.0-20250318231241-a25cabb69492 h1:k23+s51sgYix4Zgbvpmy+1ZgXLjr4ZTkBTqXmpnImwA= +github.com/smallstep/scep v0.0.0-20250318231241-a25cabb69492/go.mod h1:QQhwLqCS13nhv8L5ov7NgusowENUtXdEzdytjmJHdZQ= github.com/smallstep/truststore v0.13.0 h1:90if9htAOblavbMeWlqNLnO9bsjjgVv2hQeQJCi/py4= github.com/smallstep/truststore v0.13.0/go.mod h1:3tmMp2aLKZ/OA/jnFUB0cYPcho402UG2knuJoPh4j7A= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -459,39 +310,36 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= -github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53 h1:uxMgm0C+EjytfAqyfBG55ZONKQ7mvd7x4YYCWsf8QHQ= -github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53/go.mod h1:kNGUQ3VESx3VZwRwA9MSCUegIl6+saPL8Noq82ozCaU= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 h1:Gzfnfk2TWrk8Jj4P4c1a3CtQyMaTVCznlkLZI++hok4= +github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55/go.mod h1:4k4QO+dQ3R5FofL+SanAUZe+/QfeK0+OIuwDIRu2vSg= +github.com/tailscale/tscert v0.0.0-20251216020129-aea342f6d747 h1:RnBbFMmodYzhC6adOjTbtUQXyzV8dcvKYbolzs6Qch0= +github.com/tailscale/tscert v0.0.0-20251216020129-aea342f6d747/go.mod h1:ejPAJui3kVK4u5TgMtqtXlWf5HnKh9fLy5kvpaeuas0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= -github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= -github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= -github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= +github.com/urfave/cli v1.22.17 h1:SYzXoiPfQjHBbkYxbew5prZHS1TOLT3ierW8SYLqtVQ= +github.com/urfave/cli v1.22.17/go.mod h1:b0ht0aqgH/6pBYzzxURyrM4xXNgsoT/n2ZzwQiEhNVo= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= @@ -500,242 +348,193 @@ github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= -go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= -go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= -go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= -go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= -go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= -go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= -go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= -go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= -go.step.sm/cli-utils v0.9.0 h1:55jYcsQbnArNqepZyAwcato6Zy2MoZDRkWW+jF+aPfQ= -go.step.sm/cli-utils v0.9.0/go.mod h1:Y/CRoWl1FVR9j+7PnAewufAwKmBOTzR6l9+7EYGAnp8= -go.step.sm/crypto v0.45.0 h1:Z0WYAaaOYrJmKP9sJkPW+6wy3pgN3Ija8ek/D4serjc= -go.step.sm/crypto v0.45.0/go.mod h1:6IYlT0L2jfj81nVyCPpvA5cORy0EVHPhieSgQyuwHIY= -go.step.sm/linkedca v0.20.1 h1:bHDn1+UG1NgRrERkWbbCiAIvv4lD5NOFaswPDTyO5vU= -go.step.sm/linkedca v0.20.1/go.mod h1:Vaq4+Umtjh7DLFI1KuIxeo598vfBzgSYZUjgVJ7Syxw= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo= +go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/bridges/prometheus v0.68.0 h1:w3zlHYETbDwXyWHZlyyR58ZC39XGi8rAhkBgUgJ9d5w= +go.opentelemetry.io/contrib/bridges/prometheus v0.68.0/go.mod h1:GR/mClR2nn7vE8RLwxKjoBNg+QtgdDhRzxVa93koy5o= +go.opentelemetry.io/contrib/exporters/autoexport v0.65.0 h1:2gApdml7SznX9szEKFjKjM4qGcGSvAybYLBY319XG3g= +go.opentelemetry.io/contrib/exporters/autoexport v0.65.0/go.mod h1:0QqAGlbHXhmPYACG3n5hNzO5DnEqqtg4VcK5pr22RI0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 h1:Dn8rkudDzY6KV9dr/D/bTUuWgqDf9xe0rr4G2elrn0Y= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0/go.mod h1:gMk9F0xDgyN9M/3Ed5Y1wKcx/9mlU91NXY2SNq7RQuU= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 h1:HIBTQ3VO5aupLKjC90JgMqpezVXwFuq6Ryjn0/izoag= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0/go.mod h1:ji9vId85hMxqfvICA0Jt8JqEdrXaAkcpkI9HPXya0ro= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0 h1:8UQVDcZxOJLtX6gxtDt3vY2WTgvZqMQRzjsqiIHQdkc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0/go.mod h1:2lmweYCiHYpEjQ/lSJBYhj9jP1zvCvQW4BqL9dnT7FQ= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 h1:w1K+pCJoPpQifuVpsKamUdn9U0zM3xUziVOqsGksUrY= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0/go.mod h1:HBy4BjzgVE8139ieRI75oXm3EcDN+6GhD88JT1Kjvxg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 h1:88Y4s2C8oTui1LGM6bTWkw0ICGcOLCAI5l6zsD1j20k= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0/go.mod h1:Vl1/iaggsuRlrHf/hfPJPvVag77kKyvrLeD10kpMl+A= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 h1:RAE+JPfvEmvy+0LzyUA25/SGawPwIUbZ6u0Wug54sLc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0/go.mod h1:AGmbycVGEsRx9mXMZ75CsOyhSP6MFIcj/6dnG+vhVjk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 h1:3iZJKlCZufyRzPzlQhUIWVmfltrXuGyfjREgGP3UUjc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0/go.mod h1:/G+nUPfhq2e+qiXMGxMwumDrP5jtzU+mWN7/sjT2rak= +go.opentelemetry.io/otel/exporters/prometheus v0.65.0 h1:jOveH/b4lU9HT7y+Gfamf18BqlOuz2PWEvs8yM7Q6XE= +go.opentelemetry.io/otel/exporters/prometheus v0.65.0/go.mod h1:i1P8pcumauPtUI4YNopea1dhzEMuEqWP1xoUZDylLHo= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.19.0 h1:GJkybS+crDMdExT/BUNCEgfrmfboztcS6PhvSo88HKM= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.19.0/go.mod h1:NuAyxRYIG2lKX3YQkB+83StTxM7s52PUUkRRiC0wnYI= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.43.0 h1:TC+BewnDpeiAmcscXbGMfxkO+mwYUwE/VySwvw88PfA= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.43.0/go.mod h1:J/ZyF4vfPwsSr9xJSPyQ4LqtcTPULFR64KwTikGLe+A= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.43.0 h1:mS47AX77OtFfKG4vtp+84kuGSFZHTyxtXIN269vChY0= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.43.0/go.mod h1:PJnsC41lAGncJlPUniSwM81gc80GkgWJWr3cu2nKEtU= +go.opentelemetry.io/otel/log v0.19.0 h1:KUZs/GOsw79TBBMfDWsXS+KZ4g2Ckzksd1ymzsIEbo4= +go.opentelemetry.io/otel/log v0.19.0/go.mod h1:5DQYeGmxVIr4n0/BcJvF4upsraHjg6vudJJpnkL6Ipk= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/log v0.19.0 h1:scYVLqT22D2gqXItnWiocLUKGH9yvkkeql5dBDiXyko= +go.opentelemetry.io/otel/sdk/log v0.19.0/go.mod h1:vFBowwXGLlW9AvpuF7bMgnNI95LiW10szrOdvzBHlAg= +go.opentelemetry.io/otel/sdk/log/logtest v0.19.0 h1:BEbF7ZBB6qQloV/Ub1+3NQoOUnVtcGkU3XX4Ws3GQfk= +go.opentelemetry.io/otel/sdk/log/logtest v0.19.0/go.mod h1:Lua81/3yM0wOmoHTokLj9y9ADeA02v1naRrVrkAZuKk= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.step.sm/crypto v0.77.1 h1:4EEqfKdv0egQ1lqz2RhnU8Jv6QgXZfrgoxWMqJF9aDs= +go.step.sm/crypto v0.77.1/go.mod h1:U/SsmEm80mNnfD5WIkbhuW/B1eFp3fgFvdXyDLpU1AQ= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= -go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U= go.uber.org/zap/exp v0.3.0/go.mod h1:5I384qq7XGxYyByIhHm6jg5CHkGY0nsTfbDLgDDlgJQ= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= -golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= +go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= -golang.org/x/crypto/x509roots/fallback v0.0.0-20250305170421-49bf5b80c810 h1:V5+zy0jmgNYmK1uW/sPpBw8ioFvalrhaUrYWmu1Fpe4= -golang.org/x/crypto/x509roots/fallback v0.0.0-20250305170421-49bf5b80c810/go.mod h1:lxN5T34bK4Z/i6cMaU7frUU57VkDXFD4Kamfl/cp9oU= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/crypto/x509roots/fallback v0.0.0-20260213171211-a408498e5541 h1:FmKxj9ocLKn45jiR2jQMwCVhDvaK7fKQFzfuT9GvyK8= +golang.org/x/crypto/x509roots/fallback v0.0.0-20260213171211-a408498e5541/go.mod h1:+UoQFNBq2p2wO+Q6ddVtYc25GZ6VNdOMyyrd4nrqrKs= +golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY= +golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.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-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.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-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.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-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -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/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= 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= -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.4/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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -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-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -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-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= 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-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/api v0.180.0 h1:M2D87Yo0rGBPWpo1orwfCLehUUL6E7/TYe5gvMQWDh4= -google.golang.org/api v0.180.0/go.mod h1:51AiyoEg1MJPSZ9zvklA8VnRILPXxn1iVen9v25XHAE= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda h1:wu/KJm9KJwpfHWhkkZGohVC6KRrc1oJNr4jwtQMOQXw= -google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda/go.mod h1:g2LLCvCeCSir/JJSWosk19BR4NVxGqHUC6rxIRsd7Aw= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/api v0.271.0 h1:cIPN4qcUc61jlh7oXu6pwOQqbJW2GqYh5PS6rB2C/JY= +google.golang.org/api v0.271.0/go.mod h1:CGT29bhwkbF+i11qkRUJb2KMKqcJ1hdFceEIRd9u64Q= +google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d h1:vsOm753cOAMkt76efriTCDKjpCbK18XGHMJHo0JUKhc= +google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:0oz9d7g9QLSdv9/lgbIjowW1JoxMbxmBVNe8i6tORJI= +google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA= +google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= -sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/plugins/traefik/vendor/cel.dev/expr/.bazelversion b/plugins/traefik/vendor/cel.dev/expr/.bazelversion index 26bc914a3..13c50892b 100644 --- a/plugins/traefik/vendor/cel.dev/expr/.bazelversion +++ b/plugins/traefik/vendor/cel.dev/expr/.bazelversion @@ -1,2 +1,2 @@ -7.0.1 +7.3.2 # Keep this pinned version in parity with cel-go diff --git a/plugins/traefik/vendor/cel.dev/expr/BUILD.bazel b/plugins/traefik/vendor/cel.dev/expr/BUILD.bazel index 37d8adc95..f5bda3bb1 100644 --- a/plugins/traefik/vendor/cel.dev/expr/BUILD.bazel +++ b/plugins/traefik/vendor/cel.dev/expr/BUILD.bazel @@ -16,7 +16,6 @@ go_library( importpath = "cel.dev/expr", visibility = ["//visibility:public"], deps = [ - "@org_golang_google_genproto_googleapis_rpc//status:go_default_library", "@org_golang_google_protobuf//reflect/protoreflect", "@org_golang_google_protobuf//runtime/protoimpl", "@org_golang_google_protobuf//types/known/anypb", diff --git a/plugins/traefik/vendor/cel.dev/expr/MODULE.bazel b/plugins/traefik/vendor/cel.dev/expr/MODULE.bazel index 9794266f5..cb98ed599 100644 --- a/plugins/traefik/vendor/cel.dev/expr/MODULE.bazel +++ b/plugins/traefik/vendor/cel.dev/expr/MODULE.bazel @@ -8,26 +8,21 @@ bazel_dep( ) bazel_dep( name = "gazelle", - version = "0.36.0", + version = "0.39.1", repo_name = "bazel_gazelle", ) -bazel_dep( - name = "googleapis", - version = "0.0.0-20240819-fe8ba054a", - repo_name = "com_google_googleapis", -) bazel_dep( name = "protobuf", - version = "26.0", + version = "27.1", repo_name = "com_google_protobuf", ) bazel_dep( name = "rules_cc", - version = "0.0.9", + version = "0.0.17", ) bazel_dep( name = "rules_go", - version = "0.49.0", + version = "0.53.0", repo_name = "io_bazel_rules_go", ) bazel_dep( @@ -36,7 +31,7 @@ bazel_dep( ) bazel_dep( name = "rules_proto", - version = "6.0.0", + version = "7.0.2", ) bazel_dep( name = "rules_python", @@ -50,21 +45,12 @@ python.toolchain( python_version = "3.11", ) -switched_rules = use_extension("@com_google_googleapis//:extensions.bzl", "switched_rules") -switched_rules.use_languages( - cc = True, - go = True, - java = True, -) -use_repo(switched_rules, "com_google_googleapis_imports") - go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk") -go_sdk.download(version = "1.21.1") +go_sdk.download(version = "1.23.0") go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps") go_deps.from_file(go_mod = "//:go.mod") use_repo( go_deps, - "org_golang_google_genproto_googleapis_rpc", "org_golang_google_protobuf", ) diff --git a/plugins/traefik/vendor/cel.dev/expr/README.md b/plugins/traefik/vendor/cel.dev/expr/README.md index 7930c0b75..42d67f87c 100644 --- a/plugins/traefik/vendor/cel.dev/expr/README.md +++ b/plugins/traefik/vendor/cel.dev/expr/README.md @@ -69,5 +69,3 @@ For more detail, see: * [Language Definition](doc/langdef.md) Released under the [Apache License](LICENSE). - -Disclaimer: This is not an official Google product. diff --git a/plugins/traefik/vendor/cel.dev/expr/checked.pb.go b/plugins/traefik/vendor/cel.dev/expr/checked.pb.go index bb225c8ab..b18085e9b 100644 --- a/plugins/traefik/vendor/cel.dev/expr/checked.pb.go +++ b/plugins/traefik/vendor/cel.dev/expr/checked.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.5 +// protoc-gen-go v1.36.10 +// protoc v5.27.1 // source: cel/expr/checked.proto package expr @@ -13,6 +13,7 @@ import ( structpb "google.golang.org/protobuf/types/known/structpb" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -136,24 +137,21 @@ func (Type_WellKnownType) EnumDescriptor() ([]byte, []int) { } type CheckedExpr struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ReferenceMap map[int64]*Reference `protobuf:"bytes,2,rep,name=reference_map,json=referenceMap,proto3" json:"reference_map,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + TypeMap map[int64]*Type `protobuf:"bytes,3,rep,name=type_map,json=typeMap,proto3" json:"type_map,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + SourceInfo *SourceInfo `protobuf:"bytes,5,opt,name=source_info,json=sourceInfo,proto3" json:"source_info,omitempty"` + ExprVersion string `protobuf:"bytes,6,opt,name=expr_version,json=exprVersion,proto3" json:"expr_version,omitempty"` + Expr *Expr `protobuf:"bytes,4,opt,name=expr,proto3" json:"expr,omitempty"` unknownFields protoimpl.UnknownFields - - ReferenceMap map[int64]*Reference `protobuf:"bytes,2,rep,name=reference_map,json=referenceMap,proto3" json:"reference_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - TypeMap map[int64]*Type `protobuf:"bytes,3,rep,name=type_map,json=typeMap,proto3" json:"type_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - SourceInfo *SourceInfo `protobuf:"bytes,5,opt,name=source_info,json=sourceInfo,proto3" json:"source_info,omitempty"` - ExprVersion string `protobuf:"bytes,6,opt,name=expr_version,json=exprVersion,proto3" json:"expr_version,omitempty"` - Expr *Expr `protobuf:"bytes,4,opt,name=expr,proto3" json:"expr,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CheckedExpr) Reset() { *x = CheckedExpr{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CheckedExpr) String() string { @@ -164,7 +162,7 @@ func (*CheckedExpr) ProtoMessage() {} func (x *CheckedExpr) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -215,11 +213,8 @@ func (x *CheckedExpr) GetExpr() *Expr { } type Type struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to TypeKind: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to TypeKind: // // *Type_Dyn // *Type_Null @@ -234,16 +229,16 @@ type Type struct { // *Type_Type // *Type_Error // *Type_AbstractType_ - TypeKind isType_TypeKind `protobuf_oneof:"type_kind"` + TypeKind isType_TypeKind `protobuf_oneof:"type_kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Type) Reset() { *x = Type{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Type) String() string { @@ -254,7 +249,7 @@ func (*Type) ProtoMessage() {} func (x *Type) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -269,100 +264,126 @@ func (*Type) Descriptor() ([]byte, []int) { return file_cel_expr_checked_proto_rawDescGZIP(), []int{1} } -func (m *Type) GetTypeKind() isType_TypeKind { - if m != nil { - return m.TypeKind +func (x *Type) GetTypeKind() isType_TypeKind { + if x != nil { + return x.TypeKind } return nil } func (x *Type) GetDyn() *emptypb.Empty { - if x, ok := x.GetTypeKind().(*Type_Dyn); ok { - return x.Dyn + if x != nil { + if x, ok := x.TypeKind.(*Type_Dyn); ok { + return x.Dyn + } } return nil } func (x *Type) GetNull() structpb.NullValue { - if x, ok := x.GetTypeKind().(*Type_Null); ok { - return x.Null + if x != nil { + if x, ok := x.TypeKind.(*Type_Null); ok { + return x.Null + } } return structpb.NullValue(0) } func (x *Type) GetPrimitive() Type_PrimitiveType { - if x, ok := x.GetTypeKind().(*Type_Primitive); ok { - return x.Primitive + if x != nil { + if x, ok := x.TypeKind.(*Type_Primitive); ok { + return x.Primitive + } } return Type_PRIMITIVE_TYPE_UNSPECIFIED } func (x *Type) GetWrapper() Type_PrimitiveType { - if x, ok := x.GetTypeKind().(*Type_Wrapper); ok { - return x.Wrapper + if x != nil { + if x, ok := x.TypeKind.(*Type_Wrapper); ok { + return x.Wrapper + } } return Type_PRIMITIVE_TYPE_UNSPECIFIED } func (x *Type) GetWellKnown() Type_WellKnownType { - if x, ok := x.GetTypeKind().(*Type_WellKnown); ok { - return x.WellKnown + if x != nil { + if x, ok := x.TypeKind.(*Type_WellKnown); ok { + return x.WellKnown + } } return Type_WELL_KNOWN_TYPE_UNSPECIFIED } func (x *Type) GetListType() *Type_ListType { - if x, ok := x.GetTypeKind().(*Type_ListType_); ok { - return x.ListType + if x != nil { + if x, ok := x.TypeKind.(*Type_ListType_); ok { + return x.ListType + } } return nil } func (x *Type) GetMapType() *Type_MapType { - if x, ok := x.GetTypeKind().(*Type_MapType_); ok { - return x.MapType + if x != nil { + if x, ok := x.TypeKind.(*Type_MapType_); ok { + return x.MapType + } } return nil } func (x *Type) GetFunction() *Type_FunctionType { - if x, ok := x.GetTypeKind().(*Type_Function); ok { - return x.Function + if x != nil { + if x, ok := x.TypeKind.(*Type_Function); ok { + return x.Function + } } return nil } func (x *Type) GetMessageType() string { - if x, ok := x.GetTypeKind().(*Type_MessageType); ok { - return x.MessageType + if x != nil { + if x, ok := x.TypeKind.(*Type_MessageType); ok { + return x.MessageType + } } return "" } func (x *Type) GetTypeParam() string { - if x, ok := x.GetTypeKind().(*Type_TypeParam); ok { - return x.TypeParam + if x != nil { + if x, ok := x.TypeKind.(*Type_TypeParam); ok { + return x.TypeParam + } } return "" } func (x *Type) GetType() *Type { - if x, ok := x.GetTypeKind().(*Type_Type); ok { - return x.Type + if x != nil { + if x, ok := x.TypeKind.(*Type_Type); ok { + return x.Type + } } return nil } func (x *Type) GetError() *emptypb.Empty { - if x, ok := x.GetTypeKind().(*Type_Error); ok { - return x.Error + if x != nil { + if x, ok := x.TypeKind.(*Type_Error); ok { + return x.Error + } } return nil } func (x *Type) GetAbstractType() *Type_AbstractType { - if x, ok := x.GetTypeKind().(*Type_AbstractType_); ok { - return x.AbstractType + if x != nil { + if x, ok := x.TypeKind.(*Type_AbstractType_); ok { + return x.AbstractType + } } return nil } @@ -450,25 +471,22 @@ func (*Type_Error) isType_TypeKind() {} func (*Type_AbstractType_) isType_TypeKind() {} type Decl struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Types that are assignable to DeclKind: + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Types that are valid to be assigned to DeclKind: // // *Decl_Ident // *Decl_Function - DeclKind isDecl_DeclKind `protobuf_oneof:"decl_kind"` + DeclKind isDecl_DeclKind `protobuf_oneof:"decl_kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Decl) Reset() { *x = Decl{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Decl) String() string { @@ -479,7 +497,7 @@ func (*Decl) ProtoMessage() {} func (x *Decl) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -501,23 +519,27 @@ func (x *Decl) GetName() string { return "" } -func (m *Decl) GetDeclKind() isDecl_DeclKind { - if m != nil { - return m.DeclKind +func (x *Decl) GetDeclKind() isDecl_DeclKind { + if x != nil { + return x.DeclKind } return nil } func (x *Decl) GetIdent() *Decl_IdentDecl { - if x, ok := x.GetDeclKind().(*Decl_Ident); ok { - return x.Ident + if x != nil { + if x, ok := x.DeclKind.(*Decl_Ident); ok { + return x.Ident + } } return nil } func (x *Decl) GetFunction() *Decl_FunctionDecl { - if x, ok := x.GetDeclKind().(*Decl_Function); ok { - return x.Function + if x != nil { + if x, ok := x.DeclKind.(*Decl_Function); ok { + return x.Function + } } return nil } @@ -539,22 +561,19 @@ func (*Decl_Ident) isDecl_DeclKind() {} func (*Decl_Function) isDecl_DeclKind() {} type Reference struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + OverloadId []string `protobuf:"bytes,3,rep,name=overload_id,json=overloadId,proto3" json:"overload_id,omitempty"` + Value *Constant `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - OverloadId []string `protobuf:"bytes,3,rep,name=overload_id,json=overloadId,proto3" json:"overload_id,omitempty"` - Value *Constant `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Reference) Reset() { *x = Reference{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Reference) String() string { @@ -565,7 +584,7 @@ func (*Reference) ProtoMessage() {} func (x *Reference) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -602,20 +621,17 @@ func (x *Reference) GetValue() *Constant { } type Type_ListType struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ElemType *Type `protobuf:"bytes,1,opt,name=elem_type,json=elemType,proto3" json:"elem_type,omitempty"` unknownFields protoimpl.UnknownFields - - ElemType *Type `protobuf:"bytes,1,opt,name=elem_type,json=elemType,proto3" json:"elem_type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Type_ListType) Reset() { *x = Type_ListType{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Type_ListType) String() string { @@ -626,7 +642,7 @@ func (*Type_ListType) ProtoMessage() {} func (x *Type_ListType) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -649,21 +665,18 @@ func (x *Type_ListType) GetElemType() *Type { } type Type_MapType struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + KeyType *Type `protobuf:"bytes,1,opt,name=key_type,json=keyType,proto3" json:"key_type,omitempty"` + ValueType *Type `protobuf:"bytes,2,opt,name=value_type,json=valueType,proto3" json:"value_type,omitempty"` unknownFields protoimpl.UnknownFields - - KeyType *Type `protobuf:"bytes,1,opt,name=key_type,json=keyType,proto3" json:"key_type,omitempty"` - ValueType *Type `protobuf:"bytes,2,opt,name=value_type,json=valueType,proto3" json:"value_type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Type_MapType) Reset() { *x = Type_MapType{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Type_MapType) String() string { @@ -674,7 +687,7 @@ func (*Type_MapType) ProtoMessage() {} func (x *Type_MapType) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -704,21 +717,18 @@ func (x *Type_MapType) GetValueType() *Type { } type Type_FunctionType struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ResultType *Type `protobuf:"bytes,1,opt,name=result_type,json=resultType,proto3" json:"result_type,omitempty"` + ArgTypes []*Type `protobuf:"bytes,2,rep,name=arg_types,json=argTypes,proto3" json:"arg_types,omitempty"` unknownFields protoimpl.UnknownFields - - ResultType *Type `protobuf:"bytes,1,opt,name=result_type,json=resultType,proto3" json:"result_type,omitempty"` - ArgTypes []*Type `protobuf:"bytes,2,rep,name=arg_types,json=argTypes,proto3" json:"arg_types,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Type_FunctionType) Reset() { *x = Type_FunctionType{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Type_FunctionType) String() string { @@ -729,7 +739,7 @@ func (*Type_FunctionType) ProtoMessage() {} func (x *Type_FunctionType) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -759,21 +769,18 @@ func (x *Type_FunctionType) GetArgTypes() []*Type { } type Type_AbstractType struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - ParameterTypes []*Type `protobuf:"bytes,2,rep,name=parameter_types,json=parameterTypes,proto3" json:"parameter_types,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + ParameterTypes []*Type `protobuf:"bytes,2,rep,name=parameter_types,json=parameterTypes,proto3" json:"parameter_types,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Type_AbstractType) Reset() { *x = Type_AbstractType{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Type_AbstractType) String() string { @@ -784,7 +791,7 @@ func (*Type_AbstractType) ProtoMessage() {} func (x *Type_AbstractType) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -814,22 +821,19 @@ func (x *Type_AbstractType) GetParameterTypes() []*Type { } type Decl_IdentDecl struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Type *Type `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Value *Constant `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + Doc string `protobuf:"bytes,3,opt,name=doc,proto3" json:"doc,omitempty"` unknownFields protoimpl.UnknownFields - - Type *Type `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - Value *Constant `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - Doc string `protobuf:"bytes,3,opt,name=doc,proto3" json:"doc,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Decl_IdentDecl) Reset() { *x = Decl_IdentDecl{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Decl_IdentDecl) String() string { @@ -840,7 +844,7 @@ func (*Decl_IdentDecl) ProtoMessage() {} func (x *Decl_IdentDecl) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -877,20 +881,18 @@ func (x *Decl_IdentDecl) GetDoc() string { } type Decl_FunctionDecl struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Overloads []*Decl_FunctionDecl_Overload `protobuf:"bytes,1,rep,name=overloads,proto3" json:"overloads,omitempty"` + Doc string `protobuf:"bytes,2,opt,name=doc,proto3" json:"doc,omitempty"` unknownFields protoimpl.UnknownFields - - Overloads []*Decl_FunctionDecl_Overload `protobuf:"bytes,1,rep,name=overloads,proto3" json:"overloads,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Decl_FunctionDecl) Reset() { *x = Decl_FunctionDecl{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Decl_FunctionDecl) String() string { @@ -901,7 +903,7 @@ func (*Decl_FunctionDecl) ProtoMessage() {} func (x *Decl_FunctionDecl) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -923,26 +925,30 @@ func (x *Decl_FunctionDecl) GetOverloads() []*Decl_FunctionDecl_Overload { return nil } -type Decl_FunctionDecl_Overload struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields +func (x *Decl_FunctionDecl) GetDoc() string { + if x != nil { + return x.Doc + } + return "" +} - OverloadId string `protobuf:"bytes,1,opt,name=overload_id,json=overloadId,proto3" json:"overload_id,omitempty"` - Params []*Type `protobuf:"bytes,2,rep,name=params,proto3" json:"params,omitempty"` - TypeParams []string `protobuf:"bytes,3,rep,name=type_params,json=typeParams,proto3" json:"type_params,omitempty"` - ResultType *Type `protobuf:"bytes,4,opt,name=result_type,json=resultType,proto3" json:"result_type,omitempty"` - IsInstanceFunction bool `protobuf:"varint,5,opt,name=is_instance_function,json=isInstanceFunction,proto3" json:"is_instance_function,omitempty"` - Doc string `protobuf:"bytes,6,opt,name=doc,proto3" json:"doc,omitempty"` +type Decl_FunctionDecl_Overload struct { + state protoimpl.MessageState `protogen:"open.v1"` + OverloadId string `protobuf:"bytes,1,opt,name=overload_id,json=overloadId,proto3" json:"overload_id,omitempty"` + Params []*Type `protobuf:"bytes,2,rep,name=params,proto3" json:"params,omitempty"` + TypeParams []string `protobuf:"bytes,3,rep,name=type_params,json=typeParams,proto3" json:"type_params,omitempty"` + ResultType *Type `protobuf:"bytes,4,opt,name=result_type,json=resultType,proto3" json:"result_type,omitempty"` + IsInstanceFunction bool `protobuf:"varint,5,opt,name=is_instance_function,json=isInstanceFunction,proto3" json:"is_instance_function,omitempty"` + Doc string `protobuf:"bytes,6,opt,name=doc,proto3" json:"doc,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Decl_FunctionDecl_Overload) Reset() { *x = Decl_FunctionDecl_Overload{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Decl_FunctionDecl_Overload) String() string { @@ -953,7 +959,7 @@ func (*Decl_FunctionDecl_Overload) ProtoMessage() {} func (x *Decl_FunctionDecl_Overload) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1012,185 +1018,113 @@ func (x *Decl_FunctionDecl_Overload) GetDoc() string { var File_cel_expr_checked_proto protoreflect.FileDescriptor -var file_cel_expr_checked_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, - 0x70, 0x72, 0x1a, 0x15, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x73, 0x79, 0x6e, - 0x74, 0x61, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xba, 0x03, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, - 0x45, 0x78, 0x70, 0x72, 0x12, 0x4c, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x45, 0x78, - 0x70, 0x72, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x4d, - 0x61, 0x70, 0x12, 0x3d, 0x0a, 0x08, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, - 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x74, 0x79, 0x70, 0x65, 0x4d, 0x61, - 0x70, 0x12, 0x35, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x70, 0x72, - 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x65, 0x78, 0x70, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x04, 0x65, - 0x78, 0x70, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x1a, - 0x54, 0x0a, 0x11, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, - 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4a, 0x0a, 0x0c, 0x54, 0x79, 0x70, 0x65, 0x4d, 0x61, 0x70, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0xe6, 0x09, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x03, 0x64, 0x79, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, - 0x00, 0x52, 0x03, 0x64, 0x79, 0x6e, 0x12, 0x30, 0x0a, 0x04, 0x6e, 0x75, 0x6c, 0x6c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x48, 0x00, 0x52, 0x04, 0x6e, 0x75, 0x6c, 0x6c, 0x12, 0x3c, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6d, - 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x50, 0x72, 0x69, 0x6d, - 0x69, 0x74, 0x69, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x09, 0x70, 0x72, 0x69, - 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, - 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, - 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x07, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x12, 0x3d, 0x0a, 0x0a, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x54, 0x79, 0x70, 0x65, 0x2e, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, - 0x70, 0x65, 0x48, 0x00, 0x52, 0x09, 0x77, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x12, - 0x36, 0x0a, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, - 0x70, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x08, 0x6c, - 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x61, 0x70, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, - 0x65, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x08, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, - 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x46, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x08, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, - 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0a, - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, - 0x48, 0x00, 0x52, 0x09, 0x74, 0x79, 0x70, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x24, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x12, 0x42, 0x0a, 0x0d, 0x61, 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x41, 0x62, 0x73, 0x74, 0x72, - 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x62, 0x73, 0x74, 0x72, - 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x37, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x09, 0x65, 0x6c, 0x65, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, - 0x1a, 0x63, 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x08, 0x6b, - 0x65, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x6b, - 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x6c, 0x0a, 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x61, 0x72, 0x67, 0x54, 0x79, - 0x70, 0x65, 0x73, 0x1a, 0x5b, 0x0a, 0x0c, 0x41, 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x0e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, - 0x22, 0x73, 0x0a, 0x0d, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x49, 0x4d, 0x49, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x49, - 0x4e, 0x54, 0x36, 0x34, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, - 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x0a, - 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x59, - 0x54, 0x45, 0x53, 0x10, 0x06, 0x22, 0x56, 0x0a, 0x0d, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, - 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x57, 0x45, 0x4c, 0x4c, 0x5f, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x01, - 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x10, 0x02, 0x12, - 0x0c, 0x0a, 0x08, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x42, 0x0b, 0x0a, - 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0xc2, 0x04, 0x0a, 0x04, 0x44, - 0x65, 0x63, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x44, 0x65, 0x63, 0x6c, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x63, 0x6c, - 0x48, 0x00, 0x52, 0x05, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x08, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x44, 0x65, 0x63, 0x6c, 0x2e, 0x46, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x63, 0x6c, 0x48, 0x00, 0x52, 0x08, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x6b, 0x0a, 0x09, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x63, - 0x6c, 0x12, 0x22, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x10, 0x0a, 0x03, 0x64, 0x6f, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x6f, - 0x63, 0x1a, 0xbe, 0x02, 0x0a, 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, - 0x63, 0x6c, 0x12, 0x42, 0x0a, 0x09, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, - 0x2e, 0x44, 0x65, 0x63, 0x6c, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, - 0x63, 0x6c, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x09, 0x6f, 0x76, 0x65, - 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x1a, 0xe9, 0x01, 0x0a, 0x08, 0x4f, 0x76, 0x65, 0x72, 0x6c, - 0x6f, 0x61, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, - 0x61, 0x64, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1f, 0x0a, 0x0b, - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2f, 0x0a, - 0x0b, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, - 0x0a, 0x14, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x73, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x10, 0x0a, 0x03, 0x64, 0x6f, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, - 0x6f, 0x63, 0x42, 0x0b, 0x0a, 0x09, 0x64, 0x65, 0x63, 0x6c, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x22, - 0x6a, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x49, - 0x64, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2c, 0x0a, 0x0c, 0x64, - 0x65, 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x09, 0x44, 0x65, 0x63, - 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, 0x65, - 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} +const file_cel_expr_checked_proto_rawDesc = "" + + "\n" + + "\x16cel/expr/checked.proto\x12\bcel.expr\x1a\x15cel/expr/syntax.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\"\xba\x03\n" + + "\vCheckedExpr\x12L\n" + + "\rreference_map\x18\x02 \x03(\v2'.cel.expr.CheckedExpr.ReferenceMapEntryR\freferenceMap\x12=\n" + + "\btype_map\x18\x03 \x03(\v2\".cel.expr.CheckedExpr.TypeMapEntryR\atypeMap\x125\n" + + "\vsource_info\x18\x05 \x01(\v2\x14.cel.expr.SourceInfoR\n" + + "sourceInfo\x12!\n" + + "\fexpr_version\x18\x06 \x01(\tR\vexprVersion\x12\"\n" + + "\x04expr\x18\x04 \x01(\v2\x0e.cel.expr.ExprR\x04expr\x1aT\n" + + "\x11ReferenceMapEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\x03R\x03key\x12)\n" + + "\x05value\x18\x02 \x01(\v2\x13.cel.expr.ReferenceR\x05value:\x028\x01\x1aJ\n" + + "\fTypeMapEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\x03R\x03key\x12$\n" + + "\x05value\x18\x02 \x01(\v2\x0e.cel.expr.TypeR\x05value:\x028\x01\"\xe6\t\n" + + "\x04Type\x12*\n" + + "\x03dyn\x18\x01 \x01(\v2\x16.google.protobuf.EmptyH\x00R\x03dyn\x120\n" + + "\x04null\x18\x02 \x01(\x0e2\x1a.google.protobuf.NullValueH\x00R\x04null\x12<\n" + + "\tprimitive\x18\x03 \x01(\x0e2\x1c.cel.expr.Type.PrimitiveTypeH\x00R\tprimitive\x128\n" + + "\awrapper\x18\x04 \x01(\x0e2\x1c.cel.expr.Type.PrimitiveTypeH\x00R\awrapper\x12=\n" + + "\n" + + "well_known\x18\x05 \x01(\x0e2\x1c.cel.expr.Type.WellKnownTypeH\x00R\twellKnown\x126\n" + + "\tlist_type\x18\x06 \x01(\v2\x17.cel.expr.Type.ListTypeH\x00R\blistType\x123\n" + + "\bmap_type\x18\a \x01(\v2\x16.cel.expr.Type.MapTypeH\x00R\amapType\x129\n" + + "\bfunction\x18\b \x01(\v2\x1b.cel.expr.Type.FunctionTypeH\x00R\bfunction\x12#\n" + + "\fmessage_type\x18\t \x01(\tH\x00R\vmessageType\x12\x1f\n" + + "\n" + + "type_param\x18\n" + + " \x01(\tH\x00R\ttypeParam\x12$\n" + + "\x04type\x18\v \x01(\v2\x0e.cel.expr.TypeH\x00R\x04type\x12.\n" + + "\x05error\x18\f \x01(\v2\x16.google.protobuf.EmptyH\x00R\x05error\x12B\n" + + "\rabstract_type\x18\x0e \x01(\v2\x1b.cel.expr.Type.AbstractTypeH\x00R\fabstractType\x1a7\n" + + "\bListType\x12+\n" + + "\telem_type\x18\x01 \x01(\v2\x0e.cel.expr.TypeR\belemType\x1ac\n" + + "\aMapType\x12)\n" + + "\bkey_type\x18\x01 \x01(\v2\x0e.cel.expr.TypeR\akeyType\x12-\n" + + "\n" + + "value_type\x18\x02 \x01(\v2\x0e.cel.expr.TypeR\tvalueType\x1al\n" + + "\fFunctionType\x12/\n" + + "\vresult_type\x18\x01 \x01(\v2\x0e.cel.expr.TypeR\n" + + "resultType\x12+\n" + + "\targ_types\x18\x02 \x03(\v2\x0e.cel.expr.TypeR\bargTypes\x1a[\n" + + "\fAbstractType\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x127\n" + + "\x0fparameter_types\x18\x02 \x03(\v2\x0e.cel.expr.TypeR\x0eparameterTypes\"s\n" + + "\rPrimitiveType\x12\x1e\n" + + "\x1aPRIMITIVE_TYPE_UNSPECIFIED\x10\x00\x12\b\n" + + "\x04BOOL\x10\x01\x12\t\n" + + "\x05INT64\x10\x02\x12\n" + + "\n" + + "\x06UINT64\x10\x03\x12\n" + + "\n" + + "\x06DOUBLE\x10\x04\x12\n" + + "\n" + + "\x06STRING\x10\x05\x12\t\n" + + "\x05BYTES\x10\x06\"V\n" + + "\rWellKnownType\x12\x1f\n" + + "\x1bWELL_KNOWN_TYPE_UNSPECIFIED\x10\x00\x12\a\n" + + "\x03ANY\x10\x01\x12\r\n" + + "\tTIMESTAMP\x10\x02\x12\f\n" + + "\bDURATION\x10\x03B\v\n" + + "\ttype_kind\"\xd4\x04\n" + + "\x04Decl\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x120\n" + + "\x05ident\x18\x02 \x01(\v2\x18.cel.expr.Decl.IdentDeclH\x00R\x05ident\x129\n" + + "\bfunction\x18\x03 \x01(\v2\x1b.cel.expr.Decl.FunctionDeclH\x00R\bfunction\x1ak\n" + + "\tIdentDecl\x12\"\n" + + "\x04type\x18\x01 \x01(\v2\x0e.cel.expr.TypeR\x04type\x12(\n" + + "\x05value\x18\x02 \x01(\v2\x12.cel.expr.ConstantR\x05value\x12\x10\n" + + "\x03doc\x18\x03 \x01(\tR\x03doc\x1a\xd0\x02\n" + + "\fFunctionDecl\x12B\n" + + "\toverloads\x18\x01 \x03(\v2$.cel.expr.Decl.FunctionDecl.OverloadR\toverloads\x12\x10\n" + + "\x03doc\x18\x02 \x01(\tR\x03doc\x1a\xe9\x01\n" + + "\bOverload\x12\x1f\n" + + "\voverload_id\x18\x01 \x01(\tR\n" + + "overloadId\x12&\n" + + "\x06params\x18\x02 \x03(\v2\x0e.cel.expr.TypeR\x06params\x12\x1f\n" + + "\vtype_params\x18\x03 \x03(\tR\n" + + "typeParams\x12/\n" + + "\vresult_type\x18\x04 \x01(\v2\x0e.cel.expr.TypeR\n" + + "resultType\x120\n" + + "\x14is_instance_function\x18\x05 \x01(\bR\x12isInstanceFunction\x12\x10\n" + + "\x03doc\x18\x06 \x01(\tR\x03docB\v\n" + + "\tdecl_kind\"j\n" + + "\tReference\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1f\n" + + "\voverload_id\x18\x03 \x03(\tR\n" + + "overloadId\x12(\n" + + "\x05value\x18\x04 \x01(\v2\x12.cel.expr.ConstantR\x05valueB,\n" + + "\fdev.cel.exprB\tDeclProtoP\x01Z\fcel.dev/expr\xf8\x01\x01b\x06proto3" var ( file_cel_expr_checked_proto_rawDescOnce sync.Once - file_cel_expr_checked_proto_rawDescData = file_cel_expr_checked_proto_rawDesc + file_cel_expr_checked_proto_rawDescData []byte ) func file_cel_expr_checked_proto_rawDescGZIP() []byte { file_cel_expr_checked_proto_rawDescOnce.Do(func() { - file_cel_expr_checked_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_checked_proto_rawDescData) + file_cel_expr_checked_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cel_expr_checked_proto_rawDesc), len(file_cel_expr_checked_proto_rawDesc))) }) return file_cel_expr_checked_proto_rawDescData } var file_cel_expr_checked_proto_enumTypes = make([]protoimpl.EnumInfo, 2) var file_cel_expr_checked_proto_msgTypes = make([]protoimpl.MessageInfo, 13) -var file_cel_expr_checked_proto_goTypes = []interface{}{ +var file_cel_expr_checked_proto_goTypes = []any{ (Type_PrimitiveType)(0), // 0: cel.expr.Type.PrimitiveType (Type_WellKnownType)(0), // 1: cel.expr.Type.WellKnownType (*CheckedExpr)(nil), // 2: cel.expr.CheckedExpr @@ -1257,141 +1191,7 @@ func file_cel_expr_checked_proto_init() { return } file_cel_expr_syntax_proto_init() - if !protoimpl.UnsafeEnabled { - file_cel_expr_checked_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckedExpr); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Type); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Decl); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Reference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Type_ListType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Type_MapType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Type_FunctionType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Type_AbstractType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Decl_IdentDecl); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Decl_FunctionDecl); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Decl_FunctionDecl_Overload); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_cel_expr_checked_proto_msgTypes[1].OneofWrappers = []interface{}{ + file_cel_expr_checked_proto_msgTypes[1].OneofWrappers = []any{ (*Type_Dyn)(nil), (*Type_Null)(nil), (*Type_Primitive)(nil), @@ -1406,7 +1206,7 @@ func file_cel_expr_checked_proto_init() { (*Type_Error)(nil), (*Type_AbstractType_)(nil), } - file_cel_expr_checked_proto_msgTypes[2].OneofWrappers = []interface{}{ + file_cel_expr_checked_proto_msgTypes[2].OneofWrappers = []any{ (*Decl_Ident)(nil), (*Decl_Function)(nil), } @@ -1414,7 +1214,7 @@ func file_cel_expr_checked_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cel_expr_checked_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_cel_expr_checked_proto_rawDesc), len(file_cel_expr_checked_proto_rawDesc)), NumEnums: 2, NumMessages: 13, NumExtensions: 0, @@ -1426,7 +1226,6 @@ func file_cel_expr_checked_proto_init() { MessageInfos: file_cel_expr_checked_proto_msgTypes, }.Build() File_cel_expr_checked_proto = out.File - file_cel_expr_checked_proto_rawDesc = nil file_cel_expr_checked_proto_goTypes = nil file_cel_expr_checked_proto_depIdxs = nil } diff --git a/plugins/traefik/vendor/cel.dev/expr/cloudbuild.yaml b/plugins/traefik/vendor/cel.dev/expr/cloudbuild.yaml index c40881f12..e3e533a04 100644 --- a/plugins/traefik/vendor/cel.dev/expr/cloudbuild.yaml +++ b/plugins/traefik/vendor/cel.dev/expr/cloudbuild.yaml @@ -1,5 +1,5 @@ steps: -- name: 'gcr.io/cloud-builders/bazel:7.0.1' +- name: 'gcr.io/cloud-builders/bazel:7.3.2' entrypoint: bazel args: ['build', '...'] id: bazel-build diff --git a/plugins/traefik/vendor/cel.dev/expr/eval.pb.go b/plugins/traefik/vendor/cel.dev/expr/eval.pb.go index 8f651f9cc..83acb8935 100644 --- a/plugins/traefik/vendor/cel.dev/expr/eval.pb.go +++ b/plugins/traefik/vendor/cel.dev/expr/eval.pb.go @@ -1,17 +1,18 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.5 +// protoc-gen-go v1.36.10 +// protoc v5.27.1 // source: cel/expr/eval.proto package expr import ( - status "google.golang.org/genproto/googleapis/rpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -22,21 +23,18 @@ const ( ) type EvalState struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Values []*ExprValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + Results []*EvalState_Result `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"` unknownFields protoimpl.UnknownFields - - Values []*ExprValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` - Results []*EvalState_Result `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"` + sizeCache protoimpl.SizeCache } func (x *EvalState) Reset() { *x = EvalState{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_eval_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *EvalState) String() string { @@ -47,7 +45,7 @@ func (*EvalState) ProtoMessage() {} func (x *EvalState) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_eval_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -77,25 +75,22 @@ func (x *EvalState) GetResults() []*EvalState_Result { } type ExprValue struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Kind: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Kind: // // *ExprValue_Value // *ExprValue_Error // *ExprValue_Unknown - Kind isExprValue_Kind `protobuf_oneof:"kind"` + Kind isExprValue_Kind `protobuf_oneof:"kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ExprValue) Reset() { *x = ExprValue{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_eval_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ExprValue) String() string { @@ -106,7 +101,7 @@ func (*ExprValue) ProtoMessage() {} func (x *ExprValue) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_eval_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -121,30 +116,36 @@ func (*ExprValue) Descriptor() ([]byte, []int) { return file_cel_expr_eval_proto_rawDescGZIP(), []int{1} } -func (m *ExprValue) GetKind() isExprValue_Kind { - if m != nil { - return m.Kind +func (x *ExprValue) GetKind() isExprValue_Kind { + if x != nil { + return x.Kind } return nil } func (x *ExprValue) GetValue() *Value { - if x, ok := x.GetKind().(*ExprValue_Value); ok { - return x.Value + if x != nil { + if x, ok := x.Kind.(*ExprValue_Value); ok { + return x.Value + } } return nil } func (x *ExprValue) GetError() *ErrorSet { - if x, ok := x.GetKind().(*ExprValue_Error); ok { - return x.Error + if x != nil { + if x, ok := x.Kind.(*ExprValue_Error); ok { + return x.Error + } } return nil } func (x *ExprValue) GetUnknown() *UnknownSet { - if x, ok := x.GetKind().(*ExprValue_Unknown); ok { - return x.Unknown + if x != nil { + if x, ok := x.Kind.(*ExprValue_Unknown); ok { + return x.Unknown + } } return nil } @@ -172,20 +173,17 @@ func (*ExprValue_Error) isExprValue_Kind() {} func (*ExprValue_Unknown) isExprValue_Kind() {} type ErrorSet struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Errors []*Status `protobuf:"bytes,1,rep,name=errors,proto3" json:"errors,omitempty"` unknownFields protoimpl.UnknownFields - - Errors []*status.Status `protobuf:"bytes,1,rep,name=errors,proto3" json:"errors,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ErrorSet) Reset() { *x = ErrorSet{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_eval_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ErrorSet) String() string { @@ -196,7 +194,7 @@ func (*ErrorSet) ProtoMessage() {} func (x *ErrorSet) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_eval_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -211,28 +209,85 @@ func (*ErrorSet) Descriptor() ([]byte, []int) { return file_cel_expr_eval_proto_rawDescGZIP(), []int{2} } -func (x *ErrorSet) GetErrors() []*status.Status { +func (x *ErrorSet) GetErrors() []*Status { if x != nil { return x.Errors } return nil } -type UnknownSet struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +type Status struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Details []*anypb.Any `protobuf:"bytes,3,rep,name=details,proto3" json:"details,omitempty"` unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} - Exprs []int64 `protobuf:"varint,1,rep,packed,name=exprs,proto3" json:"exprs,omitempty"` +func (x *Status) Reset() { + *x = Status{} + mi := &file_cel_expr_eval_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *UnknownSet) Reset() { - *x = UnknownSet{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[3] +func (x *Status) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Status) ProtoMessage() {} + +func (x *Status) ProtoReflect() protoreflect.Message { + mi := &file_cel_expr_eval_proto_msgTypes[3] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Status.ProtoReflect.Descriptor instead. +func (*Status) Descriptor() ([]byte, []int) { + return file_cel_expr_eval_proto_rawDescGZIP(), []int{3} +} + +func (x *Status) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *Status) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *Status) GetDetails() []*anypb.Any { + if x != nil { + return x.Details } + return nil +} + +type UnknownSet struct { + state protoimpl.MessageState `protogen:"open.v1"` + Exprs []int64 `protobuf:"varint,1,rep,packed,name=exprs,proto3" json:"exprs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UnknownSet) Reset() { + *x = UnknownSet{} + mi := &file_cel_expr_eval_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UnknownSet) String() string { @@ -242,8 +297,8 @@ func (x *UnknownSet) String() string { func (*UnknownSet) ProtoMessage() {} func (x *UnknownSet) ProtoReflect() protoreflect.Message { - mi := &file_cel_expr_eval_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_cel_expr_eval_proto_msgTypes[4] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -255,7 +310,7 @@ func (x *UnknownSet) ProtoReflect() protoreflect.Message { // Deprecated: Use UnknownSet.ProtoReflect.Descriptor instead. func (*UnknownSet) Descriptor() ([]byte, []int) { - return file_cel_expr_eval_proto_rawDescGZIP(), []int{3} + return file_cel_expr_eval_proto_rawDescGZIP(), []int{4} } func (x *UnknownSet) GetExprs() []int64 { @@ -266,21 +321,18 @@ func (x *UnknownSet) GetExprs() []int64 { } type EvalState_Result struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Expr int64 `protobuf:"varint,1,opt,name=expr,proto3" json:"expr,omitempty"` + Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields - - Expr int64 `protobuf:"varint,1,opt,name=expr,proto3" json:"expr,omitempty"` - Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` + sizeCache protoimpl.SizeCache } func (x *EvalState_Result) Reset() { *x = EvalState_Result{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_eval_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *EvalState_Result) String() string { @@ -290,8 +342,8 @@ func (x *EvalState_Result) String() string { func (*EvalState_Result) ProtoMessage() {} func (x *EvalState_Result) ProtoReflect() protoreflect.Message { - mi := &file_cel_expr_eval_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_cel_expr_eval_proto_msgTypes[5] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -322,78 +374,67 @@ func (x *EvalState_Result) GetValue() int64 { var File_cel_expr_eval_proto protoreflect.FileDescriptor -var file_cel_expr_eval_proto_rawDesc = []byte{ - 0x0a, 0x13, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x65, 0x76, 0x61, 0x6c, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x1a, - 0x14, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x72, 0x70, - 0x63, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa2, - 0x01, 0x0a, 0x09, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2b, 0x0a, 0x06, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, - 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, - 0x32, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x30, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, - 0x70, 0x72, 0x2e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, - 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, - 0x22, 0x36, 0x0a, 0x08, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x12, 0x2a, 0x0a, 0x06, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x22, 0x0a, 0x0a, 0x55, 0x6e, 0x6b, 0x6e, - 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x70, 0x72, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x05, 0x65, 0x78, 0x70, 0x72, 0x73, 0x42, 0x2c, 0x0a, 0x0c, - 0x64, 0x65, 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x09, 0x45, 0x76, - 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, - 0x65, 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} +const file_cel_expr_eval_proto_rawDesc = "" + + "\n" + + "\x13cel/expr/eval.proto\x12\bcel.expr\x1a\x19google/protobuf/any.proto\x1a\x14cel/expr/value.proto\"\xa2\x01\n" + + "\tEvalState\x12+\n" + + "\x06values\x18\x01 \x03(\v2\x13.cel.expr.ExprValueR\x06values\x124\n" + + "\aresults\x18\x03 \x03(\v2\x1a.cel.expr.EvalState.ResultR\aresults\x1a2\n" + + "\x06Result\x12\x12\n" + + "\x04expr\x18\x01 \x01(\x03R\x04expr\x12\x14\n" + + "\x05value\x18\x02 \x01(\x03R\x05value\"\x9a\x01\n" + + "\tExprValue\x12'\n" + + "\x05value\x18\x01 \x01(\v2\x0f.cel.expr.ValueH\x00R\x05value\x12*\n" + + "\x05error\x18\x02 \x01(\v2\x12.cel.expr.ErrorSetH\x00R\x05error\x120\n" + + "\aunknown\x18\x03 \x01(\v2\x14.cel.expr.UnknownSetH\x00R\aunknownB\x06\n" + + "\x04kind\"4\n" + + "\bErrorSet\x12(\n" + + "\x06errors\x18\x01 \x03(\v2\x10.cel.expr.StatusR\x06errors\"f\n" + + "\x06Status\x12\x12\n" + + "\x04code\x18\x01 \x01(\x05R\x04code\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessage\x12.\n" + + "\adetails\x18\x03 \x03(\v2\x14.google.protobuf.AnyR\adetails\"\"\n" + + "\n" + + "UnknownSet\x12\x14\n" + + "\x05exprs\x18\x01 \x03(\x03R\x05exprsB,\n" + + "\fdev.cel.exprB\tEvalProtoP\x01Z\fcel.dev/expr\xf8\x01\x01b\x06proto3" var ( file_cel_expr_eval_proto_rawDescOnce sync.Once - file_cel_expr_eval_proto_rawDescData = file_cel_expr_eval_proto_rawDesc + file_cel_expr_eval_proto_rawDescData []byte ) func file_cel_expr_eval_proto_rawDescGZIP() []byte { file_cel_expr_eval_proto_rawDescOnce.Do(func() { - file_cel_expr_eval_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_eval_proto_rawDescData) + file_cel_expr_eval_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cel_expr_eval_proto_rawDesc), len(file_cel_expr_eval_proto_rawDesc))) }) return file_cel_expr_eval_proto_rawDescData } -var file_cel_expr_eval_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_cel_expr_eval_proto_goTypes = []interface{}{ +var file_cel_expr_eval_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_cel_expr_eval_proto_goTypes = []any{ (*EvalState)(nil), // 0: cel.expr.EvalState (*ExprValue)(nil), // 1: cel.expr.ExprValue (*ErrorSet)(nil), // 2: cel.expr.ErrorSet - (*UnknownSet)(nil), // 3: cel.expr.UnknownSet - (*EvalState_Result)(nil), // 4: cel.expr.EvalState.Result - (*Value)(nil), // 5: cel.expr.Value - (*status.Status)(nil), // 6: google.rpc.Status + (*Status)(nil), // 3: cel.expr.Status + (*UnknownSet)(nil), // 4: cel.expr.UnknownSet + (*EvalState_Result)(nil), // 5: cel.expr.EvalState.Result + (*Value)(nil), // 6: cel.expr.Value + (*anypb.Any)(nil), // 7: google.protobuf.Any } var file_cel_expr_eval_proto_depIdxs = []int32{ 1, // 0: cel.expr.EvalState.values:type_name -> cel.expr.ExprValue - 4, // 1: cel.expr.EvalState.results:type_name -> cel.expr.EvalState.Result - 5, // 2: cel.expr.ExprValue.value:type_name -> cel.expr.Value + 5, // 1: cel.expr.EvalState.results:type_name -> cel.expr.EvalState.Result + 6, // 2: cel.expr.ExprValue.value:type_name -> cel.expr.Value 2, // 3: cel.expr.ExprValue.error:type_name -> cel.expr.ErrorSet - 3, // 4: cel.expr.ExprValue.unknown:type_name -> cel.expr.UnknownSet - 6, // 5: cel.expr.ErrorSet.errors:type_name -> google.rpc.Status - 6, // [6:6] is the sub-list for method output_type - 6, // [6:6] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 4, // 4: cel.expr.ExprValue.unknown:type_name -> cel.expr.UnknownSet + 3, // 5: cel.expr.ErrorSet.errors:type_name -> cel.expr.Status + 7, // 6: cel.expr.Status.details:type_name -> google.protobuf.Any + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_cel_expr_eval_proto_init() } @@ -402,69 +443,7 @@ func file_cel_expr_eval_proto_init() { return } file_cel_expr_value_proto_init() - if !protoimpl.UnsafeEnabled { - file_cel_expr_eval_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EvalState); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_eval_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExprValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_eval_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ErrorSet); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_eval_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnknownSet); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_eval_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EvalState_Result); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_cel_expr_eval_proto_msgTypes[1].OneofWrappers = []interface{}{ + file_cel_expr_eval_proto_msgTypes[1].OneofWrappers = []any{ (*ExprValue_Value)(nil), (*ExprValue_Error)(nil), (*ExprValue_Unknown)(nil), @@ -473,9 +452,9 @@ func file_cel_expr_eval_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cel_expr_eval_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_cel_expr_eval_proto_rawDesc), len(file_cel_expr_eval_proto_rawDesc)), NumEnums: 0, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, @@ -484,7 +463,6 @@ func file_cel_expr_eval_proto_init() { MessageInfos: file_cel_expr_eval_proto_msgTypes, }.Build() File_cel_expr_eval_proto = out.File - file_cel_expr_eval_proto_rawDesc = nil file_cel_expr_eval_proto_goTypes = nil file_cel_expr_eval_proto_depIdxs = nil } diff --git a/plugins/traefik/vendor/cel.dev/expr/explain.pb.go b/plugins/traefik/vendor/cel.dev/expr/explain.pb.go index 79fd5443b..423993397 100644 --- a/plugins/traefik/vendor/cel.dev/expr/explain.pb.go +++ b/plugins/traefik/vendor/cel.dev/expr/explain.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.5 +// protoc-gen-go v1.36.10 +// protoc v5.27.1 // source: cel/expr/explain.proto package expr @@ -11,6 +11,7 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -20,23 +21,20 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in cel/expr/explain.proto. type Explain struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + ExprSteps []*Explain_ExprStep `protobuf:"bytes,2,rep,name=expr_steps,json=exprSteps,proto3" json:"expr_steps,omitempty"` unknownFields protoimpl.UnknownFields - - Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` - ExprSteps []*Explain_ExprStep `protobuf:"bytes,2,rep,name=expr_steps,json=exprSteps,proto3" json:"expr_steps,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Explain) Reset() { *x = Explain{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_explain_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_explain_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Explain) String() string { @@ -47,7 +45,7 @@ func (*Explain) ProtoMessage() {} func (x *Explain) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_explain_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -77,21 +75,18 @@ func (x *Explain) GetExprSteps() []*Explain_ExprStep { } type Explain_ExprStep struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + ValueIndex int32 `protobuf:"varint,2,opt,name=value_index,json=valueIndex,proto3" json:"value_index,omitempty"` unknownFields protoimpl.UnknownFields - - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - ValueIndex int32 `protobuf:"varint,2,opt,name=value_index,json=valueIndex,proto3" json:"value_index,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Explain_ExprStep) Reset() { *x = Explain_ExprStep{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_explain_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_explain_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Explain_ExprStep) String() string { @@ -102,7 +97,7 @@ func (*Explain_ExprStep) ProtoMessage() {} func (x *Explain_ExprStep) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_explain_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -133,42 +128,33 @@ func (x *Explain_ExprStep) GetValueIndex() int32 { var File_cel_expr_explain_proto protoreflect.FileDescriptor -var file_cel_expr_explain_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x65, 0x78, 0x70, 0x6c, 0x61, - 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, - 0x70, 0x72, 0x1a, 0x14, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xae, 0x01, 0x0a, 0x07, 0x45, 0x78, 0x70, - 0x6c, 0x61, 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x39, 0x0a, - 0x0a, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, - 0x6c, 0x61, 0x69, 0x6e, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x53, 0x74, 0x65, 0x70, 0x52, 0x09, 0x65, - 0x78, 0x70, 0x72, 0x53, 0x74, 0x65, 0x70, 0x73, 0x1a, 0x3b, 0x0a, 0x08, 0x45, 0x78, 0x70, 0x72, - 0x53, 0x74, 0x65, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x69, 0x6e, - 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x02, 0x18, 0x01, 0x42, 0x2f, 0x0a, 0x0c, 0x64, 0x65, 0x76, - 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0c, 0x45, 0x78, 0x70, 0x6c, 0x61, - 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, - 0x65, 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} +const file_cel_expr_explain_proto_rawDesc = "" + + "\n" + + "\x16cel/expr/explain.proto\x12\bcel.expr\x1a\x14cel/expr/value.proto\"\xae\x01\n" + + "\aExplain\x12'\n" + + "\x06values\x18\x01 \x03(\v2\x0f.cel.expr.ValueR\x06values\x129\n" + + "\n" + + "expr_steps\x18\x02 \x03(\v2\x1a.cel.expr.Explain.ExprStepR\texprSteps\x1a;\n" + + "\bExprStep\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x1f\n" + + "\vvalue_index\x18\x02 \x01(\x05R\n" + + "valueIndex:\x02\x18\x01B/\n" + + "\fdev.cel.exprB\fExplainProtoP\x01Z\fcel.dev/expr\xf8\x01\x01b\x06proto3" var ( file_cel_expr_explain_proto_rawDescOnce sync.Once - file_cel_expr_explain_proto_rawDescData = file_cel_expr_explain_proto_rawDesc + file_cel_expr_explain_proto_rawDescData []byte ) func file_cel_expr_explain_proto_rawDescGZIP() []byte { file_cel_expr_explain_proto_rawDescOnce.Do(func() { - file_cel_expr_explain_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_explain_proto_rawDescData) + file_cel_expr_explain_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cel_expr_explain_proto_rawDesc), len(file_cel_expr_explain_proto_rawDesc))) }) return file_cel_expr_explain_proto_rawDescData } var file_cel_expr_explain_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_cel_expr_explain_proto_goTypes = []interface{}{ +var file_cel_expr_explain_proto_goTypes = []any{ (*Explain)(nil), // 0: cel.expr.Explain (*Explain_ExprStep)(nil), // 1: cel.expr.Explain.ExprStep (*Value)(nil), // 2: cel.expr.Value @@ -189,37 +175,11 @@ func file_cel_expr_explain_proto_init() { return } file_cel_expr_value_proto_init() - if !protoimpl.UnsafeEnabled { - file_cel_expr_explain_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Explain); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_explain_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Explain_ExprStep); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cel_expr_explain_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_cel_expr_explain_proto_rawDesc), len(file_cel_expr_explain_proto_rawDesc)), NumEnums: 0, NumMessages: 2, NumExtensions: 0, @@ -230,7 +190,6 @@ func file_cel_expr_explain_proto_init() { MessageInfos: file_cel_expr_explain_proto_msgTypes, }.Build() File_cel_expr_explain_proto = out.File - file_cel_expr_explain_proto_rawDesc = nil file_cel_expr_explain_proto_goTypes = nil file_cel_expr_explain_proto_depIdxs = nil } diff --git a/plugins/traefik/vendor/cel.dev/expr/syntax.pb.go b/plugins/traefik/vendor/cel.dev/expr/syntax.pb.go index 48a952872..72d19b20d 100644 --- a/plugins/traefik/vendor/cel.dev/expr/syntax.pb.go +++ b/plugins/traefik/vendor/cel.dev/expr/syntax.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.5 +// protoc-gen-go v1.36.10 +// protoc v5.27.1 // source: cel/expr/syntax.proto package expr @@ -14,6 +14,7 @@ import ( timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -76,21 +77,18 @@ func (SourceInfo_Extension_Component) EnumDescriptor() ([]byte, []int) { } type ParsedExpr struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Expr *Expr `protobuf:"bytes,2,opt,name=expr,proto3" json:"expr,omitempty"` + SourceInfo *SourceInfo `protobuf:"bytes,3,opt,name=source_info,json=sourceInfo,proto3" json:"source_info,omitempty"` unknownFields protoimpl.UnknownFields - - Expr *Expr `protobuf:"bytes,2,opt,name=expr,proto3" json:"expr,omitempty"` - SourceInfo *SourceInfo `protobuf:"bytes,3,opt,name=source_info,json=sourceInfo,proto3" json:"source_info,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ParsedExpr) Reset() { *x = ParsedExpr{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ParsedExpr) String() string { @@ -101,7 +99,7 @@ func (*ParsedExpr) ProtoMessage() {} func (x *ParsedExpr) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -131,12 +129,9 @@ func (x *ParsedExpr) GetSourceInfo() *SourceInfo { } type Expr struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id int64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` - // Types that are assignable to ExprKind: + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` + // Types that are valid to be assigned to ExprKind: // // *Expr_ConstExpr // *Expr_IdentExpr @@ -145,16 +140,16 @@ type Expr struct { // *Expr_ListExpr // *Expr_StructExpr // *Expr_ComprehensionExpr - ExprKind isExpr_ExprKind `protobuf_oneof:"expr_kind"` + ExprKind isExpr_ExprKind `protobuf_oneof:"expr_kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Expr) Reset() { *x = Expr{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr) String() string { @@ -165,7 +160,7 @@ func (*Expr) ProtoMessage() {} func (x *Expr) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -187,58 +182,72 @@ func (x *Expr) GetId() int64 { return 0 } -func (m *Expr) GetExprKind() isExpr_ExprKind { - if m != nil { - return m.ExprKind +func (x *Expr) GetExprKind() isExpr_ExprKind { + if x != nil { + return x.ExprKind } return nil } func (x *Expr) GetConstExpr() *Constant { - if x, ok := x.GetExprKind().(*Expr_ConstExpr); ok { - return x.ConstExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_ConstExpr); ok { + return x.ConstExpr + } } return nil } func (x *Expr) GetIdentExpr() *Expr_Ident { - if x, ok := x.GetExprKind().(*Expr_IdentExpr); ok { - return x.IdentExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_IdentExpr); ok { + return x.IdentExpr + } } return nil } func (x *Expr) GetSelectExpr() *Expr_Select { - if x, ok := x.GetExprKind().(*Expr_SelectExpr); ok { - return x.SelectExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_SelectExpr); ok { + return x.SelectExpr + } } return nil } func (x *Expr) GetCallExpr() *Expr_Call { - if x, ok := x.GetExprKind().(*Expr_CallExpr); ok { - return x.CallExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_CallExpr); ok { + return x.CallExpr + } } return nil } func (x *Expr) GetListExpr() *Expr_CreateList { - if x, ok := x.GetExprKind().(*Expr_ListExpr); ok { - return x.ListExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_ListExpr); ok { + return x.ListExpr + } } return nil } func (x *Expr) GetStructExpr() *Expr_CreateStruct { - if x, ok := x.GetExprKind().(*Expr_StructExpr); ok { - return x.StructExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_StructExpr); ok { + return x.StructExpr + } } return nil } func (x *Expr) GetComprehensionExpr() *Expr_Comprehension { - if x, ok := x.GetExprKind().(*Expr_ComprehensionExpr); ok { - return x.ComprehensionExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_ComprehensionExpr); ok { + return x.ComprehensionExpr + } } return nil } @@ -290,11 +299,8 @@ func (*Expr_StructExpr) isExpr_ExprKind() {} func (*Expr_ComprehensionExpr) isExpr_ExprKind() {} type Constant struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to ConstantKind: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to ConstantKind: // // *Constant_NullValue // *Constant_BoolValue @@ -305,16 +311,16 @@ type Constant struct { // *Constant_BytesValue // *Constant_DurationValue // *Constant_TimestampValue - ConstantKind isConstant_ConstantKind `protobuf_oneof:"constant_kind"` + ConstantKind isConstant_ConstantKind `protobuf_oneof:"constant_kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Constant) Reset() { *x = Constant{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Constant) String() string { @@ -325,7 +331,7 @@ func (*Constant) ProtoMessage() {} func (x *Constant) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -340,74 +346,92 @@ func (*Constant) Descriptor() ([]byte, []int) { return file_cel_expr_syntax_proto_rawDescGZIP(), []int{2} } -func (m *Constant) GetConstantKind() isConstant_ConstantKind { - if m != nil { - return m.ConstantKind +func (x *Constant) GetConstantKind() isConstant_ConstantKind { + if x != nil { + return x.ConstantKind } return nil } func (x *Constant) GetNullValue() structpb.NullValue { - if x, ok := x.GetConstantKind().(*Constant_NullValue); ok { - return x.NullValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_NullValue); ok { + return x.NullValue + } } return structpb.NullValue(0) } func (x *Constant) GetBoolValue() bool { - if x, ok := x.GetConstantKind().(*Constant_BoolValue); ok { - return x.BoolValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_BoolValue); ok { + return x.BoolValue + } } return false } func (x *Constant) GetInt64Value() int64 { - if x, ok := x.GetConstantKind().(*Constant_Int64Value); ok { - return x.Int64Value + if x != nil { + if x, ok := x.ConstantKind.(*Constant_Int64Value); ok { + return x.Int64Value + } } return 0 } func (x *Constant) GetUint64Value() uint64 { - if x, ok := x.GetConstantKind().(*Constant_Uint64Value); ok { - return x.Uint64Value + if x != nil { + if x, ok := x.ConstantKind.(*Constant_Uint64Value); ok { + return x.Uint64Value + } } return 0 } func (x *Constant) GetDoubleValue() float64 { - if x, ok := x.GetConstantKind().(*Constant_DoubleValue); ok { - return x.DoubleValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_DoubleValue); ok { + return x.DoubleValue + } } return 0 } func (x *Constant) GetStringValue() string { - if x, ok := x.GetConstantKind().(*Constant_StringValue); ok { - return x.StringValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_StringValue); ok { + return x.StringValue + } } return "" } func (x *Constant) GetBytesValue() []byte { - if x, ok := x.GetConstantKind().(*Constant_BytesValue); ok { - return x.BytesValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_BytesValue); ok { + return x.BytesValue + } } return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in cel/expr/syntax.proto. func (x *Constant) GetDurationValue() *durationpb.Duration { - if x, ok := x.GetConstantKind().(*Constant_DurationValue); ok { - return x.DurationValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_DurationValue); ok { + return x.DurationValue + } } return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in cel/expr/syntax.proto. func (x *Constant) GetTimestampValue() *timestamppb.Timestamp { - if x, ok := x.GetConstantKind().(*Constant_TimestampValue); ok { - return x.TimestampValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_TimestampValue); ok { + return x.TimestampValue + } } return nil } @@ -445,12 +469,12 @@ type Constant_BytesValue struct { } type Constant_DurationValue struct { - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in cel/expr/syntax.proto. DurationValue *durationpb.Duration `protobuf:"bytes,8,opt,name=duration_value,json=durationValue,proto3,oneof"` } type Constant_TimestampValue struct { - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in cel/expr/syntax.proto. TimestampValue *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=timestamp_value,json=timestampValue,proto3,oneof"` } @@ -473,25 +497,22 @@ func (*Constant_DurationValue) isConstant_ConstantKind() {} func (*Constant_TimestampValue) isConstant_ConstantKind() {} type SourceInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` SyntaxVersion string `protobuf:"bytes,1,opt,name=syntax_version,json=syntaxVersion,proto3" json:"syntax_version,omitempty"` Location string `protobuf:"bytes,2,opt,name=location,proto3" json:"location,omitempty"` LineOffsets []int32 `protobuf:"varint,3,rep,packed,name=line_offsets,json=lineOffsets,proto3" json:"line_offsets,omitempty"` - Positions map[int64]int32 `protobuf:"bytes,4,rep,name=positions,proto3" json:"positions,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - MacroCalls map[int64]*Expr `protobuf:"bytes,5,rep,name=macro_calls,json=macroCalls,proto3" json:"macro_calls,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Positions map[int64]int32 `protobuf:"bytes,4,rep,name=positions,proto3" json:"positions,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + MacroCalls map[int64]*Expr `protobuf:"bytes,5,rep,name=macro_calls,json=macroCalls,proto3" json:"macro_calls,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` Extensions []*SourceInfo_Extension `protobuf:"bytes,6,rep,name=extensions,proto3" json:"extensions,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SourceInfo) Reset() { *x = SourceInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SourceInfo) String() string { @@ -502,7 +523,7 @@ func (*SourceInfo) ProtoMessage() {} func (x *SourceInfo) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -560,20 +581,17 @@ func (x *SourceInfo) GetExtensions() []*SourceInfo_Extension { } type Expr_Ident struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Expr_Ident) Reset() { *x = Expr_Ident{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_Ident) String() string { @@ -584,7 +602,7 @@ func (*Expr_Ident) ProtoMessage() {} func (x *Expr_Ident) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -607,22 +625,19 @@ func (x *Expr_Ident) GetName() string { } type Expr_Select struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Operand *Expr `protobuf:"bytes,1,opt,name=operand,proto3" json:"operand,omitempty"` + Field string `protobuf:"bytes,2,opt,name=field,proto3" json:"field,omitempty"` + TestOnly bool `protobuf:"varint,3,opt,name=test_only,json=testOnly,proto3" json:"test_only,omitempty"` unknownFields protoimpl.UnknownFields - - Operand *Expr `protobuf:"bytes,1,opt,name=operand,proto3" json:"operand,omitempty"` - Field string `protobuf:"bytes,2,opt,name=field,proto3" json:"field,omitempty"` - TestOnly bool `protobuf:"varint,3,opt,name=test_only,json=testOnly,proto3" json:"test_only,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Expr_Select) Reset() { *x = Expr_Select{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_Select) String() string { @@ -633,7 +648,7 @@ func (*Expr_Select) ProtoMessage() {} func (x *Expr_Select) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -670,22 +685,19 @@ func (x *Expr_Select) GetTestOnly() bool { } type Expr_Call struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Target *Expr `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` + Function string `protobuf:"bytes,2,opt,name=function,proto3" json:"function,omitempty"` + Args []*Expr `protobuf:"bytes,3,rep,name=args,proto3" json:"args,omitempty"` unknownFields protoimpl.UnknownFields - - Target *Expr `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` - Function string `protobuf:"bytes,2,opt,name=function,proto3" json:"function,omitempty"` - Args []*Expr `protobuf:"bytes,3,rep,name=args,proto3" json:"args,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Expr_Call) Reset() { *x = Expr_Call{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_Call) String() string { @@ -696,7 +708,7 @@ func (*Expr_Call) ProtoMessage() {} func (x *Expr_Call) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -733,21 +745,18 @@ func (x *Expr_Call) GetArgs() []*Expr { } type Expr_CreateList struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Elements []*Expr `protobuf:"bytes,1,rep,name=elements,proto3" json:"elements,omitempty"` - OptionalIndices []int32 `protobuf:"varint,2,rep,packed,name=optional_indices,json=optionalIndices,proto3" json:"optional_indices,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Elements []*Expr `protobuf:"bytes,1,rep,name=elements,proto3" json:"elements,omitempty"` + OptionalIndices []int32 `protobuf:"varint,2,rep,packed,name=optional_indices,json=optionalIndices,proto3" json:"optional_indices,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Expr_CreateList) Reset() { *x = Expr_CreateList{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_CreateList) String() string { @@ -758,7 +767,7 @@ func (*Expr_CreateList) ProtoMessage() {} func (x *Expr_CreateList) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -788,21 +797,18 @@ func (x *Expr_CreateList) GetOptionalIndices() []int32 { } type Expr_CreateStruct struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + MessageName string `protobuf:"bytes,1,opt,name=message_name,json=messageName,proto3" json:"message_name,omitempty"` + Entries []*Expr_CreateStruct_Entry `protobuf:"bytes,2,rep,name=entries,proto3" json:"entries,omitempty"` unknownFields protoimpl.UnknownFields - - MessageName string `protobuf:"bytes,1,opt,name=message_name,json=messageName,proto3" json:"message_name,omitempty"` - Entries []*Expr_CreateStruct_Entry `protobuf:"bytes,2,rep,name=entries,proto3" json:"entries,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Expr_CreateStruct) Reset() { *x = Expr_CreateStruct{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_CreateStruct) String() string { @@ -813,7 +819,7 @@ func (*Expr_CreateStruct) ProtoMessage() {} func (x *Expr_CreateStruct) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -843,26 +849,24 @@ func (x *Expr_CreateStruct) GetEntries() []*Expr_CreateStruct_Entry { } type Expr_Comprehension struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + IterVar string `protobuf:"bytes,1,opt,name=iter_var,json=iterVar,proto3" json:"iter_var,omitempty"` + IterVar2 string `protobuf:"bytes,8,opt,name=iter_var2,json=iterVar2,proto3" json:"iter_var2,omitempty"` + IterRange *Expr `protobuf:"bytes,2,opt,name=iter_range,json=iterRange,proto3" json:"iter_range,omitempty"` + AccuVar string `protobuf:"bytes,3,opt,name=accu_var,json=accuVar,proto3" json:"accu_var,omitempty"` + AccuInit *Expr `protobuf:"bytes,4,opt,name=accu_init,json=accuInit,proto3" json:"accu_init,omitempty"` + LoopCondition *Expr `protobuf:"bytes,5,opt,name=loop_condition,json=loopCondition,proto3" json:"loop_condition,omitempty"` + LoopStep *Expr `protobuf:"bytes,6,opt,name=loop_step,json=loopStep,proto3" json:"loop_step,omitempty"` + Result *Expr `protobuf:"bytes,7,opt,name=result,proto3" json:"result,omitempty"` unknownFields protoimpl.UnknownFields - - IterVar string `protobuf:"bytes,1,opt,name=iter_var,json=iterVar,proto3" json:"iter_var,omitempty"` - IterRange *Expr `protobuf:"bytes,2,opt,name=iter_range,json=iterRange,proto3" json:"iter_range,omitempty"` - AccuVar string `protobuf:"bytes,3,opt,name=accu_var,json=accuVar,proto3" json:"accu_var,omitempty"` - AccuInit *Expr `protobuf:"bytes,4,opt,name=accu_init,json=accuInit,proto3" json:"accu_init,omitempty"` - LoopCondition *Expr `protobuf:"bytes,5,opt,name=loop_condition,json=loopCondition,proto3" json:"loop_condition,omitempty"` - LoopStep *Expr `protobuf:"bytes,6,opt,name=loop_step,json=loopStep,proto3" json:"loop_step,omitempty"` - Result *Expr `protobuf:"bytes,7,opt,name=result,proto3" json:"result,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Expr_Comprehension) Reset() { *x = Expr_Comprehension{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_Comprehension) String() string { @@ -873,7 +877,7 @@ func (*Expr_Comprehension) ProtoMessage() {} func (x *Expr_Comprehension) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -895,6 +899,13 @@ func (x *Expr_Comprehension) GetIterVar() string { return "" } +func (x *Expr_Comprehension) GetIterVar2() string { + if x != nil { + return x.IterVar2 + } + return "" +} + func (x *Expr_Comprehension) GetIterRange() *Expr { if x != nil { return x.IterRange @@ -938,27 +949,24 @@ func (x *Expr_Comprehension) GetResult() *Expr { } type Expr_CreateStruct_Entry struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - // Types that are assignable to KeyKind: + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are valid to be assigned to KeyKind: // // *Expr_CreateStruct_Entry_FieldKey // *Expr_CreateStruct_Entry_MapKey KeyKind isExpr_CreateStruct_Entry_KeyKind `protobuf_oneof:"key_kind"` Value *Expr `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` OptionalEntry bool `protobuf:"varint,5,opt,name=optional_entry,json=optionalEntry,proto3" json:"optional_entry,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Expr_CreateStruct_Entry) Reset() { *x = Expr_CreateStruct_Entry{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_CreateStruct_Entry) String() string { @@ -969,7 +977,7 @@ func (*Expr_CreateStruct_Entry) ProtoMessage() {} func (x *Expr_CreateStruct_Entry) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -991,23 +999,27 @@ func (x *Expr_CreateStruct_Entry) GetId() int64 { return 0 } -func (m *Expr_CreateStruct_Entry) GetKeyKind() isExpr_CreateStruct_Entry_KeyKind { - if m != nil { - return m.KeyKind +func (x *Expr_CreateStruct_Entry) GetKeyKind() isExpr_CreateStruct_Entry_KeyKind { + if x != nil { + return x.KeyKind } return nil } func (x *Expr_CreateStruct_Entry) GetFieldKey() string { - if x, ok := x.GetKeyKind().(*Expr_CreateStruct_Entry_FieldKey); ok { - return x.FieldKey + if x != nil { + if x, ok := x.KeyKind.(*Expr_CreateStruct_Entry_FieldKey); ok { + return x.FieldKey + } } return "" } func (x *Expr_CreateStruct_Entry) GetMapKey() *Expr { - if x, ok := x.GetKeyKind().(*Expr_CreateStruct_Entry_MapKey); ok { - return x.MapKey + if x != nil { + if x, ok := x.KeyKind.(*Expr_CreateStruct_Entry_MapKey); ok { + return x.MapKey + } } return nil } @@ -1043,22 +1055,19 @@ func (*Expr_CreateStruct_Entry_FieldKey) isExpr_CreateStruct_Entry_KeyKind() {} func (*Expr_CreateStruct_Entry_MapKey) isExpr_CreateStruct_Entry_KeyKind() {} type SourceInfo_Extension struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` AffectedComponents []SourceInfo_Extension_Component `protobuf:"varint,2,rep,packed,name=affected_components,json=affectedComponents,proto3,enum=cel.expr.SourceInfo_Extension_Component" json:"affected_components,omitempty"` Version *SourceInfo_Extension_Version `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SourceInfo_Extension) Reset() { *x = SourceInfo_Extension{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SourceInfo_Extension) String() string { @@ -1069,7 +1078,7 @@ func (*SourceInfo_Extension) ProtoMessage() {} func (x *SourceInfo_Extension) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1106,21 +1115,18 @@ func (x *SourceInfo_Extension) GetVersion() *SourceInfo_Extension_Version { } type SourceInfo_Extension_Version struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Major int64 `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"` + Minor int64 `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"` unknownFields protoimpl.UnknownFields - - Major int64 `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"` - Minor int64 `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SourceInfo_Extension_Version) Reset() { *x = SourceInfo_Extension_Version{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SourceInfo_Extension_Version) String() string { @@ -1131,7 +1137,7 @@ func (*SourceInfo_Extension_Version) ProtoMessage() {} func (x *SourceInfo_Extension_Version) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1162,210 +1168,124 @@ func (x *SourceInfo_Extension_Version) GetMinor() int64 { var File_cel_expr_syntax_proto protoreflect.FileDescriptor -var file_cel_expr_syntax_proto_rawDesc = []byte{ - 0x0a, 0x15, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x73, 0x79, 0x6e, 0x74, 0x61, - 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x67, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x73, 0x65, 0x64, 0x45, 0x78, 0x70, 0x72, 0x12, 0x22, - 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, - 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x04, 0x65, 0x78, - 0x70, 0x72, 0x12, 0x35, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, - 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, - 0x70, 0x72, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xfd, 0x0a, 0x0a, 0x04, 0x45, 0x78, - 0x70, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x33, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x72, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x09, 0x63, 0x6f, - 0x6e, 0x73, 0x74, 0x45, 0x78, 0x70, 0x72, 0x12, 0x35, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x70, 0x72, 0x12, 0x38, - 0x0a, 0x0b, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, - 0x78, 0x70, 0x72, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x73, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x45, 0x78, 0x70, 0x72, 0x12, 0x32, 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, - 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x43, 0x61, 0x6c, 0x6c, - 0x48, 0x00, 0x52, 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x12, 0x38, 0x0a, 0x09, - 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x08, 0x6c, 0x69, - 0x73, 0x74, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, - 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x73, 0x74, 0x72, 0x75, - 0x63, 0x74, 0x45, 0x78, 0x70, 0x72, 0x12, 0x4d, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, - 0x68, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, - 0x70, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, - 0x48, 0x00, 0x52, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x45, 0x78, 0x70, 0x72, 0x1a, 0x1b, 0x0a, 0x05, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x1a, 0x65, 0x0a, 0x06, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x28, 0x0a, 0x07, - 0x6f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x07, 0x6f, - 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x1b, 0x0a, 0x09, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x74, 0x65, 0x73, 0x74, 0x4f, 0x6e, 0x6c, 0x79, 0x1a, 0x6e, 0x0a, 0x04, 0x43, 0x61, 0x6c, - 0x6c, 0x12, 0x26, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, - 0x72, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, - 0x78, 0x70, 0x72, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x1a, 0x63, 0x0a, 0x0a, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, - 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0f, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x1a, 0xab, - 0x02, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, - 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, - 0x78, 0x70, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, - 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x1a, - 0xba, 0x01, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x09, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x07, 0x6d, 0x61, 0x70, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x61, 0x70, - 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, - 0x70, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0d, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x42, 0x0a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x1a, 0xad, 0x02, 0x0a, - 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, - 0x0a, 0x08, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x69, 0x74, 0x65, 0x72, 0x56, 0x61, 0x72, 0x12, 0x2d, 0x0a, 0x0a, 0x69, 0x74, 0x65, - 0x72, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x09, 0x69, - 0x74, 0x65, 0x72, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x75, - 0x5f, 0x76, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x63, 0x75, - 0x56, 0x61, 0x72, 0x12, 0x2b, 0x0a, 0x09, 0x61, 0x63, 0x63, 0x75, 0x5f, 0x69, 0x6e, 0x69, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x08, 0x61, 0x63, 0x63, 0x75, 0x49, 0x6e, 0x69, 0x74, - 0x12, 0x35, 0x0a, 0x0e, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, - 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x0d, 0x6c, 0x6f, 0x6f, 0x70, 0x43, 0x6f, - 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x09, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, - 0x73, 0x74, 0x65, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x08, 0x6c, 0x6f, 0x6f, 0x70, - 0x53, 0x74, 0x65, 0x70, 0x12, 0x26, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x45, 0x78, 0x70, 0x72, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x0b, 0x0a, 0x09, - 0x65, 0x78, 0x70, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0xc1, 0x03, 0x0a, 0x08, 0x43, 0x6f, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x0a, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4e, 0x75, 0x6c, - 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6e, 0x75, 0x6c, 0x6c, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x74, - 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x75, 0x69, 0x6e, 0x74, 0x36, - 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, - 0x0b, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, - 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0a, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x46, 0x0a, 0x0e, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x02, 0x18, 0x01, - 0x48, 0x00, 0x52, 0x0d, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x49, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0f, 0x0a, 0x0d, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0xac, 0x06, - 0x0a, 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x25, 0x0a, 0x0e, - 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x21, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0b, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, - 0x74, 0x73, 0x12, 0x41, 0x0a, 0x09, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, - 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x6f, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x45, 0x0a, 0x0b, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x5f, 0x63, - 0x61, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x2e, 0x4d, 0x61, 0x63, 0x72, 0x6f, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0a, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x12, 0x3e, 0x0a, 0x0a, - 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x53, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3c, 0x0a, 0x0e, - 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4d, 0x0a, 0x0f, 0x4d, 0x61, - 0x63, 0x72, 0x6f, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x24, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, - 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0xe0, 0x02, 0x0a, 0x09, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x59, 0x0a, 0x13, 0x61, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x12, - 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, - 0x74, 0x73, 0x12, 0x40, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x35, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, - 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x22, 0x6f, 0x0a, 0x09, 0x43, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4d, 0x50, - 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, - 0x5f, 0x50, 0x41, 0x52, 0x53, 0x45, 0x52, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4d, - 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x48, 0x45, 0x43, - 0x4b, 0x45, 0x52, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, - 0x4e, 0x54, 0x5f, 0x52, 0x55, 0x4e, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x03, 0x42, 0x2e, 0x0a, 0x0c, - 0x64, 0x65, 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0b, 0x53, 0x79, - 0x6e, 0x74, 0x61, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, - 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} +const file_cel_expr_syntax_proto_rawDesc = "" + + "\n" + + "\x15cel/expr/syntax.proto\x12\bcel.expr\x1a\x1egoogle/protobuf/duration.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"g\n" + + "\n" + + "ParsedExpr\x12\"\n" + + "\x04expr\x18\x02 \x01(\v2\x0e.cel.expr.ExprR\x04expr\x125\n" + + "\vsource_info\x18\x03 \x01(\v2\x14.cel.expr.SourceInfoR\n" + + "sourceInfo\"\x9a\v\n" + + "\x04Expr\x12\x0e\n" + + "\x02id\x18\x02 \x01(\x03R\x02id\x123\n" + + "\n" + + "const_expr\x18\x03 \x01(\v2\x12.cel.expr.ConstantH\x00R\tconstExpr\x125\n" + + "\n" + + "ident_expr\x18\x04 \x01(\v2\x14.cel.expr.Expr.IdentH\x00R\tidentExpr\x128\n" + + "\vselect_expr\x18\x05 \x01(\v2\x15.cel.expr.Expr.SelectH\x00R\n" + + "selectExpr\x122\n" + + "\tcall_expr\x18\x06 \x01(\v2\x13.cel.expr.Expr.CallH\x00R\bcallExpr\x128\n" + + "\tlist_expr\x18\a \x01(\v2\x19.cel.expr.Expr.CreateListH\x00R\blistExpr\x12>\n" + + "\vstruct_expr\x18\b \x01(\v2\x1b.cel.expr.Expr.CreateStructH\x00R\n" + + "structExpr\x12M\n" + + "\x12comprehension_expr\x18\t \x01(\v2\x1c.cel.expr.Expr.ComprehensionH\x00R\x11comprehensionExpr\x1a\x1b\n" + + "\x05Ident\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x1ae\n" + + "\x06Select\x12(\n" + + "\aoperand\x18\x01 \x01(\v2\x0e.cel.expr.ExprR\aoperand\x12\x14\n" + + "\x05field\x18\x02 \x01(\tR\x05field\x12\x1b\n" + + "\ttest_only\x18\x03 \x01(\bR\btestOnly\x1an\n" + + "\x04Call\x12&\n" + + "\x06target\x18\x01 \x01(\v2\x0e.cel.expr.ExprR\x06target\x12\x1a\n" + + "\bfunction\x18\x02 \x01(\tR\bfunction\x12\"\n" + + "\x04args\x18\x03 \x03(\v2\x0e.cel.expr.ExprR\x04args\x1ac\n" + + "\n" + + "CreateList\x12*\n" + + "\belements\x18\x01 \x03(\v2\x0e.cel.expr.ExprR\belements\x12)\n" + + "\x10optional_indices\x18\x02 \x03(\x05R\x0foptionalIndices\x1a\xab\x02\n" + + "\fCreateStruct\x12!\n" + + "\fmessage_name\x18\x01 \x01(\tR\vmessageName\x12;\n" + + "\aentries\x18\x02 \x03(\v2!.cel.expr.Expr.CreateStruct.EntryR\aentries\x1a\xba\x01\n" + + "\x05Entry\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x1d\n" + + "\tfield_key\x18\x02 \x01(\tH\x00R\bfieldKey\x12)\n" + + "\amap_key\x18\x03 \x01(\v2\x0e.cel.expr.ExprH\x00R\x06mapKey\x12$\n" + + "\x05value\x18\x04 \x01(\v2\x0e.cel.expr.ExprR\x05value\x12%\n" + + "\x0eoptional_entry\x18\x05 \x01(\bR\roptionalEntryB\n" + + "\n" + + "\bkey_kind\x1a\xca\x02\n" + + "\rComprehension\x12\x19\n" + + "\biter_var\x18\x01 \x01(\tR\aiterVar\x12\x1b\n" + + "\titer_var2\x18\b \x01(\tR\biterVar2\x12-\n" + + "\n" + + "iter_range\x18\x02 \x01(\v2\x0e.cel.expr.ExprR\titerRange\x12\x19\n" + + "\baccu_var\x18\x03 \x01(\tR\aaccuVar\x12+\n" + + "\taccu_init\x18\x04 \x01(\v2\x0e.cel.expr.ExprR\baccuInit\x125\n" + + "\x0eloop_condition\x18\x05 \x01(\v2\x0e.cel.expr.ExprR\rloopCondition\x12+\n" + + "\tloop_step\x18\x06 \x01(\v2\x0e.cel.expr.ExprR\bloopStep\x12&\n" + + "\x06result\x18\a \x01(\v2\x0e.cel.expr.ExprR\x06resultB\v\n" + + "\texpr_kind\"\xc1\x03\n" + + "\bConstant\x12;\n" + + "\n" + + "null_value\x18\x01 \x01(\x0e2\x1a.google.protobuf.NullValueH\x00R\tnullValue\x12\x1f\n" + + "\n" + + "bool_value\x18\x02 \x01(\bH\x00R\tboolValue\x12!\n" + + "\vint64_value\x18\x03 \x01(\x03H\x00R\n" + + "int64Value\x12#\n" + + "\fuint64_value\x18\x04 \x01(\x04H\x00R\vuint64Value\x12#\n" + + "\fdouble_value\x18\x05 \x01(\x01H\x00R\vdoubleValue\x12#\n" + + "\fstring_value\x18\x06 \x01(\tH\x00R\vstringValue\x12!\n" + + "\vbytes_value\x18\a \x01(\fH\x00R\n" + + "bytesValue\x12F\n" + + "\x0eduration_value\x18\b \x01(\v2\x19.google.protobuf.DurationB\x02\x18\x01H\x00R\rdurationValue\x12I\n" + + "\x0ftimestamp_value\x18\t \x01(\v2\x1a.google.protobuf.TimestampB\x02\x18\x01H\x00R\x0etimestampValueB\x0f\n" + + "\rconstant_kind\"\xac\x06\n" + + "\n" + + "SourceInfo\x12%\n" + + "\x0esyntax_version\x18\x01 \x01(\tR\rsyntaxVersion\x12\x1a\n" + + "\blocation\x18\x02 \x01(\tR\blocation\x12!\n" + + "\fline_offsets\x18\x03 \x03(\x05R\vlineOffsets\x12A\n" + + "\tpositions\x18\x04 \x03(\v2#.cel.expr.SourceInfo.PositionsEntryR\tpositions\x12E\n" + + "\vmacro_calls\x18\x05 \x03(\v2$.cel.expr.SourceInfo.MacroCallsEntryR\n" + + "macroCalls\x12>\n" + + "\n" + + "extensions\x18\x06 \x03(\v2\x1e.cel.expr.SourceInfo.ExtensionR\n" + + "extensions\x1a<\n" + + "\x0ePositionsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\x03R\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\x05R\x05value:\x028\x01\x1aM\n" + + "\x0fMacroCallsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\x03R\x03key\x12$\n" + + "\x05value\x18\x02 \x01(\v2\x0e.cel.expr.ExprR\x05value:\x028\x01\x1a\xe0\x02\n" + + "\tExtension\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12Y\n" + + "\x13affected_components\x18\x02 \x03(\x0e2(.cel.expr.SourceInfo.Extension.ComponentR\x12affectedComponents\x12@\n" + + "\aversion\x18\x03 \x01(\v2&.cel.expr.SourceInfo.Extension.VersionR\aversion\x1a5\n" + + "\aVersion\x12\x14\n" + + "\x05major\x18\x01 \x01(\x03R\x05major\x12\x14\n" + + "\x05minor\x18\x02 \x01(\x03R\x05minor\"o\n" + + "\tComponent\x12\x19\n" + + "\x15COMPONENT_UNSPECIFIED\x10\x00\x12\x14\n" + + "\x10COMPONENT_PARSER\x10\x01\x12\x1a\n" + + "\x16COMPONENT_TYPE_CHECKER\x10\x02\x12\x15\n" + + "\x11COMPONENT_RUNTIME\x10\x03B.\n" + + "\fdev.cel.exprB\vSyntaxProtoP\x01Z\fcel.dev/expr\xf8\x01\x01b\x06proto3" var ( file_cel_expr_syntax_proto_rawDescOnce sync.Once - file_cel_expr_syntax_proto_rawDescData = file_cel_expr_syntax_proto_rawDesc + file_cel_expr_syntax_proto_rawDescData []byte ) func file_cel_expr_syntax_proto_rawDescGZIP() []byte { file_cel_expr_syntax_proto_rawDescOnce.Do(func() { - file_cel_expr_syntax_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_syntax_proto_rawDescData) + file_cel_expr_syntax_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cel_expr_syntax_proto_rawDesc), len(file_cel_expr_syntax_proto_rawDesc))) }) return file_cel_expr_syntax_proto_rawDescData } var file_cel_expr_syntax_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_cel_expr_syntax_proto_msgTypes = make([]protoimpl.MessageInfo, 15) -var file_cel_expr_syntax_proto_goTypes = []interface{}{ +var file_cel_expr_syntax_proto_goTypes = []any{ (SourceInfo_Extension_Component)(0), // 0: cel.expr.SourceInfo.Extension.Component (*ParsedExpr)(nil), // 1: cel.expr.ParsedExpr (*Expr)(nil), // 2: cel.expr.Expr @@ -1429,165 +1349,7 @@ func file_cel_expr_syntax_proto_init() { if File_cel_expr_syntax_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_cel_expr_syntax_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParsedExpr); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Constant); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SourceInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_Ident); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_Select); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_Call); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_CreateList); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_CreateStruct); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_Comprehension); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_CreateStruct_Entry); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SourceInfo_Extension); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SourceInfo_Extension_Version); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_cel_expr_syntax_proto_msgTypes[1].OneofWrappers = []interface{}{ + file_cel_expr_syntax_proto_msgTypes[1].OneofWrappers = []any{ (*Expr_ConstExpr)(nil), (*Expr_IdentExpr)(nil), (*Expr_SelectExpr)(nil), @@ -1596,7 +1358,7 @@ func file_cel_expr_syntax_proto_init() { (*Expr_StructExpr)(nil), (*Expr_ComprehensionExpr)(nil), } - file_cel_expr_syntax_proto_msgTypes[2].OneofWrappers = []interface{}{ + file_cel_expr_syntax_proto_msgTypes[2].OneofWrappers = []any{ (*Constant_NullValue)(nil), (*Constant_BoolValue)(nil), (*Constant_Int64Value)(nil), @@ -1607,7 +1369,7 @@ func file_cel_expr_syntax_proto_init() { (*Constant_DurationValue)(nil), (*Constant_TimestampValue)(nil), } - file_cel_expr_syntax_proto_msgTypes[10].OneofWrappers = []interface{}{ + file_cel_expr_syntax_proto_msgTypes[10].OneofWrappers = []any{ (*Expr_CreateStruct_Entry_FieldKey)(nil), (*Expr_CreateStruct_Entry_MapKey)(nil), } @@ -1615,7 +1377,7 @@ func file_cel_expr_syntax_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cel_expr_syntax_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_cel_expr_syntax_proto_rawDesc), len(file_cel_expr_syntax_proto_rawDesc)), NumEnums: 1, NumMessages: 15, NumExtensions: 0, @@ -1627,7 +1389,6 @@ func file_cel_expr_syntax_proto_init() { MessageInfos: file_cel_expr_syntax_proto_msgTypes, }.Build() File_cel_expr_syntax_proto = out.File - file_cel_expr_syntax_proto_rawDesc = nil file_cel_expr_syntax_proto_goTypes = nil file_cel_expr_syntax_proto_depIdxs = nil } diff --git a/plugins/traefik/vendor/cel.dev/expr/value.pb.go b/plugins/traefik/vendor/cel.dev/expr/value.pb.go index e5e29228c..1f53a6a29 100644 --- a/plugins/traefik/vendor/cel.dev/expr/value.pb.go +++ b/plugins/traefik/vendor/cel.dev/expr/value.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.5 +// protoc-gen-go v1.36.10 +// protoc v5.27.1 // source: cel/expr/value.proto package expr @@ -13,6 +13,7 @@ import ( structpb "google.golang.org/protobuf/types/known/structpb" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -23,11 +24,8 @@ const ( ) type Value struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Kind: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Kind: // // *Value_NullValue // *Value_BoolValue @@ -41,16 +39,16 @@ type Value struct { // *Value_MapValue // *Value_ListValue // *Value_TypeValue - Kind isValue_Kind `protobuf_oneof:"kind"` + Kind isValue_Kind `protobuf_oneof:"kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Value) Reset() { *x = Value{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_value_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_value_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Value) String() string { @@ -61,7 +59,7 @@ func (*Value) ProtoMessage() {} func (x *Value) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_value_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -76,93 +74,117 @@ func (*Value) Descriptor() ([]byte, []int) { return file_cel_expr_value_proto_rawDescGZIP(), []int{0} } -func (m *Value) GetKind() isValue_Kind { - if m != nil { - return m.Kind +func (x *Value) GetKind() isValue_Kind { + if x != nil { + return x.Kind } return nil } func (x *Value) GetNullValue() structpb.NullValue { - if x, ok := x.GetKind().(*Value_NullValue); ok { - return x.NullValue + if x != nil { + if x, ok := x.Kind.(*Value_NullValue); ok { + return x.NullValue + } } return structpb.NullValue(0) } func (x *Value) GetBoolValue() bool { - if x, ok := x.GetKind().(*Value_BoolValue); ok { - return x.BoolValue + if x != nil { + if x, ok := x.Kind.(*Value_BoolValue); ok { + return x.BoolValue + } } return false } func (x *Value) GetInt64Value() int64 { - if x, ok := x.GetKind().(*Value_Int64Value); ok { - return x.Int64Value + if x != nil { + if x, ok := x.Kind.(*Value_Int64Value); ok { + return x.Int64Value + } } return 0 } func (x *Value) GetUint64Value() uint64 { - if x, ok := x.GetKind().(*Value_Uint64Value); ok { - return x.Uint64Value + if x != nil { + if x, ok := x.Kind.(*Value_Uint64Value); ok { + return x.Uint64Value + } } return 0 } func (x *Value) GetDoubleValue() float64 { - if x, ok := x.GetKind().(*Value_DoubleValue); ok { - return x.DoubleValue + if x != nil { + if x, ok := x.Kind.(*Value_DoubleValue); ok { + return x.DoubleValue + } } return 0 } func (x *Value) GetStringValue() string { - if x, ok := x.GetKind().(*Value_StringValue); ok { - return x.StringValue + if x != nil { + if x, ok := x.Kind.(*Value_StringValue); ok { + return x.StringValue + } } return "" } func (x *Value) GetBytesValue() []byte { - if x, ok := x.GetKind().(*Value_BytesValue); ok { - return x.BytesValue + if x != nil { + if x, ok := x.Kind.(*Value_BytesValue); ok { + return x.BytesValue + } } return nil } func (x *Value) GetEnumValue() *EnumValue { - if x, ok := x.GetKind().(*Value_EnumValue); ok { - return x.EnumValue + if x != nil { + if x, ok := x.Kind.(*Value_EnumValue); ok { + return x.EnumValue + } } return nil } func (x *Value) GetObjectValue() *anypb.Any { - if x, ok := x.GetKind().(*Value_ObjectValue); ok { - return x.ObjectValue + if x != nil { + if x, ok := x.Kind.(*Value_ObjectValue); ok { + return x.ObjectValue + } } return nil } func (x *Value) GetMapValue() *MapValue { - if x, ok := x.GetKind().(*Value_MapValue); ok { - return x.MapValue + if x != nil { + if x, ok := x.Kind.(*Value_MapValue); ok { + return x.MapValue + } } return nil } func (x *Value) GetListValue() *ListValue { - if x, ok := x.GetKind().(*Value_ListValue); ok { - return x.ListValue + if x != nil { + if x, ok := x.Kind.(*Value_ListValue); ok { + return x.ListValue + } } return nil } func (x *Value) GetTypeValue() string { - if x, ok := x.GetKind().(*Value_TypeValue); ok { - return x.TypeValue + if x != nil { + if x, ok := x.Kind.(*Value_TypeValue); ok { + return x.TypeValue + } } return "" } @@ -244,21 +266,18 @@ func (*Value_ListValue) isValue_Kind() {} func (*Value_TypeValue) isValue_Kind() {} type EnumValue struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Value int32 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields - - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - Value int32 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` + sizeCache protoimpl.SizeCache } func (x *EnumValue) Reset() { *x = EnumValue{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_value_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_value_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *EnumValue) String() string { @@ -269,7 +288,7 @@ func (*EnumValue) ProtoMessage() {} func (x *EnumValue) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_value_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -299,20 +318,17 @@ func (x *EnumValue) GetValue() int32 { } type ListValue struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` unknownFields protoimpl.UnknownFields - - Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ListValue) Reset() { *x = ListValue{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_value_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_value_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListValue) String() string { @@ -323,7 +339,7 @@ func (*ListValue) ProtoMessage() {} func (x *ListValue) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_value_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -346,20 +362,17 @@ func (x *ListValue) GetValues() []*Value { } type MapValue struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Entries []*MapValue_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` unknownFields protoimpl.UnknownFields - - Entries []*MapValue_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` + sizeCache protoimpl.SizeCache } func (x *MapValue) Reset() { *x = MapValue{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_value_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_value_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MapValue) String() string { @@ -370,7 +383,7 @@ func (*MapValue) ProtoMessage() {} func (x *MapValue) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_value_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -393,21 +406,18 @@ func (x *MapValue) GetEntries() []*MapValue_Entry { } type MapValue_Entry struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Key *Value `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value *Value `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields - - Key *Value `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Value *Value `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + sizeCache protoimpl.SizeCache } func (x *MapValue_Entry) Reset() { *x = MapValue_Entry{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_value_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_value_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MapValue_Entry) String() string { @@ -418,7 +428,7 @@ func (*MapValue_Entry) ProtoMessage() {} func (x *MapValue_Entry) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_value_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -449,83 +459,58 @@ func (x *MapValue_Entry) GetValue() *Value { var File_cel_expr_value_proto protoreflect.FileDescriptor -var file_cel_expr_value_proto_rawDesc = []byte{ - 0x0a, 0x14, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, - 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, - 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9d, 0x04, 0x0a, 0x05, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6e, 0x75, 0x6c, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x0b, 0x75, 0x69, - 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x64, 0x6f, 0x75, - 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x48, - 0x00, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, - 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, - 0x00, 0x52, 0x09, 0x65, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x39, 0x0a, 0x0c, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x48, 0x00, 0x52, 0x0b, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x6d, 0x61, 0x70, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, - 0x52, 0x08, 0x6d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x6c, 0x69, - 0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x1f, 0x0a, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x74, 0x79, 0x70, 0x65, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0x35, 0x0a, 0x09, 0x45, 0x6e, 0x75, - 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0x34, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x27, 0x0a, - 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x08, 0x4d, 0x61, 0x70, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, - 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x51, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x21, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x25, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2d, 0x0a, 0x0c, 0x64, 0x65, - 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0a, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, 0x65, - 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} +const file_cel_expr_value_proto_rawDesc = "" + + "\n" + + "\x14cel/expr/value.proto\x12\bcel.expr\x1a\x19google/protobuf/any.proto\x1a\x1cgoogle/protobuf/struct.proto\"\x9d\x04\n" + + "\x05Value\x12;\n" + + "\n" + + "null_value\x18\x01 \x01(\x0e2\x1a.google.protobuf.NullValueH\x00R\tnullValue\x12\x1f\n" + + "\n" + + "bool_value\x18\x02 \x01(\bH\x00R\tboolValue\x12!\n" + + "\vint64_value\x18\x03 \x01(\x03H\x00R\n" + + "int64Value\x12#\n" + + "\fuint64_value\x18\x04 \x01(\x04H\x00R\vuint64Value\x12#\n" + + "\fdouble_value\x18\x05 \x01(\x01H\x00R\vdoubleValue\x12#\n" + + "\fstring_value\x18\x06 \x01(\tH\x00R\vstringValue\x12!\n" + + "\vbytes_value\x18\a \x01(\fH\x00R\n" + + "bytesValue\x124\n" + + "\n" + + "enum_value\x18\t \x01(\v2\x13.cel.expr.EnumValueH\x00R\tenumValue\x129\n" + + "\fobject_value\x18\n" + + " \x01(\v2\x14.google.protobuf.AnyH\x00R\vobjectValue\x121\n" + + "\tmap_value\x18\v \x01(\v2\x12.cel.expr.MapValueH\x00R\bmapValue\x124\n" + + "\n" + + "list_value\x18\f \x01(\v2\x13.cel.expr.ListValueH\x00R\tlistValue\x12\x1f\n" + + "\n" + + "type_value\x18\x0f \x01(\tH\x00R\ttypeValueB\x06\n" + + "\x04kind\"5\n" + + "\tEnumValue\x12\x12\n" + + "\x04type\x18\x01 \x01(\tR\x04type\x12\x14\n" + + "\x05value\x18\x02 \x01(\x05R\x05value\"4\n" + + "\tListValue\x12'\n" + + "\x06values\x18\x01 \x03(\v2\x0f.cel.expr.ValueR\x06values\"\x91\x01\n" + + "\bMapValue\x122\n" + + "\aentries\x18\x01 \x03(\v2\x18.cel.expr.MapValue.EntryR\aentries\x1aQ\n" + + "\x05Entry\x12!\n" + + "\x03key\x18\x01 \x01(\v2\x0f.cel.expr.ValueR\x03key\x12%\n" + + "\x05value\x18\x02 \x01(\v2\x0f.cel.expr.ValueR\x05valueB-\n" + + "\fdev.cel.exprB\n" + + "ValueProtoP\x01Z\fcel.dev/expr\xf8\x01\x01b\x06proto3" var ( file_cel_expr_value_proto_rawDescOnce sync.Once - file_cel_expr_value_proto_rawDescData = file_cel_expr_value_proto_rawDesc + file_cel_expr_value_proto_rawDescData []byte ) func file_cel_expr_value_proto_rawDescGZIP() []byte { file_cel_expr_value_proto_rawDescOnce.Do(func() { - file_cel_expr_value_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_value_proto_rawDescData) + file_cel_expr_value_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cel_expr_value_proto_rawDesc), len(file_cel_expr_value_proto_rawDesc))) }) return file_cel_expr_value_proto_rawDescData } var file_cel_expr_value_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_cel_expr_value_proto_goTypes = []interface{}{ +var file_cel_expr_value_proto_goTypes = []any{ (*Value)(nil), // 0: cel.expr.Value (*EnumValue)(nil), // 1: cel.expr.EnumValue (*ListValue)(nil), // 2: cel.expr.ListValue @@ -556,69 +541,7 @@ func file_cel_expr_value_proto_init() { if File_cel_expr_value_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_cel_expr_value_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Value); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_value_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EnumValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_value_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_value_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MapValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_value_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MapValue_Entry); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_cel_expr_value_proto_msgTypes[0].OneofWrappers = []interface{}{ + file_cel_expr_value_proto_msgTypes[0].OneofWrappers = []any{ (*Value_NullValue)(nil), (*Value_BoolValue)(nil), (*Value_Int64Value)(nil), @@ -636,7 +559,7 @@ func file_cel_expr_value_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cel_expr_value_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_cel_expr_value_proto_rawDesc), len(file_cel_expr_value_proto_rawDesc)), NumEnums: 0, NumMessages: 5, NumExtensions: 0, @@ -647,7 +570,6 @@ func file_cel_expr_value_proto_init() { MessageInfos: file_cel_expr_value_proto_msgTypes, }.Build() File_cel_expr_value_proto = out.File - file_cel_expr_value_proto_rawDesc = nil file_cel_expr_value_proto_goTypes = nil file_cel_expr_value_proto_depIdxs = nil } diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/CHANGES.md b/plugins/traefik/vendor/cloud.google.com/go/auth/CHANGES.md new file mode 100644 index 000000000..846231f64 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/CHANGES.md @@ -0,0 +1,475 @@ +# Changes + +## [0.18.2](https://github.com/googleapis/google-cloud-go/releases/tag/auth%2Fv0.18.2) (2026-02-13) + +### Bug Fixes + +* fixes gdch credentials logic (#13741) ([f82cda5](https://github.com/googleapis/google-cloud-go/commit/f82cda58bd9885b7b8a9d8b15126f5a1e0add0dc)) + +## [0.18.1](https://github.com/googleapis/google-cloud-go/releases/tag/auth%2Fv0.18.1) (2026-01-21) + +### Bug Fixes + +* add InternalOptions.TelemetryAttributes for internal client use (#13641) ([3876978](https://github.com/googleapis/google-cloud-go/commit/38769789755ed47d85e85dcd56596109de65f780)) +* remove singleton and restore normal usage of otelgrpc.clientHandler (#13522) ([673d4b0](https://github.com/googleapis/google-cloud-go/commit/673d4b05617f833aa433f7f6a350b5cb888ea20d)) + +## [0.18.0](https://github.com/googleapis/google-cloud-go/releases/tag/auth%2Fv0.18.0) (2025-12-15) + +### Features + +* Support scopes field from impersonated credential json (#13308) ([e3f62e1](https://github.com/googleapis/google-cloud-go/commit/e3f62e102840127a0058f5cced4c9738f2bf45f2)) +* add support for parsing EC private key (#13317) ([ea6bc62](https://github.com/googleapis/google-cloud-go/commit/ea6bc62ffe2cc0a6d607d698a181b37fa46c340d)) +* deprecate unsafe credentials JSON loading options (#13397) ([0dd2a3b](https://github.com/googleapis/google-cloud-go/commit/0dd2a3bdece9a85ee7216a737559fa9f5a869545)) + +## [0.17.0](https://github.com/googleapis/google-cloud-go/releases/tag/auth%2Fv0.17.0) (2025-10-02) + +### Features + +* Add trust boundary support for service accounts and impersonation (HTTP/gRPC) (#11870) ([5c2b665](https://github.com/googleapis/google-cloud-go/commit/5c2b665f392e6dd90192f107188720aa1357e7da)) +* add trust boundary support for external accounts (#12864) ([a67a146](https://github.com/googleapis/google-cloud-go/commit/a67a146a6a88a6f1ba10c409dfce8015ecd60a64)) + +## [0.16.5](https://github.com/googleapis/google-cloud-go/compare/auth/v0.16.4...auth/v0.16.5) (2025-08-14) + + +### Bug Fixes + +* **auth:** Improve error message for unknown credentials type ([#12673](https://github.com/googleapis/google-cloud-go/issues/12673)) ([558b164](https://github.com/googleapis/google-cloud-go/commit/558b16429f621276694405fa5f2091199f2d4c4d)) +* **auth:** Set Content-Type in userTokenProvider.exchangeToken ([#12634](https://github.com/googleapis/google-cloud-go/issues/12634)) ([1197ebc](https://github.com/googleapis/google-cloud-go/commit/1197ebcbca491f8c610da732c7361c90bc6f46d0)) + +## [0.16.4](https://github.com/googleapis/google-cloud-go/compare/auth/v0.16.3...auth/v0.16.4) (2025-08-06) + + +### Bug Fixes + +* **auth:** Add UseDefaultClient: true to metadata.Options ([#12666](https://github.com/googleapis/google-cloud-go/issues/12666)) ([1482191](https://github.com/googleapis/google-cloud-go/commit/1482191e88236693efef68769752638281566766)), refs [#11078](https://github.com/googleapis/google-cloud-go/issues/11078) [#12657](https://github.com/googleapis/google-cloud-go/issues/12657) + +## [0.16.3](https://github.com/googleapis/google-cloud-go/compare/auth/v0.16.2...auth/v0.16.3) (2025-07-17) + + +### Bug Fixes + +* **auth:** Fix race condition in cachedTokenProvider.tokenAsync ([#12586](https://github.com/googleapis/google-cloud-go/issues/12586)) ([73867cc](https://github.com/googleapis/google-cloud-go/commit/73867ccc1e9808d65361bcfc0776bd95fe34dbb3)) + +## [0.16.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.16.1...auth/v0.16.2) (2025-06-04) + + +### Bug Fixes + +* **auth:** Add back DirectPath misconfiguration logging ([#11162](https://github.com/googleapis/google-cloud-go/issues/11162)) ([8d52da5](https://github.com/googleapis/google-cloud-go/commit/8d52da58da5a0ed77a0f6307d1b561bc045406a1)) +* **auth:** Remove s2a fallback option ([#12354](https://github.com/googleapis/google-cloud-go/issues/12354)) ([d5acc59](https://github.com/googleapis/google-cloud-go/commit/d5acc599cd775ddc404349e75906fa02e8ff133e)) + +## [0.16.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.16.0...auth/v0.16.1) (2025-04-23) + + +### Bug Fixes + +* **auth:** Clone detectopts before assigning TokenBindingType ([#11881](https://github.com/googleapis/google-cloud-go/issues/11881)) ([2167b02](https://github.com/googleapis/google-cloud-go/commit/2167b020fdc43b517c2b6ecca264a10e357ea035)) + +## [0.16.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.15.0...auth/v0.16.0) (2025-04-14) + + +### Features + +* **auth/credentials:** Return X.509 certificate chain as subject token ([#11948](https://github.com/googleapis/google-cloud-go/issues/11948)) ([d445a3f](https://github.com/googleapis/google-cloud-go/commit/d445a3f66272ffd5c39c4939af9bebad4582631c)), refs [#11757](https://github.com/googleapis/google-cloud-go/issues/11757) +* **auth:** Configure DirectPath bound credentials from AllowedHardBoundTokens ([#11665](https://github.com/googleapis/google-cloud-go/issues/11665)) ([0fc40bc](https://github.com/googleapis/google-cloud-go/commit/0fc40bcf4e4673704df0973e9fa65957395d7bb4)) + + +### Bug Fixes + +* **auth:** Allow non-default SA credentials for DP ([#11828](https://github.com/googleapis/google-cloud-go/issues/11828)) ([3a996b4](https://github.com/googleapis/google-cloud-go/commit/3a996b4129e6d0a34dfda6671f535d5aefb26a82)) +* **auth:** Restore calling DialContext ([#11930](https://github.com/googleapis/google-cloud-go/issues/11930)) ([9ec9a29](https://github.com/googleapis/google-cloud-go/commit/9ec9a29494e93197edbaf45aba28984801e9770a)), refs [#11118](https://github.com/googleapis/google-cloud-go/issues/11118) + +## [0.15.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.14.1...auth/v0.15.0) (2025-02-19) + + +### Features + +* **auth:** Add hard-bound token request to compute token provider. ([#11588](https://github.com/googleapis/google-cloud-go/issues/11588)) ([0e608bb](https://github.com/googleapis/google-cloud-go/commit/0e608bb5ac3d694c8ad36ca4340071d3a2c78699)) + +## [0.14.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.14.0...auth/v0.14.1) (2025-01-24) + + +### Documentation + +* **auth:** Add warning about externally-provided credentials ([#11462](https://github.com/googleapis/google-cloud-go/issues/11462)) ([49fb6ff](https://github.com/googleapis/google-cloud-go/commit/49fb6ff4d754895f82c9c4d502fc7547d3b5a941)) + +## [0.14.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.13.0...auth/v0.14.0) (2025-01-08) + + +### Features + +* **auth:** Add universe domain support to idtoken ([#11059](https://github.com/googleapis/google-cloud-go/issues/11059)) ([72add7e](https://github.com/googleapis/google-cloud-go/commit/72add7e9f8f455af695e8ef79212a4bd3122fb3a)) + + +### Bug Fixes + +* **auth/oauth2adapt:** Update golang.org/x/net to v0.33.0 ([e9b0b69](https://github.com/googleapis/google-cloud-go/commit/e9b0b69644ea5b276cacff0a707e8a5e87efafc9)) +* **auth:** Fix copy of delegates in impersonate.NewIDTokenCredentials ([#11386](https://github.com/googleapis/google-cloud-go/issues/11386)) ([ff7ef8e](https://github.com/googleapis/google-cloud-go/commit/ff7ef8e7ade7171bce3e4f30ff10a2e9f6c27ca0)), refs [#11379](https://github.com/googleapis/google-cloud-go/issues/11379) +* **auth:** Update golang.org/x/net to v0.33.0 ([e9b0b69](https://github.com/googleapis/google-cloud-go/commit/e9b0b69644ea5b276cacff0a707e8a5e87efafc9)) + +## [0.13.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.12.1...auth/v0.13.0) (2024-12-13) + + +### Features + +* **auth:** Add logging support ([#11079](https://github.com/googleapis/google-cloud-go/issues/11079)) ([c80e31d](https://github.com/googleapis/google-cloud-go/commit/c80e31df5ecb33a810be3dfb9d9e27ac531aa91d)) +* **auth:** Pass logger from auth layer to metadata package ([#11288](https://github.com/googleapis/google-cloud-go/issues/11288)) ([b552efd](https://github.com/googleapis/google-cloud-go/commit/b552efd6ab34e5dfded18438e0fbfd925805614f)) + + +### Bug Fixes + +* **auth:** Check compute cred type before non-default flag for DP ([#11255](https://github.com/googleapis/google-cloud-go/issues/11255)) ([4347ca1](https://github.com/googleapis/google-cloud-go/commit/4347ca141892be8ae813399b4b437662a103bc90)) + +## [0.12.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.12.0...auth/v0.12.1) (2024-12-10) + + +### Bug Fixes + +* **auth:** Correct typo in link ([#11160](https://github.com/googleapis/google-cloud-go/issues/11160)) ([af6fb46](https://github.com/googleapis/google-cloud-go/commit/af6fb46d7cd694ddbe8c9d63bc4cdcd62b9fb2c1)) + +## [0.12.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.11.0...auth/v0.12.0) (2024-12-04) + + +### Features + +* **auth:** Add support for providing custom certificate URL ([#11006](https://github.com/googleapis/google-cloud-go/issues/11006)) ([ebf3657](https://github.com/googleapis/google-cloud-go/commit/ebf36579724afb375d3974cf1da38f703e3b7dbc)), refs [#11005](https://github.com/googleapis/google-cloud-go/issues/11005) + + +### Bug Fixes + +* **auth:** Ensure endpoints are present in Validator ([#11209](https://github.com/googleapis/google-cloud-go/issues/11209)) ([106cd53](https://github.com/googleapis/google-cloud-go/commit/106cd53309facaef1b8ea78376179f523f6912b9)), refs [#11006](https://github.com/googleapis/google-cloud-go/issues/11006) [#11190](https://github.com/googleapis/google-cloud-go/issues/11190) [#11189](https://github.com/googleapis/google-cloud-go/issues/11189) [#11188](https://github.com/googleapis/google-cloud-go/issues/11188) + +## [0.11.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.10.2...auth/v0.11.0) (2024-11-21) + + +### Features + +* **auth:** Add universe domain support to mTLS ([#11159](https://github.com/googleapis/google-cloud-go/issues/11159)) ([117748b](https://github.com/googleapis/google-cloud-go/commit/117748ba1cfd4ae62a6a4feb7e30951cb2bc9344)) + +## [0.10.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.10.1...auth/v0.10.2) (2024-11-12) + + +### Bug Fixes + +* **auth:** Restore use of grpc.Dial ([#11118](https://github.com/googleapis/google-cloud-go/issues/11118)) ([2456b94](https://github.com/googleapis/google-cloud-go/commit/2456b943b7b8aaabd4d8bfb7572c0f477ae0db45)), refs [#7556](https://github.com/googleapis/google-cloud-go/issues/7556) + +## [0.10.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.10.0...auth/v0.10.1) (2024-11-06) + + +### Bug Fixes + +* **auth:** Restore Application Default Credentials support to idtoken ([#11083](https://github.com/googleapis/google-cloud-go/issues/11083)) ([8771f2e](https://github.com/googleapis/google-cloud-go/commit/8771f2ea9807ab822083808e0678392edff3b4f2)) +* **auth:** Skip impersonate universe domain check if empty ([#11086](https://github.com/googleapis/google-cloud-go/issues/11086)) ([87159c1](https://github.com/googleapis/google-cloud-go/commit/87159c1059d4a18d1367ce62746a838a94964ab6)) + +## [0.10.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.9...auth/v0.10.0) (2024-10-30) + + +### Features + +* **auth:** Add universe domain support to credentials/impersonate ([#10953](https://github.com/googleapis/google-cloud-go/issues/10953)) ([e06cb64](https://github.com/googleapis/google-cloud-go/commit/e06cb6499f7eda3aef08ab18ff197016f667684b)) + +## [0.9.9](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.8...auth/v0.9.9) (2024-10-22) + + +### Bug Fixes + +* **auth:** Fallback cert lookups for missing files ([#11013](https://github.com/googleapis/google-cloud-go/issues/11013)) ([bd76695](https://github.com/googleapis/google-cloud-go/commit/bd766957ec238b7c40ddbabb369e612dc9b07313)), refs [#10844](https://github.com/googleapis/google-cloud-go/issues/10844) +* **auth:** Replace MDS endpoint universe_domain with universe-domain ([#11000](https://github.com/googleapis/google-cloud-go/issues/11000)) ([6a1586f](https://github.com/googleapis/google-cloud-go/commit/6a1586f2ce9974684affaea84e7b629313b4d114)) + +## [0.9.8](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.7...auth/v0.9.8) (2024-10-09) + + +### Bug Fixes + +* **auth:** Restore OpenTelemetry handling in transports ([#10968](https://github.com/googleapis/google-cloud-go/issues/10968)) ([08c6d04](https://github.com/googleapis/google-cloud-go/commit/08c6d04901c1a20e219b2d86df41dbaa6d7d7b55)), refs [#10962](https://github.com/googleapis/google-cloud-go/issues/10962) +* **auth:** Try talk to plaintext S2A if credentials can not be found for mTLS-S2A ([#10941](https://github.com/googleapis/google-cloud-go/issues/10941)) ([0f0bf2d](https://github.com/googleapis/google-cloud-go/commit/0f0bf2d18c97dd8b65bcf0099f0802b5631c6287)) + +## [0.9.7](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.6...auth/v0.9.7) (2024-10-01) + + +### Bug Fixes + +* **auth:** Restore support for non-default service accounts for DirectPath ([#10937](https://github.com/googleapis/google-cloud-go/issues/10937)) ([a38650e](https://github.com/googleapis/google-cloud-go/commit/a38650edbf420223077498cafa537aec74b37aad)), refs [#10907](https://github.com/googleapis/google-cloud-go/issues/10907) + +## [0.9.6](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.5...auth/v0.9.6) (2024-09-30) + + +### Bug Fixes + +* **auth:** Make aws credentials provider retrieve fresh credentials ([#10920](https://github.com/googleapis/google-cloud-go/issues/10920)) ([250fbf8](https://github.com/googleapis/google-cloud-go/commit/250fbf87d858d865e399a241b7e537c4ff0c3dd8)) + +## [0.9.5](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.4...auth/v0.9.5) (2024-09-25) + + +### Bug Fixes + +* **auth:** Restore support for GOOGLE_CLOUD_UNIVERSE_DOMAIN env ([#10915](https://github.com/googleapis/google-cloud-go/issues/10915)) ([94caaaa](https://github.com/googleapis/google-cloud-go/commit/94caaaa061362d0e00ef6214afcc8a0a3e7ebfb2)) +* **auth:** Skip directpath credentials overwrite when it's not on GCE ([#10833](https://github.com/googleapis/google-cloud-go/issues/10833)) ([7e5e8d1](https://github.com/googleapis/google-cloud-go/commit/7e5e8d10b761b0a6e43e19a028528db361bc07b1)) +* **auth:** Use new context for non-blocking token refresh ([#10919](https://github.com/googleapis/google-cloud-go/issues/10919)) ([cf7102d](https://github.com/googleapis/google-cloud-go/commit/cf7102d33a21be1e5a9d47a49456b3a57c43b350)) + +## [0.9.4](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.3...auth/v0.9.4) (2024-09-11) + + +### Bug Fixes + +* **auth:** Enable self-signed JWT for non-GDU universe domain ([#10831](https://github.com/googleapis/google-cloud-go/issues/10831)) ([f9869f7](https://github.com/googleapis/google-cloud-go/commit/f9869f7903cfd34d1b97c25d0dc5669d2c5138e6)) + +## [0.9.3](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.2...auth/v0.9.3) (2024-09-03) + + +### Bug Fixes + +* **auth:** Choose quota project envvar over file when both present ([#10807](https://github.com/googleapis/google-cloud-go/issues/10807)) ([2d8dd77](https://github.com/googleapis/google-cloud-go/commit/2d8dd7700eff92d4b95027be55e26e1e7aa79181)), refs [#10804](https://github.com/googleapis/google-cloud-go/issues/10804) + +## [0.9.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.1...auth/v0.9.2) (2024-08-30) + + +### Bug Fixes + +* **auth:** Handle non-Transport DefaultTransport ([#10733](https://github.com/googleapis/google-cloud-go/issues/10733)) ([98d91dc](https://github.com/googleapis/google-cloud-go/commit/98d91dc8316b247498fab41ab35e57a0446fe556)), refs [#10742](https://github.com/googleapis/google-cloud-go/issues/10742) +* **auth:** Make sure quota option takes precedence over env/file ([#10797](https://github.com/googleapis/google-cloud-go/issues/10797)) ([f1b050d](https://github.com/googleapis/google-cloud-go/commit/f1b050d56d804b245cab048c2980d32b0eaceb4e)), refs [#10795](https://github.com/googleapis/google-cloud-go/issues/10795) + + +### Documentation + +* **auth:** Fix Go doc comment link ([#10751](https://github.com/googleapis/google-cloud-go/issues/10751)) ([015acfa](https://github.com/googleapis/google-cloud-go/commit/015acfab4d172650928bb1119bc2cd6307b9a437)) + +## [0.9.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.0...auth/v0.9.1) (2024-08-22) + + +### Bug Fixes + +* **auth:** Setting expireEarly to default when the value is 0 ([#10732](https://github.com/googleapis/google-cloud-go/issues/10732)) ([5e67869](https://github.com/googleapis/google-cloud-go/commit/5e67869a31e9e8ecb4eeebd2cfa11a761c3b1948)) + +## [0.9.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.8.1...auth/v0.9.0) (2024-08-16) + + +### Features + +* **auth:** Auth library can talk to S2A over mTLS ([#10634](https://github.com/googleapis/google-cloud-go/issues/10634)) ([5250a13](https://github.com/googleapis/google-cloud-go/commit/5250a13ec95b8d4eefbe0158f82857ff2189cb45)) + +## [0.8.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.8.0...auth/v0.8.1) (2024-08-13) + + +### Bug Fixes + +* **auth:** Make default client creation more lenient ([#10669](https://github.com/googleapis/google-cloud-go/issues/10669)) ([1afb9ee](https://github.com/googleapis/google-cloud-go/commit/1afb9ee1ee9de9810722800018133304a0ca34d1)), refs [#10638](https://github.com/googleapis/google-cloud-go/issues/10638) + +## [0.8.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.7.3...auth/v0.8.0) (2024-08-07) + + +### Features + +* **auth:** Adds support for X509 workload identity federation ([#10373](https://github.com/googleapis/google-cloud-go/issues/10373)) ([5d07505](https://github.com/googleapis/google-cloud-go/commit/5d075056cbe27bb1da4072a26070c41f8999eb9b)) + +## [0.7.3](https://github.com/googleapis/google-cloud-go/compare/auth/v0.7.2...auth/v0.7.3) (2024-08-01) + + +### Bug Fixes + +* **auth/oauth2adapt:** Update dependencies ([257c40b](https://github.com/googleapis/google-cloud-go/commit/257c40bd6d7e59730017cf32bda8823d7a232758)) +* **auth:** Disable automatic universe domain check for MDS ([#10620](https://github.com/googleapis/google-cloud-go/issues/10620)) ([7cea5ed](https://github.com/googleapis/google-cloud-go/commit/7cea5edd5a0c1e6bca558696f5607879141910e8)) +* **auth:** Update dependencies ([257c40b](https://github.com/googleapis/google-cloud-go/commit/257c40bd6d7e59730017cf32bda8823d7a232758)) + +## [0.7.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.7.1...auth/v0.7.2) (2024-07-22) + + +### Bug Fixes + +* **auth:** Use default client for universe metadata lookup ([#10551](https://github.com/googleapis/google-cloud-go/issues/10551)) ([d9046fd](https://github.com/googleapis/google-cloud-go/commit/d9046fdd1435d1ce48f374806c1def4cb5ac6cd3)), refs [#10544](https://github.com/googleapis/google-cloud-go/issues/10544) + +## [0.7.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.7.0...auth/v0.7.1) (2024-07-10) + + +### Bug Fixes + +* **auth:** Bump google.golang.org/grpc@v1.64.1 ([8ecc4e9](https://github.com/googleapis/google-cloud-go/commit/8ecc4e9622e5bbe9b90384d5848ab816027226c5)) + +## [0.7.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.6.1...auth/v0.7.0) (2024-07-09) + + +### Features + +* **auth:** Add workload X509 cert provider as a default cert provider ([#10479](https://github.com/googleapis/google-cloud-go/issues/10479)) ([c51ee6c](https://github.com/googleapis/google-cloud-go/commit/c51ee6cf65ce05b4d501083e49d468c75ac1ea63)) + + +### Bug Fixes + +* **auth/oauth2adapt:** Bump google.golang.org/api@v0.187.0 ([8fa9e39](https://github.com/googleapis/google-cloud-go/commit/8fa9e398e512fd8533fd49060371e61b5725a85b)) +* **auth:** Bump google.golang.org/api@v0.187.0 ([8fa9e39](https://github.com/googleapis/google-cloud-go/commit/8fa9e398e512fd8533fd49060371e61b5725a85b)) +* **auth:** Check len of slices, not non-nil ([#10483](https://github.com/googleapis/google-cloud-go/issues/10483)) ([0a966a1](https://github.com/googleapis/google-cloud-go/commit/0a966a183e5f0e811977216d736d875b7233e942)) + +## [0.6.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.6.0...auth/v0.6.1) (2024-07-01) + + +### Bug Fixes + +* **auth:** Support gRPC API keys ([#10460](https://github.com/googleapis/google-cloud-go/issues/10460)) ([daa6646](https://github.com/googleapis/google-cloud-go/commit/daa6646d2af5d7fb5b30489f4934c7db89868c7c)) +* **auth:** Update http and grpc transports to support token exchange over mTLS ([#10397](https://github.com/googleapis/google-cloud-go/issues/10397)) ([c6dfdcf](https://github.com/googleapis/google-cloud-go/commit/c6dfdcf893c3f971eba15026c12db0a960ae81f2)) + +## [0.6.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.5.2...auth/v0.6.0) (2024-06-25) + + +### Features + +* **auth:** Add non-blocking token refresh for compute MDS ([#10263](https://github.com/googleapis/google-cloud-go/issues/10263)) ([9ac350d](https://github.com/googleapis/google-cloud-go/commit/9ac350da11a49b8e2174d3fc5b1a5070fec78b4e)) + + +### Bug Fixes + +* **auth:** Return error if envvar detected file returns an error ([#10431](https://github.com/googleapis/google-cloud-go/issues/10431)) ([e52b9a7](https://github.com/googleapis/google-cloud-go/commit/e52b9a7c45468827f5d220ab00965191faeb9d05)) + +## [0.5.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.5.1...auth/v0.5.2) (2024-06-24) + + +### Bug Fixes + +* **auth:** Fetch initial token when CachedTokenProviderOptions.DisableAutoRefresh is true ([#10415](https://github.com/googleapis/google-cloud-go/issues/10415)) ([3266763](https://github.com/googleapis/google-cloud-go/commit/32667635ca2efad05cd8c087c004ca07d7406913)), refs [#10414](https://github.com/googleapis/google-cloud-go/issues/10414) + +## [0.5.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.5.0...auth/v0.5.1) (2024-05-31) + + +### Bug Fixes + +* **auth:** Pass through client to 2LO and 3LO flows ([#10290](https://github.com/googleapis/google-cloud-go/issues/10290)) ([685784e](https://github.com/googleapis/google-cloud-go/commit/685784ea84358c15e9214bdecb307d37aa3b6d2f)) + +## [0.5.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.4.2...auth/v0.5.0) (2024-05-28) + + +### Features + +* **auth:** Adds X509 workload certificate provider ([#10233](https://github.com/googleapis/google-cloud-go/issues/10233)) ([17a9db7](https://github.com/googleapis/google-cloud-go/commit/17a9db73af35e3d1a7a25ac4fd1377a103de6150)) + +## [0.4.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.4.1...auth/v0.4.2) (2024-05-16) + + +### Bug Fixes + +* **auth:** Enable client certificates by default only for GDU ([#10151](https://github.com/googleapis/google-cloud-go/issues/10151)) ([7c52978](https://github.com/googleapis/google-cloud-go/commit/7c529786275a39b7e00525f7d5e7be0d963e9e15)) +* **auth:** Handle non-Transport DefaultTransport ([#10162](https://github.com/googleapis/google-cloud-go/issues/10162)) ([fa3bfdb](https://github.com/googleapis/google-cloud-go/commit/fa3bfdb23aaa45b34394a8b61e753b3587506782)), refs [#10159](https://github.com/googleapis/google-cloud-go/issues/10159) +* **auth:** Have refresh time match docs ([#10147](https://github.com/googleapis/google-cloud-go/issues/10147)) ([bcb5568](https://github.com/googleapis/google-cloud-go/commit/bcb5568c07a54dd3d2e869d15f502b0741a609e8)) +* **auth:** Update compute token fetching error with named prefix ([#10180](https://github.com/googleapis/google-cloud-go/issues/10180)) ([4573504](https://github.com/googleapis/google-cloud-go/commit/4573504828d2928bebedc875d87650ba227829ea)) + +## [0.4.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.4.0...auth/v0.4.1) (2024-05-09) + + +### Bug Fixes + +* **auth:** Don't try to detect default creds it opt configured ([#10143](https://github.com/googleapis/google-cloud-go/issues/10143)) ([804632e](https://github.com/googleapis/google-cloud-go/commit/804632e7c5b0b85ff522f7951114485e256eb5bc)) + +## [0.4.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.3.0...auth/v0.4.0) (2024-05-07) + + +### Features + +* **auth:** Enable client certificates by default ([#10102](https://github.com/googleapis/google-cloud-go/issues/10102)) ([9013e52](https://github.com/googleapis/google-cloud-go/commit/9013e5200a6ec0f178ed91acb255481ffb073a2c)) + + +### Bug Fixes + +* **auth:** Get s2a logic up to date ([#10093](https://github.com/googleapis/google-cloud-go/issues/10093)) ([4fe9ae4](https://github.com/googleapis/google-cloud-go/commit/4fe9ae4b7101af2a5221d6d6b2e77b479305bb06)) + +## [0.3.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.2.2...auth/v0.3.0) (2024-04-23) + + +### Features + +* **auth/httptransport:** Add ability to customize transport ([#10023](https://github.com/googleapis/google-cloud-go/issues/10023)) ([72c7f6b](https://github.com/googleapis/google-cloud-go/commit/72c7f6bbec3136cc7a62788fc7186bc33ef6c3b3)), refs [#9812](https://github.com/googleapis/google-cloud-go/issues/9812) [#9814](https://github.com/googleapis/google-cloud-go/issues/9814) + + +### Bug Fixes + +* **auth/credentials:** Error on bad file name if explicitly set ([#10018](https://github.com/googleapis/google-cloud-go/issues/10018)) ([55beaa9](https://github.com/googleapis/google-cloud-go/commit/55beaa993aaf052d8be39766afc6777c3c2a0bdd)), refs [#9809](https://github.com/googleapis/google-cloud-go/issues/9809) + +## [0.2.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.2.1...auth/v0.2.2) (2024-04-19) + + +### Bug Fixes + +* **auth:** Add internal opt to skip validation on transports ([#9999](https://github.com/googleapis/google-cloud-go/issues/9999)) ([9e20ef8](https://github.com/googleapis/google-cloud-go/commit/9e20ef89f6287d6bd03b8697d5898dc43b4a77cf)), refs [#9823](https://github.com/googleapis/google-cloud-go/issues/9823) +* **auth:** Set secure flag for gRPC conn pools ([#10002](https://github.com/googleapis/google-cloud-go/issues/10002)) ([14e3956](https://github.com/googleapis/google-cloud-go/commit/14e3956dfd736399731b5ee8d9b178ae085cf7ba)), refs [#9833](https://github.com/googleapis/google-cloud-go/issues/9833) + +## [0.2.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.2.0...auth/v0.2.1) (2024-04-18) + + +### Bug Fixes + +* **auth:** Default gRPC token type to Bearer if not set ([#9800](https://github.com/googleapis/google-cloud-go/issues/9800)) ([5284066](https://github.com/googleapis/google-cloud-go/commit/5284066670b6fe65d79089cfe0199c9660f87fc7)) + +## [0.2.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.1.1...auth/v0.2.0) (2024-04-15) + +### Breaking Changes + +In the below mentioned commits there were a few large breaking changes since the +last release of the module. + +1. The `Credentials` type has been moved to the root of the module as it is + becoming the core abstraction for the whole module. +2. Because of the above mentioned change many functions that previously + returned a `TokenProvider` now return `Credentials`. Similarly, these + functions have been renamed to be more specific. +3. Most places that used to take an optional `TokenProvider` now accept + `Credentials`. You can make a `Credentials` from a `TokenProvider` using the + constructor found in the `auth` package. +4. The `detect` package has been renamed to `credentials`. With this change some + function signatures were also updated for better readability. +5. Derivative auth flows like `impersonate` and `downscope` have been moved to + be under the new `credentials` package. + +Although these changes are disruptive we think that they are for the best of the +long-term health of the module. We do not expect any more large breaking changes +like these in future revisions, even before 1.0.0. This version will be the +first version of the auth library that our client libraries start to use and +depend on. + +### Features + +* **auth/credentials/externalaccount:** Add default TokenURL ([#9700](https://github.com/googleapis/google-cloud-go/issues/9700)) ([81830e6](https://github.com/googleapis/google-cloud-go/commit/81830e6848ceefd055aa4d08f933d1154455a0f6)) +* **auth:** Add downscope.Options.UniverseDomain ([#9634](https://github.com/googleapis/google-cloud-go/issues/9634)) ([52cf7d7](https://github.com/googleapis/google-cloud-go/commit/52cf7d780853594291c4e34302d618299d1f5a1d)) +* **auth:** Add universe domain to grpctransport and httptransport ([#9663](https://github.com/googleapis/google-cloud-go/issues/9663)) ([67d353b](https://github.com/googleapis/google-cloud-go/commit/67d353beefe3b607c08c891876fbd95ab89e5fe3)), refs [#9670](https://github.com/googleapis/google-cloud-go/issues/9670) +* **auth:** Add UniverseDomain to DetectOptions ([#9536](https://github.com/googleapis/google-cloud-go/issues/9536)) ([3618d3f](https://github.com/googleapis/google-cloud-go/commit/3618d3f7061615c0e189f376c75abc201203b501)) +* **auth:** Make package externalaccount public ([#9633](https://github.com/googleapis/google-cloud-go/issues/9633)) ([a0978d8](https://github.com/googleapis/google-cloud-go/commit/a0978d8e96968399940ebd7d092539772bf9caac)) +* **auth:** Move credentials to base auth package ([#9590](https://github.com/googleapis/google-cloud-go/issues/9590)) ([1a04baf](https://github.com/googleapis/google-cloud-go/commit/1a04bafa83c27342b9308d785645e1e5423ea10d)) +* **auth:** Refactor public sigs to use Credentials ([#9603](https://github.com/googleapis/google-cloud-go/issues/9603)) ([69cb240](https://github.com/googleapis/google-cloud-go/commit/69cb240c530b1f7173a9af2555c19e9a1beb56c5)) + + +### Bug Fixes + +* **auth/oauth2adapt:** Update protobuf dep to v1.33.0 ([30b038d](https://github.com/googleapis/google-cloud-go/commit/30b038d8cac0b8cd5dd4761c87f3f298760dd33a)) +* **auth:** Fix uint32 conversion ([9221c7f](https://github.com/googleapis/google-cloud-go/commit/9221c7fa12cef9d5fb7ddc92f41f1d6204971c7b)) +* **auth:** Port sts expires fix ([#9618](https://github.com/googleapis/google-cloud-go/issues/9618)) ([7bec97b](https://github.com/googleapis/google-cloud-go/commit/7bec97b2f51ed3ac4f9b88bf100d301da3f5d1bd)) +* **auth:** Read universe_domain from all credentials files ([#9632](https://github.com/googleapis/google-cloud-go/issues/9632)) ([16efbb5](https://github.com/googleapis/google-cloud-go/commit/16efbb52e39ea4a319e5ee1e95c0e0305b6d9824)) +* **auth:** Remove content-type header from idms get requests ([#9508](https://github.com/googleapis/google-cloud-go/issues/9508)) ([8589f41](https://github.com/googleapis/google-cloud-go/commit/8589f41599d265d7c3d46a3d86c9fab2329cbdd9)) +* **auth:** Update protobuf dep to v1.33.0 ([30b038d](https://github.com/googleapis/google-cloud-go/commit/30b038d8cac0b8cd5dd4761c87f3f298760dd33a)) + +## [0.1.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.1.0...auth/v0.1.1) (2024-03-10) + + +### Bug Fixes + +* **auth/impersonate:** Properly send default detect params ([#9529](https://github.com/googleapis/google-cloud-go/issues/9529)) ([5b6b8be](https://github.com/googleapis/google-cloud-go/commit/5b6b8bef577f82707e51f5cc5d258d5bdf90218f)), refs [#9136](https://github.com/googleapis/google-cloud-go/issues/9136) +* **auth:** Update grpc-go to v1.56.3 ([343cea8](https://github.com/googleapis/google-cloud-go/commit/343cea8c43b1e31ae21ad50ad31d3b0b60143f8c)) +* **auth:** Update grpc-go to v1.59.0 ([81a97b0](https://github.com/googleapis/google-cloud-go/commit/81a97b06cb28b25432e4ece595c55a9857e960b7)) + +## 0.1.0 (2023-10-18) + + +### Features + +* **auth:** Add base auth package ([#8465](https://github.com/googleapis/google-cloud-go/issues/8465)) ([6a45f26](https://github.com/googleapis/google-cloud-go/commit/6a45f26b809b64edae21f312c18d4205f96b180e)) +* **auth:** Add cert support to httptransport ([#8569](https://github.com/googleapis/google-cloud-go/issues/8569)) ([37e3435](https://github.com/googleapis/google-cloud-go/commit/37e3435f8e98595eafab481bdfcb31a4c56fa993)) +* **auth:** Add Credentials.UniverseDomain() ([#8654](https://github.com/googleapis/google-cloud-go/issues/8654)) ([af0aa1e](https://github.com/googleapis/google-cloud-go/commit/af0aa1ed8015bc8fe0dd87a7549ae029107cbdb8)) +* **auth:** Add detect package ([#8491](https://github.com/googleapis/google-cloud-go/issues/8491)) ([d977419](https://github.com/googleapis/google-cloud-go/commit/d977419a3269f6acc193df77a2136a6eb4b4add7)) +* **auth:** Add downscope package ([#8532](https://github.com/googleapis/google-cloud-go/issues/8532)) ([dda9bff](https://github.com/googleapis/google-cloud-go/commit/dda9bff8ec70e6d104901b4105d13dcaa4e2404c)) +* **auth:** Add grpctransport package ([#8625](https://github.com/googleapis/google-cloud-go/issues/8625)) ([69a8347](https://github.com/googleapis/google-cloud-go/commit/69a83470bdcc7ed10c6c36d1abc3b7cfdb8a0ee5)) +* **auth:** Add httptransport package ([#8567](https://github.com/googleapis/google-cloud-go/issues/8567)) ([6898597](https://github.com/googleapis/google-cloud-go/commit/6898597d2ea95d630fcd00fd15c58c75ea843bff)) +* **auth:** Add idtoken package ([#8580](https://github.com/googleapis/google-cloud-go/issues/8580)) ([a79e693](https://github.com/googleapis/google-cloud-go/commit/a79e693e97e4e3e1c6742099af3dbc58866d88fe)) +* **auth:** Add impersonate package ([#8578](https://github.com/googleapis/google-cloud-go/issues/8578)) ([e29ba0c](https://github.com/googleapis/google-cloud-go/commit/e29ba0cb7bd3888ab9e808087027dc5a32474c04)) +* **auth:** Add support for external accounts in detect ([#8508](https://github.com/googleapis/google-cloud-go/issues/8508)) ([62210d5](https://github.com/googleapis/google-cloud-go/commit/62210d5d3e56e8e9f35db8e6ac0defec19582507)) +* **auth:** Port external account changes ([#8697](https://github.com/googleapis/google-cloud-go/issues/8697)) ([5823db5](https://github.com/googleapis/google-cloud-go/commit/5823db5d633069999b58b9131a7f9cd77e82c899)) + + +### Bug Fixes + +* **auth/oauth2adapt:** Update golang.org/x/net to v0.17.0 ([174da47](https://github.com/googleapis/google-cloud-go/commit/174da47254fefb12921bbfc65b7829a453af6f5d)) +* **auth:** Update golang.org/x/net to v0.17.0 ([174da47](https://github.com/googleapis/google-cloud-go/commit/174da47254fefb12921bbfc65b7829a453af6f5d)) diff --git a/plugins/traefik/vendor/github.com/google/pprof/LICENSE b/plugins/traefik/vendor/cloud.google.com/go/auth/LICENSE similarity index 100% rename from plugins/traefik/vendor/github.com/google/pprof/LICENSE rename to plugins/traefik/vendor/cloud.google.com/go/auth/LICENSE diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/README.md b/plugins/traefik/vendor/cloud.google.com/go/auth/README.md new file mode 100644 index 000000000..6fe4f0763 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/README.md @@ -0,0 +1,40 @@ +# Google Auth Library for Go + +[![Go Reference](https://pkg.go.dev/badge/cloud.google.com/go/auth.svg)](https://pkg.go.dev/cloud.google.com/go/auth) + +## Install + +``` bash +go get cloud.google.com/go/auth@latest +``` + +## Usage + +The most common way this library is used is transitively, by default, from any +of our Go client libraries. + +### Notable use-cases + +- To create a credential directly please see examples in the + [credentials](https://pkg.go.dev/cloud.google.com/go/auth/credentials) + package. +- To create a authenticated HTTP client please see examples in the + [httptransport](https://pkg.go.dev/cloud.google.com/go/auth/httptransport) + package. +- To create a authenticated gRPC connection please see examples in the + [grpctransport](https://pkg.go.dev/cloud.google.com/go/auth/grpctransport) + package. +- To create an ID token please see examples in the + [idtoken](https://pkg.go.dev/cloud.google.com/go/auth/credentials/idtoken) + package. + +## Contributing + +Contributions are welcome. Please, see the +[CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md) +document for details. + +Please note that this project is released with a Contributor Code of Conduct. +By participating in this project you agree to abide by its terms. +See [Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md#contributor-code-of-conduct) +for more information. diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/auth.go b/plugins/traefik/vendor/cloud.google.com/go/auth/auth.go new file mode 100644 index 000000000..c6d801583 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/auth.go @@ -0,0 +1,618 @@ +// Copyright 2023 Google LLC +// +// 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 auth provides utilities for managing Google Cloud credentials, +// including functionality for creating, caching, and refreshing OAuth2 tokens. +// It offers customizable options for different OAuth2 flows, such as 2-legged +// (2LO) and 3-legged (3LO) OAuth, along with support for PKCE and automatic +// token management. +package auth + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "log/slog" + "net/http" + "net/url" + "strings" + "sync" + "time" + + "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/jwt" + "github.com/googleapis/gax-go/v2/internallog" +) + +const ( + // Parameter keys for AuthCodeURL method to support PKCE. + codeChallengeKey = "code_challenge" + codeChallengeMethodKey = "code_challenge_method" + + // Parameter key for Exchange method to support PKCE. + codeVerifierKey = "code_verifier" + + // 3 minutes and 45 seconds before expiration. The shortest MDS cache is 4 minutes, + // so we give it 15 seconds to refresh it's cache before attempting to refresh a token. + defaultExpiryDelta = 225 * time.Second + + universeDomainDefault = "googleapis.com" +) + +// tokenState represents different states for a [Token]. +type tokenState int + +const ( + // fresh indicates that the [Token] is valid. It is not expired or close to + // expired, or the token has no expiry. + fresh tokenState = iota + // stale indicates that the [Token] is close to expired, and should be + // refreshed. The token can be used normally. + stale + // invalid indicates that the [Token] is expired or invalid. The token + // cannot be used for a normal operation. + invalid +) + +var ( + defaultGrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer" + defaultHeader = &jwt.Header{Algorithm: jwt.HeaderAlgRSA256, Type: jwt.HeaderType} + + // for testing + timeNow = time.Now +) + +// TokenProvider specifies an interface for anything that can return a token. +type TokenProvider interface { + // Token returns a Token or an error. + // The Token returned must be safe to use + // concurrently. + // The returned Token must not be modified. + // The context provided must be sent along to any requests that are made in + // the implementing code. + Token(context.Context) (*Token, error) +} + +// Token holds the credential token used to authorized requests. All fields are +// considered read-only. +type Token struct { + // Value is the token used to authorize requests. It is usually an access + // token but may be other types of tokens such as ID tokens in some flows. + Value string + // Type is the type of token Value is. If uninitialized, it should be + // assumed to be a "Bearer" token. + Type string + // Expiry is the time the token is set to expire. + Expiry time.Time + // Metadata may include, but is not limited to, the body of the token + // response returned by the server. + Metadata map[string]interface{} // TODO(codyoss): maybe make a method to flatten metadata to avoid []string for url.Values +} + +// IsValid reports that a [Token] is non-nil, has a [Token.Value], and has not +// expired. A token is considered expired if [Token.Expiry] has passed or will +// pass in the next 225 seconds. +func (t *Token) IsValid() bool { + return t.isValidWithEarlyExpiry(defaultExpiryDelta) +} + +// MetadataString is a convenience method for accessing string values in the +// token's metadata. Returns an empty string if the metadata is nil or the value +// for the given key cannot be cast to a string. +func (t *Token) MetadataString(k string) string { + if t.Metadata == nil { + return "" + } + s, ok := t.Metadata[k].(string) + if !ok { + return "" + } + return s +} + +func (t *Token) isValidWithEarlyExpiry(earlyExpiry time.Duration) bool { + if t.isEmpty() { + return false + } + if t.Expiry.IsZero() { + return true + } + return !t.Expiry.Round(0).Add(-earlyExpiry).Before(timeNow()) +} + +func (t *Token) isEmpty() bool { + return t == nil || t.Value == "" +} + +// Credentials holds Google credentials, including +// [Application Default Credentials]. +// +// [Application Default Credentials]: https://developers.google.com/accounts/docs/application-default-credentials +type Credentials struct { + json []byte + projectID CredentialsPropertyProvider + quotaProjectID CredentialsPropertyProvider + // universeDomain is the default service domain for a given Cloud universe. + universeDomain CredentialsPropertyProvider + + TokenProvider +} + +// JSON returns the bytes associated with the the file used to source +// credentials if one was used. +func (c *Credentials) JSON() []byte { + return c.json +} + +// ProjectID returns the associated project ID from the underlying file or +// environment. +func (c *Credentials) ProjectID(ctx context.Context) (string, error) { + if c.projectID == nil { + return internal.GetProjectID(c.json, ""), nil + } + v, err := c.projectID.GetProperty(ctx) + if err != nil { + return "", err + } + return internal.GetProjectID(c.json, v), nil +} + +// QuotaProjectID returns the associated quota project ID from the underlying +// file or environment. +func (c *Credentials) QuotaProjectID(ctx context.Context) (string, error) { + if c.quotaProjectID == nil { + return internal.GetQuotaProject(c.json, ""), nil + } + v, err := c.quotaProjectID.GetProperty(ctx) + if err != nil { + return "", err + } + return internal.GetQuotaProject(c.json, v), nil +} + +// UniverseDomain returns the default service domain for a given Cloud universe. +// The default value is "googleapis.com". +func (c *Credentials) UniverseDomain(ctx context.Context) (string, error) { + if c.universeDomain == nil { + return universeDomainDefault, nil + } + v, err := c.universeDomain.GetProperty(ctx) + if err != nil { + return "", err + } + if v == "" { + return universeDomainDefault, nil + } + return v, err +} + +// CredentialsPropertyProvider provides an implementation to fetch a property +// value for [Credentials]. +type CredentialsPropertyProvider interface { + GetProperty(context.Context) (string, error) +} + +// CredentialsPropertyFunc is a type adapter to allow the use of ordinary +// functions as a [CredentialsPropertyProvider]. +type CredentialsPropertyFunc func(context.Context) (string, error) + +// GetProperty loads the properly value provided the given context. +func (p CredentialsPropertyFunc) GetProperty(ctx context.Context) (string, error) { + return p(ctx) +} + +// CredentialsOptions are used to configure [Credentials]. +type CredentialsOptions struct { + // TokenProvider is a means of sourcing a token for the credentials. Required. + TokenProvider TokenProvider + // JSON is the raw contents of the credentials file if sourced from a file. + JSON []byte + // ProjectIDProvider resolves the project ID associated with the + // credentials. + ProjectIDProvider CredentialsPropertyProvider + // QuotaProjectIDProvider resolves the quota project ID associated with the + // credentials. + QuotaProjectIDProvider CredentialsPropertyProvider + // UniverseDomainProvider resolves the universe domain with the credentials. + UniverseDomainProvider CredentialsPropertyProvider +} + +// NewCredentials returns new [Credentials] from the provided options. +func NewCredentials(opts *CredentialsOptions) *Credentials { + creds := &Credentials{ + TokenProvider: opts.TokenProvider, + json: opts.JSON, + projectID: opts.ProjectIDProvider, + quotaProjectID: opts.QuotaProjectIDProvider, + universeDomain: opts.UniverseDomainProvider, + } + + return creds +} + +// CachedTokenProviderOptions provides options for configuring a cached +// [TokenProvider]. +type CachedTokenProviderOptions struct { + // DisableAutoRefresh makes the TokenProvider always return the same token, + // even if it is expired. The default is false. Optional. + DisableAutoRefresh bool + // ExpireEarly configures the amount of time before a token expires, that it + // should be refreshed. If unset, the default value is 3 minutes and 45 + // seconds. Optional. + ExpireEarly time.Duration + // DisableAsyncRefresh configures a synchronous workflow that refreshes + // tokens in a blocking manner. The default is false. Optional. + DisableAsyncRefresh bool +} + +func (ctpo *CachedTokenProviderOptions) autoRefresh() bool { + if ctpo == nil { + return true + } + return !ctpo.DisableAutoRefresh +} + +func (ctpo *CachedTokenProviderOptions) expireEarly() time.Duration { + if ctpo == nil || ctpo.ExpireEarly == 0 { + return defaultExpiryDelta + } + return ctpo.ExpireEarly +} + +func (ctpo *CachedTokenProviderOptions) blockingRefresh() bool { + if ctpo == nil { + return false + } + return ctpo.DisableAsyncRefresh +} + +// NewCachedTokenProvider wraps a [TokenProvider] to cache the tokens returned +// by the underlying provider. By default it will refresh tokens asynchronously +// a few minutes before they expire. +func NewCachedTokenProvider(tp TokenProvider, opts *CachedTokenProviderOptions) TokenProvider { + if ctp, ok := tp.(*cachedTokenProvider); ok { + return ctp + } + return &cachedTokenProvider{ + tp: tp, + autoRefresh: opts.autoRefresh(), + expireEarly: opts.expireEarly(), + blockingRefresh: opts.blockingRefresh(), + } +} + +type cachedTokenProvider struct { + tp TokenProvider + autoRefresh bool + expireEarly time.Duration + blockingRefresh bool + + mu sync.Mutex + cachedToken *Token + // isRefreshRunning ensures that the non-blocking refresh will only be + // attempted once, even if multiple callers enter the Token method. + isRefreshRunning bool + // isRefreshErr ensures that the non-blocking refresh will only be attempted + // once per refresh window if an error is encountered. + isRefreshErr bool +} + +func (c *cachedTokenProvider) Token(ctx context.Context) (*Token, error) { + if c.blockingRefresh { + return c.tokenBlocking(ctx) + } + return c.tokenNonBlocking(ctx) +} + +func (c *cachedTokenProvider) tokenNonBlocking(ctx context.Context) (*Token, error) { + switch c.tokenState() { + case fresh: + c.mu.Lock() + defer c.mu.Unlock() + return c.cachedToken, nil + case stale: + // Call tokenAsync with a new Context because the user-provided context + // may have a short timeout incompatible with async token refresh. + c.tokenAsync(context.Background()) + // Return the stale token immediately to not block customer requests to Cloud services. + c.mu.Lock() + defer c.mu.Unlock() + return c.cachedToken, nil + default: // invalid + return c.tokenBlocking(ctx) + } +} + +// tokenState reports the token's validity. +func (c *cachedTokenProvider) tokenState() tokenState { + c.mu.Lock() + defer c.mu.Unlock() + t := c.cachedToken + now := timeNow() + if t == nil || t.Value == "" { + return invalid + } else if t.Expiry.IsZero() { + return fresh + } else if now.After(t.Expiry.Round(0)) { + return invalid + } else if now.After(t.Expiry.Round(0).Add(-c.expireEarly)) { + return stale + } + return fresh +} + +// tokenAsync uses a bool to ensure that only one non-blocking token refresh +// happens at a time, even if multiple callers have entered this function +// concurrently. This avoids creating an arbitrary number of concurrent +// goroutines. Retries should be attempted and managed within the Token method. +// If the refresh attempt fails, no further attempts are made until the refresh +// window expires and the token enters the invalid state, at which point the +// blocking call to Token should likely return the same error on the main goroutine. +func (c *cachedTokenProvider) tokenAsync(ctx context.Context) { + fn := func() { + t, err := c.tp.Token(ctx) + c.mu.Lock() + defer c.mu.Unlock() + c.isRefreshRunning = false + if err != nil { + // Discard errors from the non-blocking refresh, but prevent further + // attempts. + c.isRefreshErr = true + return + } + c.cachedToken = t + } + c.mu.Lock() + defer c.mu.Unlock() + if !c.isRefreshRunning && !c.isRefreshErr { + c.isRefreshRunning = true + go fn() + } +} + +func (c *cachedTokenProvider) tokenBlocking(ctx context.Context) (*Token, error) { + c.mu.Lock() + defer c.mu.Unlock() + c.isRefreshErr = false + if c.cachedToken.IsValid() || (!c.autoRefresh && !c.cachedToken.isEmpty()) { + return c.cachedToken, nil + } + t, err := c.tp.Token(ctx) + if err != nil { + return nil, err + } + c.cachedToken = t + return t, nil +} + +// Error is a error associated with retrieving a [Token]. It can hold useful +// additional details for debugging. +type Error struct { + // Response is the HTTP response associated with error. The body will always + // be already closed and consumed. + Response *http.Response + // Body is the HTTP response body. + Body []byte + // Err is the underlying wrapped error. + Err error + + // code returned in the token response + code string + // description returned in the token response + description string + // uri returned in the token response + uri string +} + +func (e *Error) Error() string { + if e.code != "" { + s := fmt.Sprintf("auth: %q", e.code) + if e.description != "" { + s += fmt.Sprintf(" %q", e.description) + } + if e.uri != "" { + s += fmt.Sprintf(" %q", e.uri) + } + return s + } + return fmt.Sprintf("auth: cannot fetch token: %v\nResponse: %s", e.Response.StatusCode, e.Body) +} + +// Temporary returns true if the error is considered temporary and may be able +// to be retried. +func (e *Error) Temporary() bool { + if e.Response == nil { + return false + } + sc := e.Response.StatusCode + return sc == http.StatusInternalServerError || sc == http.StatusServiceUnavailable || sc == http.StatusRequestTimeout || sc == http.StatusTooManyRequests +} + +func (e *Error) Unwrap() error { + return e.Err +} + +// Style describes how the token endpoint wants to receive the ClientID and +// ClientSecret. +type Style int + +const ( + // StyleUnknown means the value has not been initiated. Sending this in + // a request will cause the token exchange to fail. + StyleUnknown Style = iota + // StyleInParams sends client info in the body of a POST request. + StyleInParams + // StyleInHeader sends client info using Basic Authorization header. + StyleInHeader +) + +// Options2LO is the configuration settings for doing a 2-legged JWT OAuth2 flow. +type Options2LO struct { + // Email is the OAuth2 client ID. This value is set as the "iss" in the + // JWT. + Email string + // PrivateKey contains the contents of an RSA private key or the + // contents of a PEM file that contains a private key. It is used to sign + // the JWT created. + PrivateKey []byte + // TokenURL is th URL the JWT is sent to. Required. + TokenURL string + // PrivateKeyID is the ID of the key used to sign the JWT. It is used as the + // "kid" in the JWT header. Optional. + PrivateKeyID string + // Subject is the used for to impersonate a user. It is used as the "sub" in + // the JWT.m Optional. + Subject string + // Scopes specifies requested permissions for the token. Optional. + Scopes []string + // Expires specifies the lifetime of the token. Optional. + Expires time.Duration + // Audience specifies the "aud" in the JWT. Optional. + Audience string + // PrivateClaims allows specifying any custom claims for the JWT. Optional. + PrivateClaims map[string]interface{} + // UniverseDomain is the default service domain for a given Cloud universe. + UniverseDomain string + + // Client is the client to be used to make the underlying token requests. + // Optional. + Client *http.Client + // UseIDToken requests that the token returned be an ID token if one is + // returned from the server. Optional. + UseIDToken bool + // Logger is used for debug logging. If provided, logging will be enabled + // at the loggers configured level. By default logging is disabled unless + // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default + // logger will be used. Optional. + Logger *slog.Logger +} + +func (o *Options2LO) client() *http.Client { + if o.Client != nil { + return o.Client + } + return internal.DefaultClient() +} + +func (o *Options2LO) validate() error { + if o == nil { + return errors.New("auth: options must be provided") + } + if o.Email == "" { + return errors.New("auth: email must be provided") + } + if len(o.PrivateKey) == 0 { + return errors.New("auth: private key must be provided") + } + if o.TokenURL == "" { + return errors.New("auth: token URL must be provided") + } + return nil +} + +// New2LOTokenProvider returns a [TokenProvider] from the provided options. +func New2LOTokenProvider(opts *Options2LO) (TokenProvider, error) { + if err := opts.validate(); err != nil { + return nil, err + } + return tokenProvider2LO{opts: opts, Client: opts.client(), logger: internallog.New(opts.Logger)}, nil +} + +type tokenProvider2LO struct { + opts *Options2LO + Client *http.Client + logger *slog.Logger +} + +func (tp tokenProvider2LO) Token(ctx context.Context) (*Token, error) { + pk, err := internal.ParseKey(tp.opts.PrivateKey) + if err != nil { + return nil, err + } + claimSet := &jwt.Claims{ + Iss: tp.opts.Email, + Scope: strings.Join(tp.opts.Scopes, " "), + Aud: tp.opts.TokenURL, + AdditionalClaims: tp.opts.PrivateClaims, + Sub: tp.opts.Subject, + } + if t := tp.opts.Expires; t > 0 { + claimSet.Exp = time.Now().Add(t).Unix() + } + if aud := tp.opts.Audience; aud != "" { + claimSet.Aud = aud + } + h := *defaultHeader + h.KeyID = tp.opts.PrivateKeyID + payload, err := jwt.EncodeJWS(&h, claimSet, pk) + if err != nil { + return nil, err + } + v := url.Values{} + v.Set("grant_type", defaultGrantType) + v.Set("assertion", payload) + req, err := http.NewRequestWithContext(ctx, "POST", tp.opts.TokenURL, strings.NewReader(v.Encode())) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + tp.logger.DebugContext(ctx, "2LO token request", "request", internallog.HTTPRequest(req, []byte(v.Encode()))) + resp, body, err := internal.DoRequest(tp.Client, req) + if err != nil { + return nil, fmt.Errorf("auth: cannot fetch token: %w", err) + } + tp.logger.DebugContext(ctx, "2LO token response", "response", internallog.HTTPResponse(resp, body)) + if c := resp.StatusCode; c < http.StatusOK || c >= http.StatusMultipleChoices { + return nil, &Error{ + Response: resp, + Body: body, + } + } + // tokenRes is the JSON response body. + var tokenRes struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + IDToken string `json:"id_token"` + ExpiresIn int64 `json:"expires_in"` + } + if err := json.Unmarshal(body, &tokenRes); err != nil { + return nil, fmt.Errorf("auth: cannot fetch token: %w", err) + } + token := &Token{ + Value: tokenRes.AccessToken, + Type: tokenRes.TokenType, + } + token.Metadata = make(map[string]interface{}) + json.Unmarshal(body, &token.Metadata) // no error checks for optional fields + + if secs := tokenRes.ExpiresIn; secs > 0 { + token.Expiry = time.Now().Add(time.Duration(secs) * time.Second) + } + if v := tokenRes.IDToken; v != "" { + // decode returned id token to get expiry + claimSet, err := jwt.DecodeJWS(v) + if err != nil { + return nil, fmt.Errorf("auth: error decoding JWT token: %w", err) + } + token.Expiry = time.Unix(claimSet.Exp, 0) + } + if tp.opts.UseIDToken { + if tokenRes.IDToken == "" { + return nil, fmt.Errorf("auth: response doesn't have JWT token") + } + token.Value = tokenRes.IDToken + } + return token, nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/compute.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/compute.go new file mode 100644 index 000000000..a2d5c310a --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/compute.go @@ -0,0 +1,102 @@ +// Copyright 2023 Google LLC +// +// 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 credentials + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/url" + "strings" + "time" + + "cloud.google.com/go/auth" + "cloud.google.com/go/compute/metadata" +) + +var ( + computeTokenMetadata = map[string]interface{}{ + "auth.google.tokenSource": "compute-metadata", + "auth.google.serviceAccount": "default", + } + computeTokenURI = "instance/service-accounts/default/token" +) + +// computeTokenProvider creates a [cloud.google.com/go/auth.TokenProvider] that +// uses the metadata service to retrieve tokens. +func computeTokenProvider(opts *DetectOptions, client *metadata.Client) auth.TokenProvider { + return auth.NewCachedTokenProvider(&computeProvider{ + scopes: opts.Scopes, + client: client, + tokenBindingType: opts.TokenBindingType, + }, &auth.CachedTokenProviderOptions{ + ExpireEarly: opts.EarlyTokenRefresh, + DisableAsyncRefresh: opts.DisableAsyncRefresh, + }) +} + +// computeProvider fetches tokens from the google cloud metadata service. +type computeProvider struct { + scopes []string + client *metadata.Client + tokenBindingType TokenBindingType +} + +type metadataTokenResp struct { + AccessToken string `json:"access_token"` + ExpiresInSec int `json:"expires_in"` + TokenType string `json:"token_type"` +} + +func (cs *computeProvider) Token(ctx context.Context) (*auth.Token, error) { + tokenURI, err := url.Parse(computeTokenURI) + if err != nil { + return nil, err + } + hasScopes := len(cs.scopes) > 0 + if hasScopes || cs.tokenBindingType != NoBinding { + v := url.Values{} + if hasScopes { + v.Set("scopes", strings.Join(cs.scopes, ",")) + } + switch cs.tokenBindingType { + case MTLSHardBinding: + v.Set("transport", "mtls") + v.Set("binding-enforcement", "on") + case ALTSHardBinding: + v.Set("transport", "alts") + } + tokenURI.RawQuery = v.Encode() + } + tokenJSON, err := cs.client.GetWithContext(ctx, tokenURI.String()) + if err != nil { + return nil, fmt.Errorf("credentials: cannot fetch token: %w", err) + } + var res metadataTokenResp + if err := json.NewDecoder(strings.NewReader(tokenJSON)).Decode(&res); err != nil { + return nil, fmt.Errorf("credentials: invalid token JSON from metadata: %w", err) + } + if res.ExpiresInSec == 0 || res.AccessToken == "" { + return nil, errors.New("credentials: incomplete token received from metadata") + } + token := &auth.Token{ + Value: res.AccessToken, + Type: res.TokenType, + Expiry: time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second), + Metadata: computeTokenMetadata, + } + return token, nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/detect.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/detect.go new file mode 100644 index 000000000..c9d7600e0 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/detect.go @@ -0,0 +1,471 @@ +// Copyright 2023 Google LLC +// +// 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 credentials + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "log/slog" + "net/http" + "os" + "time" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/credsfile" + "cloud.google.com/go/auth/internal/trustboundary" + "cloud.google.com/go/compute/metadata" + "github.com/googleapis/gax-go/v2/internallog" +) + +const ( + // jwtTokenURL is Google's OAuth 2.0 token URL to use with the JWT(2LO) flow. + jwtTokenURL = "https://oauth2.googleapis.com/token" + + // Google's OAuth 2.0 default endpoints. + googleAuthURL = "https://accounts.google.com/o/oauth2/auth" + googleTokenURL = "https://oauth2.googleapis.com/token" + + // GoogleMTLSTokenURL is Google's default OAuth2.0 mTLS endpoint. + GoogleMTLSTokenURL = "https://oauth2.mtls.googleapis.com/token" + + // Help on default credentials + adcSetupURL = "https://cloud.google.com/docs/authentication/external/set-up-adc" +) + +var ( + // for testing + allowOnGCECheck = true +) + +// CredType specifies the type of JSON credentials being provided +// to a loading function such as [NewCredentialsFromFile] or +// [NewCredentialsFromJSON]. +type CredType string + +const ( + // ServiceAccount represents a service account file type. + ServiceAccount CredType = "service_account" + // AuthorizedUser represents a user credentials file type. + AuthorizedUser CredType = "authorized_user" + // ExternalAccount represents an external account file type. + // + // IMPORTANT: + // This credential type does not validate the credential configuration. A security + // risk occurs when a credential configuration configured with malicious urls + // is used. + // You should validate credential configurations provided by untrusted sources. + // See [Security requirements when using credential configurations from an external + // source] https://cloud.google.com/docs/authentication/external/externally-sourced-credentials + // for more details. + ExternalAccount CredType = "external_account" + // ImpersonatedServiceAccount represents an impersonated service account file type. + // + // IMPORTANT: + // This credential type does not validate the credential configuration. A security + // risk occurs when a credential configuration configured with malicious urls + // is used. + // You should validate credential configurations provided by untrusted sources. + // See [Security requirements when using credential configurations from an external + // source] https://cloud.google.com/docs/authentication/external/externally-sourced-credentials + // for more details. + ImpersonatedServiceAccount CredType = "impersonated_service_account" + // GDCHServiceAccount represents a GDCH service account credentials. + GDCHServiceAccount CredType = "gdch_service_account" + // ExternalAccountAuthorizedUser represents an external account authorized user credentials. + ExternalAccountAuthorizedUser CredType = "external_account_authorized_user" +) + +// TokenBindingType specifies the type of binding used when requesting a token +// whether to request a hard-bound token using mTLS or an instance identity +// bound token using ALTS. +type TokenBindingType int + +const ( + // NoBinding specifies that requested tokens are not required to have a + // binding. This is the default option. + NoBinding TokenBindingType = iota + // MTLSHardBinding specifies that a hard-bound token should be requested + // using an mTLS with S2A channel. + MTLSHardBinding + // ALTSHardBinding specifies that an instance identity bound token should + // be requested using an ALTS channel. + ALTSHardBinding +) + +// OnGCE reports whether this process is running in Google Cloud. +func OnGCE() bool { + // TODO(codyoss): once all libs use this auth lib move metadata check here + return allowOnGCECheck && metadata.OnGCE() +} + +// DetectDefault searches for "Application Default Credentials" and returns +// a credential based on the [DetectOptions] provided. +// +// It looks for credentials in the following places, preferring the first +// location found: +// +// - A JSON file whose path is specified by the GOOGLE_APPLICATION_CREDENTIALS +// environment variable. For workload identity federation, refer to +// https://cloud.google.com/iam/docs/how-to#using-workload-identity-federation +// on how to generate the JSON configuration file for on-prem/non-Google +// cloud platforms. +// - A JSON file in a location known to the gcloud command-line tool. On +// Windows, this is %APPDATA%/gcloud/application_default_credentials.json. On +// other systems, $HOME/.config/gcloud/application_default_credentials.json. +// - On Google Compute Engine, Google App Engine standard second generation +// runtimes, and Google App Engine flexible environment, it fetches +// credentials from the metadata server. +// +// Important: If you accept a credential configuration (credential +// JSON/File/Stream) from an external source for authentication to Google +// Cloud Platform, you must validate it before providing it to any Google +// API or library. Providing an unvalidated credential configuration to +// Google APIs can compromise the security of your systems and data. For +// more information, refer to [Validate credential configurations from +// external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials). +func DetectDefault(opts *DetectOptions) (*auth.Credentials, error) { + if err := opts.validate(); err != nil { + return nil, err + } + trustBoundaryEnabled, err := trustboundary.IsEnabled() + if err != nil { + return nil, err + } + if len(opts.CredentialsJSON) > 0 { + return readCredentialsFileJSON(opts.CredentialsJSON, opts) + } + if opts.CredentialsFile != "" { + return readCredentialsFile(opts.CredentialsFile, opts) + } + if filename := os.Getenv(credsfile.GoogleAppCredsEnvVar); filename != "" { + creds, err := readCredentialsFile(filename, opts) + if err != nil { + return nil, err + } + return creds, nil + } + + fileName := credsfile.GetWellKnownFileName() + if b, err := os.ReadFile(fileName); err == nil { + return readCredentialsFileJSON(b, opts) + } + + if OnGCE() { + metadataClient := metadata.NewWithOptions(&metadata.Options{ + Logger: opts.logger(), + UseDefaultClient: true, + }) + gceUniverseDomainProvider := &internal.ComputeUniverseDomainProvider{ + MetadataClient: metadataClient, + } + + tp := computeTokenProvider(opts, metadataClient) + if trustBoundaryEnabled { + gceConfigProvider := trustboundary.NewGCEConfigProvider(gceUniverseDomainProvider) + var err error + tp, err = trustboundary.NewProvider(opts.client(), gceConfigProvider, opts.logger(), tp) + if err != nil { + return nil, fmt.Errorf("credentials: failed to initialize GCE trust boundary provider: %w", err) + } + + } + return auth.NewCredentials(&auth.CredentialsOptions{ + TokenProvider: tp, + ProjectIDProvider: auth.CredentialsPropertyFunc(func(ctx context.Context) (string, error) { + return metadataClient.ProjectIDWithContext(ctx) + }), + UniverseDomainProvider: gceUniverseDomainProvider, + }), nil + } + + return nil, fmt.Errorf("credentials: could not find default credentials. See %v for more information", adcSetupURL) +} + +// DetectOptions provides configuration for [DetectDefault]. +type DetectOptions struct { + // Scopes that credentials tokens should have. Example: + // https://www.googleapis.com/auth/cloud-platform. Required if Audience is + // not provided. + Scopes []string + // TokenBindingType specifies the type of binding used when requesting a + // token whether to request a hard-bound token using mTLS or an instance + // identity bound token using ALTS. Optional. + TokenBindingType TokenBindingType + // Audience that credentials tokens should have. Only applicable for 2LO + // flows with service accounts. If specified, scopes should not be provided. + Audience string + // Subject is the user email used for [domain wide delegation](https://developers.google.com/identity/protocols/oauth2/service-account#delegatingauthority). + // Optional. + Subject string + // EarlyTokenRefresh configures how early before a token expires that it + // should be refreshed. Once the token’s time until expiration has entered + // this refresh window the token is considered valid but stale. If unset, + // the default value is 3 minutes and 45 seconds. Optional. + EarlyTokenRefresh time.Duration + // DisableAsyncRefresh configures a synchronous workflow that refreshes + // stale tokens while blocking. The default is false. Optional. + DisableAsyncRefresh bool + // AuthHandlerOptions configures an authorization handler and other options + // for 3LO flows. It is required, and only used, for client credential + // flows. + AuthHandlerOptions *auth.AuthorizationHandlerOptions + // TokenURL allows to set the token endpoint for user credential flows. If + // unset the default value is: https://oauth2.googleapis.com/token. + // Optional. + TokenURL string + // STSAudience is the audience sent to when retrieving an STS token. + // Currently this only used for GDCH auth flow, for which it is required. + STSAudience string + // CredentialsFile overrides detection logic and sources a credential file + // from the provided filepath. If provided, CredentialsJSON must not be. + // Optional. + // + // Deprecated: This field is deprecated because of a potential security risk. + // It does not validate the credential configuration. The security risk occurs + // when a credential configuration is accepted from a source that is not + // under your control and used without validation on your side. + // + // If you know that you will be loading credential configurations of a + // specific type, it is recommended to use a credential-type-specific + // NewCredentialsFromFile method. This will ensure that an unexpected + // credential type with potential for malicious intent is not loaded + // unintentionally. You might still have to do validation for certain + // credential types. Please follow the recommendation for that method. For + // example, if you want to load only service accounts, you can use + // + // creds, err := credentials.NewCredentialsFromFile(ctx, credentials.ServiceAccount, filename, opts) + // + // If you are loading your credential configuration from an untrusted source + // and have not mitigated the risks (e.g. by validating the configuration + // yourself), make these changes as soon as possible to prevent security + // risks to your environment. + // + // Regardless of the method used, it is always your responsibility to + // validate configurations received from external sources. + // + // For more details see: + // https://cloud.google.com/docs/authentication/external/externally-sourced-credentials + CredentialsFile string + // CredentialsJSON overrides detection logic and uses the JSON bytes as the + // source for the credential. If provided, CredentialsFile must not be. + // Optional. + // + // Deprecated: This field is deprecated because of a potential security risk. + // It does not validate the credential configuration. The security risk occurs + // when a credential configuration is accepted from a source that is not + // under your control and used without validation on your side. + // + // If you know that you will be loading credential configurations of a + // specific type, it is recommended to use a credential-type-specific + // NewCredentialsFromJSON method. This will ensure that an unexpected + // credential type with potential for malicious intent is not loaded + // unintentionally. You might still have to do validation for certain + // credential types. Please follow the recommendation for that method. For + // example, if you want to load only service accounts, you can use + // + // creds, err := credentials.NewCredentialsFromJSON(ctx, credentials.ServiceAccount, json, opts) + // + // If you are loading your credential configuration from an untrusted source + // and have not mitigated the risks (e.g. by validating the configuration + // yourself), make these changes as soon as possible to prevent security + // risks to your environment. + // + // Regardless of the method used, it is always your responsibility to + // validate configurations received from external sources. + // + // For more details see: + // https://cloud.google.com/docs/authentication/external/externally-sourced-credentials + CredentialsJSON []byte + // UseSelfSignedJWT directs service account based credentials to create a + // self-signed JWT with the private key found in the file, skipping any + // network requests that would normally be made. Optional. + UseSelfSignedJWT bool + // Client configures the underlying client used to make network requests + // when fetching tokens. Optional. + Client *http.Client + // UniverseDomain is the default service domain for a given Cloud universe. + // The default value is "googleapis.com". This option is ignored for + // authentication flows that do not support universe domain. Optional. + UniverseDomain string + // Logger is used for debug logging. If provided, logging will be enabled + // at the loggers configured level. By default logging is disabled unless + // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default + // logger will be used. Optional. + Logger *slog.Logger +} + +// NewCredentialsFromFile creates a [cloud.google.com/go/auth.Credentials] from +// the provided file. The credType argument specifies the expected credential +// type. If the file content does not match the expected type, an error is +// returned. +// +// Important: If you accept a credential configuration (credential +// JSON/File/Stream) from an external source for authentication to Google +// Cloud Platform, you must validate it before providing it to any Google +// API or library. Providing an unvalidated credential configuration to +// Google APIs can compromise the security of your systems and data. For +// more information, refer to [Validate credential configurations from +// external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials). +func NewCredentialsFromFile(credType CredType, filename string, opts *DetectOptions) (*auth.Credentials, error) { + b, err := os.ReadFile(filename) + if err != nil { + return nil, err + } + return NewCredentialsFromJSON(credType, b, opts) +} + +// NewCredentialsFromJSON creates a [cloud.google.com/go/auth.Credentials] from +// the provided JSON bytes. The credType argument specifies the expected +// credential type. If the JSON does not match the expected type, an error is +// returned. +// +// Important: If you accept a credential configuration (credential +// JSON/File/Stream) from an external source for authentication to Google +// Cloud Platform, you must validate it before providing it to any Google +// API or library. Providing an unvalidated credential configuration to +// Google APIs can compromise the security of your systems and data. For +// more information, refer to [Validate credential configurations from +// external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials). +func NewCredentialsFromJSON(credType CredType, b []byte, opts *DetectOptions) (*auth.Credentials, error) { + if err := checkCredentialType(b, credType); err != nil { + return nil, err + } + // We can't use readCredentialsFileJSON because it does auto-detection + // for client_credentials.json which we don't support here (no type field). + // Instead, we call fileCredentials just as readCredentialsFileJSON does + // when it doesn't detect client_credentials.json. + return fileCredentials(b, opts) +} + +func checkCredentialType(b []byte, expected CredType) error { + + fileType, err := credsfile.ParseFileType(b) + if err != nil { + return err + } + if CredType(fileType) != expected { + return fmt.Errorf("credentials: expected type %q, found %q", expected, fileType) + } + return nil +} + +func (o *DetectOptions) validate() error { + if o == nil { + return errors.New("credentials: options must be provided") + } + if len(o.Scopes) > 0 && o.Audience != "" { + return errors.New("credentials: both scopes and audience were provided") + } + if len(o.CredentialsJSON) > 0 && o.CredentialsFile != "" { + return errors.New("credentials: both credentials file and JSON were provided") + } + return nil +} + +func (o *DetectOptions) tokenURL() string { + if o.TokenURL != "" { + return o.TokenURL + } + return googleTokenURL +} + +func (o *DetectOptions) scopes() []string { + scopes := make([]string, len(o.Scopes)) + copy(scopes, o.Scopes) + return scopes +} + +func (o *DetectOptions) client() *http.Client { + if o.Client != nil { + return o.Client + } + return internal.DefaultClient() +} + +func (o *DetectOptions) logger() *slog.Logger { + return internallog.New(o.Logger) +} + +func readCredentialsFile(filename string, opts *DetectOptions) (*auth.Credentials, error) { + b, err := os.ReadFile(filename) + if err != nil { + return nil, err + } + return readCredentialsFileJSON(b, opts) +} + +func readCredentialsFileJSON(b []byte, opts *DetectOptions) (*auth.Credentials, error) { + // attempt to parse jsonData as a Google Developers Console client_credentials.json. + config := clientCredConfigFromJSON(b, opts) + if config != nil { + if config.AuthHandlerOpts == nil { + return nil, errors.New("credentials: auth handler must be specified for this credential filetype") + } + tp, err := auth.New3LOTokenProvider(config) + if err != nil { + return nil, err + } + return auth.NewCredentials(&auth.CredentialsOptions{ + TokenProvider: tp, + JSON: b, + }), nil + } + return fileCredentials(b, opts) +} + +func clientCredConfigFromJSON(b []byte, opts *DetectOptions) *auth.Options3LO { + var creds credsfile.ClientCredentialsFile + var c *credsfile.Config3LO + if err := json.Unmarshal(b, &creds); err != nil { + return nil + } + switch { + case creds.Web != nil: + c = creds.Web + case creds.Installed != nil: + c = creds.Installed + default: + return nil + } + if len(c.RedirectURIs) < 1 { + return nil + } + var handleOpts *auth.AuthorizationHandlerOptions + if opts.AuthHandlerOptions != nil { + handleOpts = &auth.AuthorizationHandlerOptions{ + Handler: opts.AuthHandlerOptions.Handler, + State: opts.AuthHandlerOptions.State, + PKCEOpts: opts.AuthHandlerOptions.PKCEOpts, + } + } + return &auth.Options3LO{ + ClientID: c.ClientID, + ClientSecret: c.ClientSecret, + RedirectURL: c.RedirectURIs[0], + Scopes: opts.scopes(), + AuthURL: c.AuthURI, + TokenURL: c.TokenURI, + Client: opts.client(), + Logger: opts.logger(), + EarlyTokenExpiry: opts.EarlyTokenRefresh, + AuthHandlerOpts: handleOpts, + // TODO(codyoss): refactor this out. We need to add in auto-detection + // for this use case. + AuthStyle: auth.StyleInParams, + } +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/doc.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/doc.go new file mode 100644 index 000000000..1dbb2866b --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/doc.go @@ -0,0 +1,45 @@ +// Copyright 2023 Google LLC +// +// 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 credentials provides support for making OAuth2 authorized and +// authenticated HTTP requests to Google APIs. It supports the Web server flow, +// client-side credentials, service accounts, Google Compute Engine service +// accounts, Google App Engine service accounts and workload identity federation +// from non-Google cloud platforms. +// +// A brief overview of the package follows. For more information, please read +// https://developers.google.com/accounts/docs/OAuth2 +// and +// https://developers.google.com/accounts/docs/application-default-credentials. +// For more information on using workload identity federation, refer to +// https://cloud.google.com/iam/docs/how-to#using-workload-identity-federation. +// +// # Credentials +// +// The [cloud.google.com/go/auth.Credentials] type represents Google +// credentials, including Application Default Credentials. +// +// Use [DetectDefault] to obtain Application Default Credentials. +// +// Application Default Credentials support workload identity federation to +// access Google Cloud resources from non-Google Cloud platforms including Amazon +// Web Services (AWS), Microsoft Azure or any identity provider that supports +// OpenID Connect (OIDC). Workload identity federation is recommended for +// non-Google Cloud environments as it avoids the need to download, manage, and +// store service account private keys locally. +// +// # Workforce Identity Federation +// +// For more information on this feature see [cloud.google.com/go/auth/credentials/externalaccount]. +package credentials diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/filetypes.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/filetypes.go new file mode 100644 index 000000000..f3737a5e8 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/filetypes.go @@ -0,0 +1,329 @@ +// Copyright 2023 Google LLC +// +// 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 credentials + +import ( + "errors" + "fmt" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/credentials/internal/externalaccount" + "cloud.google.com/go/auth/credentials/internal/externalaccountuser" + "cloud.google.com/go/auth/credentials/internal/gdch" + "cloud.google.com/go/auth/credentials/internal/impersonate" + internalauth "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/credsfile" + "cloud.google.com/go/auth/internal/trustboundary" +) + +const cloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform" + +func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) { + fileType, err := credsfile.ParseFileType(b) + if err != nil { + return nil, err + } + if fileType == "" { + return nil, errors.New("credentials: unsupported unidentified file type") + } + + var projectID, universeDomain string + var tp auth.TokenProvider + switch CredType(fileType) { + case ServiceAccount: + f, err := credsfile.ParseServiceAccount(b) + if err != nil { + return nil, err + } + tp, err = handleServiceAccount(f, opts) + if err != nil { + return nil, err + } + projectID = f.ProjectID + universeDomain = resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) + case AuthorizedUser: + f, err := credsfile.ParseUserCredentials(b) + if err != nil { + return nil, err + } + tp, err = handleUserCredential(f, opts) + if err != nil { + return nil, err + } + universeDomain = f.UniverseDomain + case ExternalAccount: + f, err := credsfile.ParseExternalAccount(b) + if err != nil { + return nil, err + } + tp, err = handleExternalAccount(f, opts) + if err != nil { + return nil, err + } + universeDomain = resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) + case ExternalAccountAuthorizedUser: + f, err := credsfile.ParseExternalAccountAuthorizedUser(b) + if err != nil { + return nil, err + } + tp, err = handleExternalAccountAuthorizedUser(f, opts) + if err != nil { + return nil, err + } + universeDomain = f.UniverseDomain + case ImpersonatedServiceAccount: + f, err := credsfile.ParseImpersonatedServiceAccount(b) + if err != nil { + return nil, err + } + tp, err = handleImpersonatedServiceAccount(f, opts) + if err != nil { + return nil, err + } + universeDomain = resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) + case GDCHServiceAccount: + f, err := credsfile.ParseGDCHServiceAccount(b) + if err != nil { + return nil, err + } + tp, err = handleGDCHServiceAccount(f, opts) + if err != nil { + return nil, err + } + projectID = f.Project + universeDomain = f.UniverseDomain + default: + return nil, fmt.Errorf("credentials: unsupported filetype %q", fileType) + } + return auth.NewCredentials(&auth.CredentialsOptions{ + TokenProvider: auth.NewCachedTokenProvider(tp, &auth.CachedTokenProviderOptions{ + ExpireEarly: opts.EarlyTokenRefresh, + }), + JSON: b, + ProjectIDProvider: internalauth.StaticCredentialsProperty(projectID), + // TODO(codyoss): only set quota project here if there was a user override + UniverseDomainProvider: internalauth.StaticCredentialsProperty(universeDomain), + }), nil +} + +// resolveUniverseDomain returns optsUniverseDomain if non-empty, in order to +// support configuring universe-specific credentials in code. Auth flows +// unsupported for universe domain should not use this func, but should instead +// simply set the file universe domain on the credentials. +func resolveUniverseDomain(optsUniverseDomain, fileUniverseDomain string) string { + if optsUniverseDomain != "" { + return optsUniverseDomain + } + return fileUniverseDomain +} + +func handleServiceAccount(f *credsfile.ServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { + ud := resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) + if opts.UseSelfSignedJWT { + return configureSelfSignedJWT(f, opts) + } else if ud != "" && ud != internalauth.DefaultUniverseDomain { + // For non-GDU universe domains, token exchange is impossible and services + // must support self-signed JWTs. + opts.UseSelfSignedJWT = true + return configureSelfSignedJWT(f, opts) + } + opts2LO := &auth.Options2LO{ + Email: f.ClientEmail, + PrivateKey: []byte(f.PrivateKey), + PrivateKeyID: f.PrivateKeyID, + Scopes: opts.scopes(), + TokenURL: f.TokenURL, + Subject: opts.Subject, + Client: opts.client(), + Logger: opts.logger(), + UniverseDomain: ud, + } + if opts2LO.TokenURL == "" { + opts2LO.TokenURL = jwtTokenURL + } + + tp, err := auth.New2LOTokenProvider(opts2LO) + if err != nil { + return nil, err + } + + trustBoundaryEnabled, err := trustboundary.IsEnabled() + if err != nil { + return nil, err + } + if !trustBoundaryEnabled { + return tp, nil + } + saConfig := trustboundary.NewServiceAccountConfigProvider(opts2LO.Email, opts2LO.UniverseDomain) + return trustboundary.NewProvider(opts.client(), saConfig, opts.logger(), tp) +} + +func handleUserCredential(f *credsfile.UserCredentialsFile, opts *DetectOptions) (auth.TokenProvider, error) { + opts3LO := &auth.Options3LO{ + ClientID: f.ClientID, + ClientSecret: f.ClientSecret, + Scopes: opts.scopes(), + AuthURL: googleAuthURL, + TokenURL: opts.tokenURL(), + AuthStyle: auth.StyleInParams, + EarlyTokenExpiry: opts.EarlyTokenRefresh, + RefreshToken: f.RefreshToken, + Client: opts.client(), + Logger: opts.logger(), + } + return auth.New3LOTokenProvider(opts3LO) +} + +func handleExternalAccount(f *credsfile.ExternalAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { + externalOpts := &externalaccount.Options{ + Audience: f.Audience, + SubjectTokenType: f.SubjectTokenType, + TokenURL: f.TokenURL, + TokenInfoURL: f.TokenInfoURL, + ServiceAccountImpersonationURL: f.ServiceAccountImpersonationURL, + ClientSecret: f.ClientSecret, + ClientID: f.ClientID, + CredentialSource: f.CredentialSource, + QuotaProjectID: f.QuotaProjectID, + Scopes: opts.scopes(), + WorkforcePoolUserProject: f.WorkforcePoolUserProject, + Client: opts.client(), + Logger: opts.logger(), + IsDefaultClient: opts.Client == nil, + } + if f.ServiceAccountImpersonation != nil { + externalOpts.ServiceAccountImpersonationLifetimeSeconds = f.ServiceAccountImpersonation.TokenLifetimeSeconds + } + tp, err := externalaccount.NewTokenProvider(externalOpts) + if err != nil { + return nil, err + } + trustBoundaryEnabled, err := trustboundary.IsEnabled() + if err != nil { + return nil, err + } + if !trustBoundaryEnabled { + return tp, nil + } + + ud := resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) + var configProvider trustboundary.ConfigProvider + + if f.ServiceAccountImpersonationURL == "" { + // No impersonation, this is a direct external account credential. + // The trust boundary is based on the workload/workforce pool. + var err error + configProvider, err = trustboundary.NewExternalAccountConfigProvider(f.Audience, ud) + if err != nil { + return nil, err + } + } else { + // Impersonation is used. The trust boundary is based on the target service account. + targetSAEmail, err := impersonate.ExtractServiceAccountEmail(f.ServiceAccountImpersonationURL) + if err != nil { + return nil, fmt.Errorf("credentials: could not extract target service account email for trust boundary: %w", err) + } + configProvider = trustboundary.NewServiceAccountConfigProvider(targetSAEmail, ud) + } + + return trustboundary.NewProvider(opts.client(), configProvider, opts.logger(), tp) +} + +func handleExternalAccountAuthorizedUser(f *credsfile.ExternalAccountAuthorizedUserFile, opts *DetectOptions) (auth.TokenProvider, error) { + externalOpts := &externalaccountuser.Options{ + Audience: f.Audience, + RefreshToken: f.RefreshToken, + TokenURL: f.TokenURL, + TokenInfoURL: f.TokenInfoURL, + ClientID: f.ClientID, + ClientSecret: f.ClientSecret, + Scopes: opts.scopes(), + Client: opts.client(), + Logger: opts.logger(), + } + tp, err := externalaccountuser.NewTokenProvider(externalOpts) + if err != nil { + return nil, err + } + trustBoundaryEnabled, err := trustboundary.IsEnabled() + if err != nil { + return nil, err + } + if !trustBoundaryEnabled { + return tp, nil + } + + ud := resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) + configProvider, err := trustboundary.NewExternalAccountConfigProvider(f.Audience, ud) + if err != nil { + return nil, err + } + return trustboundary.NewProvider(opts.client(), configProvider, opts.logger(), tp) +} + +func handleImpersonatedServiceAccount(f *credsfile.ImpersonatedServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { + if f.ServiceAccountImpersonationURL == "" || f.CredSource == nil { + return nil, errors.New("missing 'source_credentials' field or 'service_account_impersonation_url' in credentials") + } + + sourceOpts := *opts + + // Source credential needs IAM or Cloud Platform scope to call the + // iamcredentials endpoint. The scopes provided by the user are for the + // impersonated credentials. + sourceOpts.Scopes = []string{cloudPlatformScope} + sourceTP, err := fileCredentials(f.CredSource, &sourceOpts) + if err != nil { + return nil, err + } + ud := resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) + scopes := opts.scopes() + if len(scopes) == 0 { + scopes = f.Scopes + } + impOpts := &impersonate.Options{ + URL: f.ServiceAccountImpersonationURL, + Scopes: scopes, + Tp: sourceTP, + Delegates: f.Delegates, + Client: opts.client(), + Logger: opts.logger(), + UniverseDomain: ud, + } + tp, err := impersonate.NewTokenProvider(impOpts) + if err != nil { + return nil, err + } + trustBoundaryEnabled, err := trustboundary.IsEnabled() + if err != nil { + return nil, err + } + if !trustBoundaryEnabled { + return tp, nil + } + targetSAEmail, err := impersonate.ExtractServiceAccountEmail(f.ServiceAccountImpersonationURL) + if err != nil { + return nil, fmt.Errorf("credentials: could not extract target service account email for trust boundary: %w", err) + } + targetSAConfig := trustboundary.NewServiceAccountConfigProvider(targetSAEmail, ud) + return trustboundary.NewProvider(opts.client(), targetSAConfig, opts.logger(), tp) +} +func handleGDCHServiceAccount(f *credsfile.GDCHServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { + return gdch.NewTokenProvider(f, &gdch.Options{ + STSAudience: opts.STSAudience, + Client: opts.client(), + Logger: opts.logger(), + }) +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/aws_provider.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/aws_provider.go new file mode 100644 index 000000000..9ecd1f64b --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/aws_provider.go @@ -0,0 +1,531 @@ +// Copyright 2023 Google LLC +// +// 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 externalaccount + +import ( + "bytes" + "context" + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "log/slog" + "net/http" + "net/url" + "os" + "path" + "sort" + "strings" + "time" + + "cloud.google.com/go/auth/internal" + "github.com/googleapis/gax-go/v2/internallog" +) + +var ( + // getenv aliases os.Getenv for testing + getenv = os.Getenv +) + +const ( + // AWS Signature Version 4 signing algorithm identifier. + awsAlgorithm = "AWS4-HMAC-SHA256" + + // The termination string for the AWS credential scope value as defined in + // https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html + awsRequestType = "aws4_request" + + // The AWS authorization header name for the security session token if available. + awsSecurityTokenHeader = "x-amz-security-token" + + // The name of the header containing the session token for metadata endpoint calls + awsIMDSv2SessionTokenHeader = "X-aws-ec2-metadata-token" + + awsIMDSv2SessionTTLHeader = "X-aws-ec2-metadata-token-ttl-seconds" + + awsIMDSv2SessionTTL = "300" + + // The AWS authorization header name for the auto-generated date. + awsDateHeader = "x-amz-date" + + defaultRegionalCredentialVerificationURL = "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15" + + // Supported AWS configuration environment variables. + awsAccessKeyIDEnvVar = "AWS_ACCESS_KEY_ID" + awsDefaultRegionEnvVar = "AWS_DEFAULT_REGION" + awsRegionEnvVar = "AWS_REGION" + awsSecretAccessKeyEnvVar = "AWS_SECRET_ACCESS_KEY" + awsSessionTokenEnvVar = "AWS_SESSION_TOKEN" + + awsTimeFormatLong = "20060102T150405Z" + awsTimeFormatShort = "20060102" + awsProviderType = "aws" +) + +type awsSubjectProvider struct { + EnvironmentID string + RegionURL string + RegionalCredVerificationURL string + CredVerificationURL string + IMDSv2SessionTokenURL string + TargetResource string + requestSigner *awsRequestSigner + region string + securityCredentialsProvider AwsSecurityCredentialsProvider + reqOpts *RequestOptions + + Client *http.Client + logger *slog.Logger +} + +func (sp *awsSubjectProvider) subjectToken(ctx context.Context) (string, error) { + // Set Defaults + if sp.RegionalCredVerificationURL == "" { + sp.RegionalCredVerificationURL = defaultRegionalCredentialVerificationURL + } + headers := make(map[string]string) + if sp.shouldUseMetadataServer() { + awsSessionToken, err := sp.getAWSSessionToken(ctx) + if err != nil { + return "", err + } + + if awsSessionToken != "" { + headers[awsIMDSv2SessionTokenHeader] = awsSessionToken + } + } + + awsSecurityCredentials, err := sp.getSecurityCredentials(ctx, headers) + if err != nil { + return "", err + } + if sp.region, err = sp.getRegion(ctx, headers); err != nil { + return "", err + } + sp.requestSigner = &awsRequestSigner{ + RegionName: sp.region, + AwsSecurityCredentials: awsSecurityCredentials, + } + + // Generate the signed request to AWS STS GetCallerIdentity API. + // Use the required regional endpoint. Otherwise, the request will fail. + req, err := http.NewRequestWithContext(ctx, "POST", strings.Replace(sp.RegionalCredVerificationURL, "{region}", sp.region, 1), nil) + if err != nil { + return "", err + } + // The full, canonical resource name of the workload identity pool + // provider, with or without the HTTPS prefix. + // Including this header as part of the signature is recommended to + // ensure data integrity. + if sp.TargetResource != "" { + req.Header.Set("x-goog-cloud-target-resource", sp.TargetResource) + } + sp.requestSigner.signRequest(req) + + /* + The GCP STS endpoint expects the headers to be formatted as: + # [ + # {key: 'x-amz-date', value: '...'}, + # {key: 'Authorization', value: '...'}, + # ... + # ] + # And then serialized as: + # quote(json.dumps({ + # url: '...', + # method: 'POST', + # headers: [{key: 'x-amz-date', value: '...'}, ...] + # })) + */ + + awsSignedReq := awsRequest{ + URL: req.URL.String(), + Method: "POST", + } + for headerKey, headerList := range req.Header { + for _, headerValue := range headerList { + awsSignedReq.Headers = append(awsSignedReq.Headers, awsRequestHeader{ + Key: headerKey, + Value: headerValue, + }) + } + } + sort.Slice(awsSignedReq.Headers, func(i, j int) bool { + headerCompare := strings.Compare(awsSignedReq.Headers[i].Key, awsSignedReq.Headers[j].Key) + if headerCompare == 0 { + return strings.Compare(awsSignedReq.Headers[i].Value, awsSignedReq.Headers[j].Value) < 0 + } + return headerCompare < 0 + }) + + result, err := json.Marshal(awsSignedReq) + if err != nil { + return "", err + } + return url.QueryEscape(string(result)), nil +} + +func (sp *awsSubjectProvider) providerType() string { + if sp.securityCredentialsProvider != nil { + return programmaticProviderType + } + return awsProviderType +} + +func (sp *awsSubjectProvider) getAWSSessionToken(ctx context.Context) (string, error) { + if sp.IMDSv2SessionTokenURL == "" { + return "", nil + } + req, err := http.NewRequestWithContext(ctx, "PUT", sp.IMDSv2SessionTokenURL, nil) + if err != nil { + return "", err + } + req.Header.Set(awsIMDSv2SessionTTLHeader, awsIMDSv2SessionTTL) + + sp.logger.DebugContext(ctx, "aws session token request", "request", internallog.HTTPRequest(req, nil)) + resp, body, err := internal.DoRequest(sp.Client, req) + if err != nil { + return "", err + } + sp.logger.DebugContext(ctx, "aws session token response", "response", internallog.HTTPResponse(resp, body)) + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("credentials: unable to retrieve AWS session token: %s", body) + } + return string(body), nil +} + +func (sp *awsSubjectProvider) getRegion(ctx context.Context, headers map[string]string) (string, error) { + if sp.securityCredentialsProvider != nil { + return sp.securityCredentialsProvider.AwsRegion(ctx, sp.reqOpts) + } + if canRetrieveRegionFromEnvironment() { + if envAwsRegion := getenv(awsRegionEnvVar); envAwsRegion != "" { + return envAwsRegion, nil + } + return getenv(awsDefaultRegionEnvVar), nil + } + + if sp.RegionURL == "" { + return "", errors.New("credentials: unable to determine AWS region") + } + + req, err := http.NewRequestWithContext(ctx, "GET", sp.RegionURL, nil) + if err != nil { + return "", err + } + + for name, value := range headers { + req.Header.Add(name, value) + } + sp.logger.DebugContext(ctx, "aws region request", "request", internallog.HTTPRequest(req, nil)) + resp, body, err := internal.DoRequest(sp.Client, req) + if err != nil { + return "", err + } + sp.logger.DebugContext(ctx, "aws region response", "response", internallog.HTTPResponse(resp, body)) + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("credentials: unable to retrieve AWS region - %s", body) + } + + // This endpoint will return the region in format: us-east-2b. + // Only the us-east-2 part should be used. + bodyLen := len(body) + if bodyLen == 0 { + return "", nil + } + return string(body[:bodyLen-1]), nil +} + +func (sp *awsSubjectProvider) getSecurityCredentials(ctx context.Context, headers map[string]string) (result *AwsSecurityCredentials, err error) { + if sp.securityCredentialsProvider != nil { + return sp.securityCredentialsProvider.AwsSecurityCredentials(ctx, sp.reqOpts) + } + if canRetrieveSecurityCredentialFromEnvironment() { + return &AwsSecurityCredentials{ + AccessKeyID: getenv(awsAccessKeyIDEnvVar), + SecretAccessKey: getenv(awsSecretAccessKeyEnvVar), + SessionToken: getenv(awsSessionTokenEnvVar), + }, nil + } + + roleName, err := sp.getMetadataRoleName(ctx, headers) + if err != nil { + return + } + credentials, err := sp.getMetadataSecurityCredentials(ctx, roleName, headers) + if err != nil { + return + } + + if credentials.AccessKeyID == "" { + return result, errors.New("credentials: missing AccessKeyId credential") + } + if credentials.SecretAccessKey == "" { + return result, errors.New("credentials: missing SecretAccessKey credential") + } + + return credentials, nil +} + +func (sp *awsSubjectProvider) getMetadataSecurityCredentials(ctx context.Context, roleName string, headers map[string]string) (*AwsSecurityCredentials, error) { + var result *AwsSecurityCredentials + + req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s/%s", sp.CredVerificationURL, roleName), nil) + if err != nil { + return result, err + } + for name, value := range headers { + req.Header.Add(name, value) + } + sp.logger.DebugContext(ctx, "aws security credential request", "request", internallog.HTTPRequest(req, nil)) + resp, body, err := internal.DoRequest(sp.Client, req) + if err != nil { + return result, err + } + sp.logger.DebugContext(ctx, "aws security credential response", "response", internallog.HTTPResponse(resp, body)) + if resp.StatusCode != http.StatusOK { + return result, fmt.Errorf("credentials: unable to retrieve AWS security credentials - %s", body) + } + if err := json.Unmarshal(body, &result); err != nil { + return nil, err + } + return result, nil +} + +func (sp *awsSubjectProvider) getMetadataRoleName(ctx context.Context, headers map[string]string) (string, error) { + if sp.CredVerificationURL == "" { + return "", errors.New("credentials: unable to determine the AWS metadata server security credentials endpoint") + } + req, err := http.NewRequestWithContext(ctx, "GET", sp.CredVerificationURL, nil) + if err != nil { + return "", err + } + for name, value := range headers { + req.Header.Add(name, value) + } + + sp.logger.DebugContext(ctx, "aws metadata role request", "request", internallog.HTTPRequest(req, nil)) + resp, body, err := internal.DoRequest(sp.Client, req) + if err != nil { + return "", err + } + sp.logger.DebugContext(ctx, "aws metadata role response", "response", internallog.HTTPResponse(resp, body)) + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("credentials: unable to retrieve AWS role name - %s", body) + } + return string(body), nil +} + +// awsRequestSigner is a utility class to sign http requests using a AWS V4 signature. +type awsRequestSigner struct { + RegionName string + AwsSecurityCredentials *AwsSecurityCredentials +} + +// signRequest adds the appropriate headers to an http.Request +// or returns an error if something prevented this. +func (rs *awsRequestSigner) signRequest(req *http.Request) error { + // req is assumed non-nil + signedRequest := cloneRequest(req) + timestamp := Now() + signedRequest.Header.Set("host", requestHost(req)) + if rs.AwsSecurityCredentials.SessionToken != "" { + signedRequest.Header.Set(awsSecurityTokenHeader, rs.AwsSecurityCredentials.SessionToken) + } + if signedRequest.Header.Get("date") == "" { + signedRequest.Header.Set(awsDateHeader, timestamp.Format(awsTimeFormatLong)) + } + authorizationCode, err := rs.generateAuthentication(signedRequest, timestamp) + if err != nil { + return err + } + signedRequest.Header.Set("Authorization", authorizationCode) + req.Header = signedRequest.Header + return nil +} + +func (rs *awsRequestSigner) generateAuthentication(req *http.Request, timestamp time.Time) (string, error) { + canonicalHeaderColumns, canonicalHeaderData := canonicalHeaders(req) + dateStamp := timestamp.Format(awsTimeFormatShort) + serviceName := "" + + if splitHost := strings.Split(requestHost(req), "."); len(splitHost) > 0 { + serviceName = splitHost[0] + } + credentialScope := strings.Join([]string{dateStamp, rs.RegionName, serviceName, awsRequestType}, "/") + requestString, err := canonicalRequest(req, canonicalHeaderColumns, canonicalHeaderData) + if err != nil { + return "", err + } + requestHash, err := getSha256([]byte(requestString)) + if err != nil { + return "", err + } + + stringToSign := strings.Join([]string{awsAlgorithm, timestamp.Format(awsTimeFormatLong), credentialScope, requestHash}, "\n") + signingKey := []byte("AWS4" + rs.AwsSecurityCredentials.SecretAccessKey) + for _, signingInput := range []string{ + dateStamp, rs.RegionName, serviceName, awsRequestType, stringToSign, + } { + signingKey, err = getHmacSha256(signingKey, []byte(signingInput)) + if err != nil { + return "", err + } + } + + return fmt.Sprintf("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s", awsAlgorithm, rs.AwsSecurityCredentials.AccessKeyID, credentialScope, canonicalHeaderColumns, hex.EncodeToString(signingKey)), nil +} + +func getSha256(input []byte) (string, error) { + hash := sha256.New() + if _, err := hash.Write(input); err != nil { + return "", err + } + return hex.EncodeToString(hash.Sum(nil)), nil +} + +func getHmacSha256(key, input []byte) ([]byte, error) { + hash := hmac.New(sha256.New, key) + if _, err := hash.Write(input); err != nil { + return nil, err + } + return hash.Sum(nil), nil +} + +func cloneRequest(r *http.Request) *http.Request { + r2 := new(http.Request) + *r2 = *r + if r.Header != nil { + r2.Header = make(http.Header, len(r.Header)) + + // Find total number of values. + headerCount := 0 + for _, headerValues := range r.Header { + headerCount += len(headerValues) + } + copiedHeaders := make([]string, headerCount) // shared backing array for headers' values + + for headerKey, headerValues := range r.Header { + headerCount = copy(copiedHeaders, headerValues) + r2.Header[headerKey] = copiedHeaders[:headerCount:headerCount] + copiedHeaders = copiedHeaders[headerCount:] + } + } + return r2 +} + +func canonicalPath(req *http.Request) string { + result := req.URL.EscapedPath() + if result == "" { + return "/" + } + return path.Clean(result) +} + +func canonicalQuery(req *http.Request) string { + queryValues := req.URL.Query() + for queryKey := range queryValues { + sort.Strings(queryValues[queryKey]) + } + return queryValues.Encode() +} + +func canonicalHeaders(req *http.Request) (string, string) { + // Header keys need to be sorted alphabetically. + var headers []string + lowerCaseHeaders := make(http.Header) + for k, v := range req.Header { + k := strings.ToLower(k) + if _, ok := lowerCaseHeaders[k]; ok { + // include additional values + lowerCaseHeaders[k] = append(lowerCaseHeaders[k], v...) + } else { + headers = append(headers, k) + lowerCaseHeaders[k] = v + } + } + sort.Strings(headers) + + var fullHeaders bytes.Buffer + for _, header := range headers { + headerValue := strings.Join(lowerCaseHeaders[header], ",") + fullHeaders.WriteString(header) + fullHeaders.WriteRune(':') + fullHeaders.WriteString(headerValue) + fullHeaders.WriteRune('\n') + } + + return strings.Join(headers, ";"), fullHeaders.String() +} + +func requestDataHash(req *http.Request) (string, error) { + var requestData []byte + if req.Body != nil { + requestBody, err := req.GetBody() + if err != nil { + return "", err + } + defer requestBody.Close() + + requestData, err = internal.ReadAll(requestBody) + if err != nil { + return "", err + } + } + + return getSha256(requestData) +} + +func requestHost(req *http.Request) string { + if req.Host != "" { + return req.Host + } + return req.URL.Host +} + +func canonicalRequest(req *http.Request, canonicalHeaderColumns, canonicalHeaderData string) (string, error) { + dataHash, err := requestDataHash(req) + if err != nil { + return "", err + } + return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s", req.Method, canonicalPath(req), canonicalQuery(req), canonicalHeaderData, canonicalHeaderColumns, dataHash), nil +} + +type awsRequestHeader struct { + Key string `json:"key"` + Value string `json:"value"` +} + +type awsRequest struct { + URL string `json:"url"` + Method string `json:"method"` + Headers []awsRequestHeader `json:"headers"` +} + +// The AWS region can be provided through AWS_REGION or AWS_DEFAULT_REGION. Only one is +// required. +func canRetrieveRegionFromEnvironment() bool { + return getenv(awsRegionEnvVar) != "" || getenv(awsDefaultRegionEnvVar) != "" +} + +// Check if both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are available. +func canRetrieveSecurityCredentialFromEnvironment() bool { + return getenv(awsAccessKeyIDEnvVar) != "" && getenv(awsSecretAccessKeyEnvVar) != "" +} + +func (sp *awsSubjectProvider) shouldUseMetadataServer() bool { + return sp.securityCredentialsProvider == nil && (!canRetrieveRegionFromEnvironment() || !canRetrieveSecurityCredentialFromEnvironment()) +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/executable_provider.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/executable_provider.go new file mode 100644 index 000000000..d5765c474 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/executable_provider.go @@ -0,0 +1,284 @@ +// Copyright 2023 Google LLC +// +// 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 externalaccount + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "os" + "os/exec" + "regexp" + "strings" + "time" + + "cloud.google.com/go/auth/internal" +) + +const ( + executableSupportedMaxVersion = 1 + executableDefaultTimeout = 30 * time.Second + executableSource = "response" + executableProviderType = "executable" + outputFileSource = "output file" + + allowExecutablesEnvVar = "GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES" + + jwtTokenType = "urn:ietf:params:oauth:token-type:jwt" + idTokenType = "urn:ietf:params:oauth:token-type:id_token" + saml2TokenType = "urn:ietf:params:oauth:token-type:saml2" +) + +var ( + serviceAccountImpersonationRE = regexp.MustCompile(`https://iamcredentials..+/v1/projects/-/serviceAccounts/(.*@.*):generateAccessToken`) +) + +type nonCacheableError struct { + message string +} + +func (nce nonCacheableError) Error() string { + return nce.message +} + +// environment is a contract for testing +type environment interface { + existingEnv() []string + getenv(string) string + run(ctx context.Context, command string, env []string) ([]byte, error) + now() time.Time +} + +type runtimeEnvironment struct{} + +func (r runtimeEnvironment) existingEnv() []string { + return os.Environ() +} +func (r runtimeEnvironment) getenv(key string) string { + return os.Getenv(key) +} +func (r runtimeEnvironment) now() time.Time { + return time.Now().UTC() +} + +func (r runtimeEnvironment) run(ctx context.Context, command string, env []string) ([]byte, error) { + splitCommand := strings.Fields(command) + cmd := exec.CommandContext(ctx, splitCommand[0], splitCommand[1:]...) + cmd.Env = env + + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + if err := cmd.Run(); err != nil { + if ctx.Err() == context.DeadlineExceeded { + return nil, context.DeadlineExceeded + } + if exitError, ok := err.(*exec.ExitError); ok { + return nil, exitCodeError(exitError) + } + return nil, executableError(err) + } + + bytesStdout := bytes.TrimSpace(stdout.Bytes()) + if len(bytesStdout) > 0 { + return bytesStdout, nil + } + return bytes.TrimSpace(stderr.Bytes()), nil +} + +type executableSubjectProvider struct { + Command string + Timeout time.Duration + OutputFile string + client *http.Client + opts *Options + env environment +} + +type executableResponse struct { + Version int `json:"version,omitempty"` + Success *bool `json:"success,omitempty"` + TokenType string `json:"token_type,omitempty"` + ExpirationTime int64 `json:"expiration_time,omitempty"` + IDToken string `json:"id_token,omitempty"` + SamlResponse string `json:"saml_response,omitempty"` + Code string `json:"code,omitempty"` + Message string `json:"message,omitempty"` +} + +func (sp *executableSubjectProvider) parseSubjectTokenFromSource(response []byte, source string, now int64) (string, error) { + var result executableResponse + if err := json.Unmarshal(response, &result); err != nil { + return "", jsonParsingError(source, string(response)) + } + // Validate + if result.Version == 0 { + return "", missingFieldError(source, "version") + } + if result.Success == nil { + return "", missingFieldError(source, "success") + } + if !*result.Success { + if result.Code == "" || result.Message == "" { + return "", malformedFailureError() + } + return "", userDefinedError(result.Code, result.Message) + } + if result.Version > executableSupportedMaxVersion || result.Version < 0 { + return "", unsupportedVersionError(source, result.Version) + } + if result.ExpirationTime == 0 && sp.OutputFile != "" { + return "", missingFieldError(source, "expiration_time") + } + if result.TokenType == "" { + return "", missingFieldError(source, "token_type") + } + if result.ExpirationTime != 0 && result.ExpirationTime < now { + return "", tokenExpiredError() + } + + switch result.TokenType { + case jwtTokenType, idTokenType: + if result.IDToken == "" { + return "", missingFieldError(source, "id_token") + } + return result.IDToken, nil + case saml2TokenType: + if result.SamlResponse == "" { + return "", missingFieldError(source, "saml_response") + } + return result.SamlResponse, nil + default: + return "", tokenTypeError(source) + } +} + +func (sp *executableSubjectProvider) subjectToken(ctx context.Context) (string, error) { + if token, err := sp.getTokenFromOutputFile(); token != "" || err != nil { + return token, err + } + return sp.getTokenFromExecutableCommand(ctx) +} + +func (sp *executableSubjectProvider) providerType() string { + return executableProviderType +} + +func (sp *executableSubjectProvider) getTokenFromOutputFile() (token string, err error) { + if sp.OutputFile == "" { + // This ExecutableCredentialSource doesn't use an OutputFile. + return "", nil + } + + file, err := os.Open(sp.OutputFile) + if err != nil { + // No OutputFile found. Hasn't been created yet, so skip it. + return "", nil + } + defer file.Close() + + data, err := internal.ReadAll(file) + if err != nil || len(data) == 0 { + // Cachefile exists, but no data found. Get new credential. + return "", nil + } + + token, err = sp.parseSubjectTokenFromSource(data, outputFileSource, sp.env.now().Unix()) + if err != nil { + if _, ok := err.(nonCacheableError); ok { + // If the cached token is expired we need a new token, + // and if the cache contains a failure, we need to try again. + return "", nil + } + + // There was an error in the cached token, and the developer should be aware of it. + return "", err + } + // Token parsing succeeded. Use found token. + return token, nil +} + +func (sp *executableSubjectProvider) executableEnvironment() []string { + result := sp.env.existingEnv() + result = append(result, fmt.Sprintf("GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE=%v", sp.opts.Audience)) + result = append(result, fmt.Sprintf("GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE=%v", sp.opts.SubjectTokenType)) + result = append(result, "GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE=0") + if sp.opts.ServiceAccountImpersonationURL != "" { + matches := serviceAccountImpersonationRE.FindStringSubmatch(sp.opts.ServiceAccountImpersonationURL) + if matches != nil { + result = append(result, fmt.Sprintf("GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL=%v", matches[1])) + } + } + if sp.OutputFile != "" { + result = append(result, fmt.Sprintf("GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE=%v", sp.OutputFile)) + } + return result +} + +func (sp *executableSubjectProvider) getTokenFromExecutableCommand(ctx context.Context) (string, error) { + // For security reasons, we need our consumers to set this environment variable to allow executables to be run. + if sp.env.getenv(allowExecutablesEnvVar) != "1" { + return "", errors.New("credentials: executables need to be explicitly allowed (set GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES to '1') to run") + } + + ctx, cancel := context.WithDeadline(ctx, sp.env.now().Add(sp.Timeout)) + defer cancel() + + output, err := sp.env.run(ctx, sp.Command, sp.executableEnvironment()) + if err != nil { + return "", err + } + return sp.parseSubjectTokenFromSource(output, executableSource, sp.env.now().Unix()) +} + +func missingFieldError(source, field string) error { + return fmt.Errorf("credentials: %q missing %q field", source, field) +} + +func jsonParsingError(source, data string) error { + return fmt.Errorf("credentials: unable to parse %q: %v", source, data) +} + +func malformedFailureError() error { + return nonCacheableError{"credentials: response must include `error` and `message` fields when unsuccessful"} +} + +func userDefinedError(code, message string) error { + return nonCacheableError{fmt.Sprintf("credentials: response contains unsuccessful response: (%v) %v", code, message)} +} + +func unsupportedVersionError(source string, version int) error { + return fmt.Errorf("credentials: %v contains unsupported version: %v", source, version) +} + +func tokenExpiredError() error { + return nonCacheableError{"credentials: the token returned by the executable is expired"} +} + +func tokenTypeError(source string) error { + return fmt.Errorf("credentials: %v contains unsupported token type", source) +} + +func exitCodeError(err *exec.ExitError) error { + return fmt.Errorf("credentials: executable command failed with exit code %v: %w", err.ExitCode(), err) +} + +func executableError(err error) error { + return fmt.Errorf("credentials: executable command failed: %w", err) +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/externalaccount.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/externalaccount.go new file mode 100644 index 000000000..f4f49f175 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/externalaccount.go @@ -0,0 +1,431 @@ +// Copyright 2023 Google LLC +// +// 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 externalaccount + +import ( + "context" + "errors" + "fmt" + "log/slog" + "net/http" + "regexp" + "strconv" + "strings" + "time" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/credentials/internal/impersonate" + "cloud.google.com/go/auth/credentials/internal/stsexchange" + "cloud.google.com/go/auth/internal/credsfile" + "github.com/googleapis/gax-go/v2/internallog" +) + +const ( + timeoutMinimum = 5 * time.Second + timeoutMaximum = 120 * time.Second + + universeDomainPlaceholder = "UNIVERSE_DOMAIN" + defaultTokenURL = "https://sts.UNIVERSE_DOMAIN/v1/token" + defaultUniverseDomain = "googleapis.com" +) + +var ( + // Now aliases time.Now for testing + Now = func() time.Time { + return time.Now().UTC() + } + validWorkforceAudiencePattern *regexp.Regexp = regexp.MustCompile(`//iam\.googleapis\.com/locations/[^/]+/workforcePools/`) +) + +// Options stores the configuration for fetching tokens with external credentials. +type Options struct { + // Audience is the Secure Token Service (STS) audience which contains the resource name for the workload + // identity pool or the workforce pool and the provider identifier in that pool. + Audience string + // SubjectTokenType is the STS token type based on the Oauth2.0 token exchange spec + // e.g. `urn:ietf:params:oauth:token-type:jwt`. + SubjectTokenType string + // TokenURL is the STS token exchange endpoint. + TokenURL string + // TokenInfoURL is the token_info endpoint used to retrieve the account related information ( + // user attributes like account identifier, eg. email, username, uid, etc). This is + // needed for gCloud session account identification. + TokenInfoURL string + // ServiceAccountImpersonationURL is the URL for the service account impersonation request. This is only + // required for workload identity pools when APIs to be accessed have not integrated with UberMint. + ServiceAccountImpersonationURL string + // ServiceAccountImpersonationLifetimeSeconds is the number of seconds the service account impersonation + // token will be valid for. + ServiceAccountImpersonationLifetimeSeconds int + // ClientSecret is currently only required if token_info endpoint also + // needs to be called with the generated GCP access token. When provided, STS will be + // called with additional basic authentication using client_id as username and client_secret as password. + ClientSecret string + // ClientID is only required in conjunction with ClientSecret, as described above. + ClientID string + // CredentialSource contains the necessary information to retrieve the token itself, as well + // as some environmental information. + CredentialSource *credsfile.CredentialSource + // QuotaProjectID is injected by gCloud. If the value is non-empty, the Auth libraries + // will set the x-goog-user-project which overrides the project associated with the credentials. + QuotaProjectID string + // Scopes contains the desired scopes for the returned access token. + Scopes []string + // WorkforcePoolUserProject should be set when it is a workforce pool and + // not a workload identity pool. The underlying principal must still have + // serviceusage.services.use IAM permission to use the project for + // billing/quota. Optional. + WorkforcePoolUserProject string + // UniverseDomain is the default service domain for a given Cloud universe. + // This value will be used in the default STS token URL. The default value + // is "googleapis.com". It will not be used if TokenURL is set. Optional. + UniverseDomain string + // SubjectTokenProvider is an optional token provider for OIDC/SAML + // credentials. One of SubjectTokenProvider, AWSSecurityCredentialProvider + // or CredentialSource must be provided. Optional. + SubjectTokenProvider SubjectTokenProvider + // AwsSecurityCredentialsProvider is an AWS Security Credential provider + // for AWS credentials. One of SubjectTokenProvider, + // AWSSecurityCredentialProvider or CredentialSource must be provided. Optional. + AwsSecurityCredentialsProvider AwsSecurityCredentialsProvider + // Client for token request. + Client *http.Client + // IsDefaultClient marks whether the client passed in is a default client that can be overriden. + // This is important for X509 credentials which should create a new client if the default was used + // but should respect a client explicitly passed in by the user. + IsDefaultClient bool + // Logger is used for debug logging. If provided, logging will be enabled + // at the loggers configured level. By default logging is disabled unless + // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default + // logger will be used. Optional. + Logger *slog.Logger +} + +// SubjectTokenProvider can be used to supply a subject token to exchange for a +// GCP access token. +type SubjectTokenProvider interface { + // SubjectToken should return a valid subject token or an error. + // The external account token provider does not cache the returned subject + // token, so caching logic should be implemented in the provider to prevent + // multiple requests for the same subject token. + SubjectToken(ctx context.Context, opts *RequestOptions) (string, error) +} + +// RequestOptions contains information about the requested subject token or AWS +// security credentials from the Google external account credential. +type RequestOptions struct { + // Audience is the requested audience for the external account credential. + Audience string + // Subject token type is the requested subject token type for the external + // account credential. Expected values include: + // “urn:ietf:params:oauth:token-type:jwt” + // “urn:ietf:params:oauth:token-type:id-token” + // “urn:ietf:params:oauth:token-type:saml2” + // “urn:ietf:params:aws:token-type:aws4_request” + SubjectTokenType string +} + +// AwsSecurityCredentialsProvider can be used to supply AwsSecurityCredentials +// and an AWS Region to exchange for a GCP access token. +type AwsSecurityCredentialsProvider interface { + // AwsRegion should return the AWS region or an error. + AwsRegion(ctx context.Context, opts *RequestOptions) (string, error) + // GetAwsSecurityCredentials should return a valid set of + // AwsSecurityCredentials or an error. The external account token provider + // does not cache the returned security credentials, so caching logic should + // be implemented in the provider to prevent multiple requests for the + // same security credentials. + AwsSecurityCredentials(ctx context.Context, opts *RequestOptions) (*AwsSecurityCredentials, error) +} + +// AwsSecurityCredentials models AWS security credentials. +type AwsSecurityCredentials struct { + // AccessKeyId is the AWS Access Key ID - Required. + AccessKeyID string `json:"AccessKeyID"` + // SecretAccessKey is the AWS Secret Access Key - Required. + SecretAccessKey string `json:"SecretAccessKey"` + // SessionToken is the AWS Session token. This should be provided for + // temporary AWS security credentials - Optional. + SessionToken string `json:"Token"` +} + +func (o *Options) validate() error { + if o.Audience == "" { + return fmt.Errorf("externalaccount: Audience must be set") + } + if o.SubjectTokenType == "" { + return fmt.Errorf("externalaccount: Subject token type must be set") + } + if o.WorkforcePoolUserProject != "" { + if valid := validWorkforceAudiencePattern.MatchString(o.Audience); !valid { + return fmt.Errorf("externalaccount: workforce_pool_user_project should not be set for non-workforce pool credentials") + } + } + count := 0 + if o.CredentialSource != nil { + count++ + } + if o.SubjectTokenProvider != nil { + count++ + } + if o.AwsSecurityCredentialsProvider != nil { + count++ + } + if count == 0 { + return fmt.Errorf("externalaccount: one of CredentialSource, SubjectTokenProvider, or AwsSecurityCredentialsProvider must be set") + } + if count > 1 { + return fmt.Errorf("externalaccount: only one of CredentialSource, SubjectTokenProvider, or AwsSecurityCredentialsProvider must be set") + } + return nil +} + +// client returns the http client that should be used for the token exchange. If a non-default client +// is provided, then the client configured in the options will always be returned. If a default client +// is provided and the options are configured for X509 credentials, a new client will be created. +func (o *Options) client() (*http.Client, error) { + // If a client was provided and no override certificate config location was provided, use the provided client. + if o.CredentialSource == nil || o.CredentialSource.Certificate == nil || (!o.IsDefaultClient && o.CredentialSource.Certificate.CertificateConfigLocation == "") { + return o.Client, nil + } + + // If a new client should be created, validate and use the certificate source to create a new mTLS client. + cert := o.CredentialSource.Certificate + if !cert.UseDefaultCertificateConfig && cert.CertificateConfigLocation == "" { + return nil, errors.New("credentials: \"certificate\" object must either specify a certificate_config_location or use_default_certificate_config should be true") + } + if cert.UseDefaultCertificateConfig && cert.CertificateConfigLocation != "" { + return nil, errors.New("credentials: \"certificate\" object cannot specify both a certificate_config_location and use_default_certificate_config=true") + } + return createX509Client(cert.CertificateConfigLocation) +} + +// resolveTokenURL sets the default STS token endpoint with the configured +// universe domain. +func (o *Options) resolveTokenURL() { + if o.TokenURL != "" { + return + } else if o.UniverseDomain != "" { + o.TokenURL = strings.Replace(defaultTokenURL, universeDomainPlaceholder, o.UniverseDomain, 1) + } else { + o.TokenURL = strings.Replace(defaultTokenURL, universeDomainPlaceholder, defaultUniverseDomain, 1) + } +} + +// NewTokenProvider returns a [cloud.google.com/go/auth.TokenProvider] +// configured with the provided options. +func NewTokenProvider(opts *Options) (auth.TokenProvider, error) { + if err := opts.validate(); err != nil { + return nil, err + } + opts.resolveTokenURL() + logger := internallog.New(opts.Logger) + stp, err := newSubjectTokenProvider(opts) + if err != nil { + return nil, err + } + + client, err := opts.client() + if err != nil { + return nil, err + } + + tp := &tokenProvider{ + client: client, + opts: opts, + stp: stp, + logger: logger, + } + + if opts.ServiceAccountImpersonationURL == "" { + return auth.NewCachedTokenProvider(tp, nil), nil + } + + scopes := make([]string, len(opts.Scopes)) + copy(scopes, opts.Scopes) + // needed for impersonation + tp.opts.Scopes = []string{"https://www.googleapis.com/auth/cloud-platform"} + imp, err := impersonate.NewTokenProvider(&impersonate.Options{ + Client: client, + URL: opts.ServiceAccountImpersonationURL, + Scopes: scopes, + Tp: auth.NewCachedTokenProvider(tp, nil), + TokenLifetimeSeconds: opts.ServiceAccountImpersonationLifetimeSeconds, + Logger: logger, + }) + if err != nil { + return nil, err + } + return auth.NewCachedTokenProvider(imp, nil), nil +} + +type subjectTokenProvider interface { + subjectToken(ctx context.Context) (string, error) + providerType() string +} + +// tokenProvider is the provider that handles external credentials. It is used to retrieve Tokens. +type tokenProvider struct { + client *http.Client + logger *slog.Logger + opts *Options + stp subjectTokenProvider +} + +func (tp *tokenProvider) Token(ctx context.Context) (*auth.Token, error) { + subjectToken, err := tp.stp.subjectToken(ctx) + if err != nil { + return nil, err + } + + stsRequest := &stsexchange.TokenRequest{ + GrantType: stsexchange.GrantType, + Audience: tp.opts.Audience, + Scope: tp.opts.Scopes, + RequestedTokenType: stsexchange.TokenType, + SubjectToken: subjectToken, + SubjectTokenType: tp.opts.SubjectTokenType, + } + header := make(http.Header) + header.Set("Content-Type", "application/x-www-form-urlencoded") + header.Add("x-goog-api-client", getGoogHeaderValue(tp.opts, tp.stp)) + clientAuth := stsexchange.ClientAuthentication{ + AuthStyle: auth.StyleInHeader, + ClientID: tp.opts.ClientID, + ClientSecret: tp.opts.ClientSecret, + } + var options map[string]interface{} + // Do not pass workforce_pool_user_project when client authentication is used. + // The client ID is sufficient for determining the user project. + if tp.opts.WorkforcePoolUserProject != "" && tp.opts.ClientID == "" { + options = map[string]interface{}{ + "userProject": tp.opts.WorkforcePoolUserProject, + } + } + stsResp, err := stsexchange.ExchangeToken(ctx, &stsexchange.Options{ + Client: tp.client, + Endpoint: tp.opts.TokenURL, + Request: stsRequest, + Authentication: clientAuth, + Headers: header, + ExtraOpts: options, + Logger: tp.logger, + }) + if err != nil { + return nil, err + } + + tok := &auth.Token{ + Value: stsResp.AccessToken, + Type: stsResp.TokenType, + } + // The RFC8693 doesn't define the explicit 0 of "expires_in" field behavior. + if stsResp.ExpiresIn <= 0 { + return nil, fmt.Errorf("credentials: got invalid expiry from security token service") + } + tok.Expiry = Now().Add(time.Duration(stsResp.ExpiresIn) * time.Second) + return tok, nil +} + +// newSubjectTokenProvider determines the type of credsfile.CredentialSource needed to create a +// subjectTokenProvider +func newSubjectTokenProvider(o *Options) (subjectTokenProvider, error) { + logger := internallog.New(o.Logger) + reqOpts := &RequestOptions{Audience: o.Audience, SubjectTokenType: o.SubjectTokenType} + if o.AwsSecurityCredentialsProvider != nil { + return &awsSubjectProvider{ + securityCredentialsProvider: o.AwsSecurityCredentialsProvider, + TargetResource: o.Audience, + reqOpts: reqOpts, + logger: logger, + }, nil + } else if o.SubjectTokenProvider != nil { + return &programmaticProvider{stp: o.SubjectTokenProvider, opts: reqOpts}, nil + } else if len(o.CredentialSource.EnvironmentID) > 3 && o.CredentialSource.EnvironmentID[:3] == "aws" { + if awsVersion, err := strconv.Atoi(o.CredentialSource.EnvironmentID[3:]); err == nil { + if awsVersion != 1 { + return nil, fmt.Errorf("credentials: aws version '%d' is not supported in the current build", awsVersion) + } + + awsProvider := &awsSubjectProvider{ + EnvironmentID: o.CredentialSource.EnvironmentID, + RegionURL: o.CredentialSource.RegionURL, + RegionalCredVerificationURL: o.CredentialSource.RegionalCredVerificationURL, + CredVerificationURL: o.CredentialSource.URL, + TargetResource: o.Audience, + Client: o.Client, + logger: logger, + } + if o.CredentialSource.IMDSv2SessionTokenURL != "" { + awsProvider.IMDSv2SessionTokenURL = o.CredentialSource.IMDSv2SessionTokenURL + } + + return awsProvider, nil + } + } else if o.CredentialSource.File != "" { + return &fileSubjectProvider{File: o.CredentialSource.File, Format: o.CredentialSource.Format}, nil + } else if o.CredentialSource.URL != "" { + return &urlSubjectProvider{ + URL: o.CredentialSource.URL, + Headers: o.CredentialSource.Headers, + Format: o.CredentialSource.Format, + Client: o.Client, + Logger: logger, + }, nil + } else if o.CredentialSource.Executable != nil { + ec := o.CredentialSource.Executable + if ec.Command == "" { + return nil, errors.New("credentials: missing `command` field — executable command must be provided") + } + + execProvider := &executableSubjectProvider{} + execProvider.Command = ec.Command + if ec.TimeoutMillis == 0 { + execProvider.Timeout = executableDefaultTimeout + } else { + execProvider.Timeout = time.Duration(ec.TimeoutMillis) * time.Millisecond + if execProvider.Timeout < timeoutMinimum || execProvider.Timeout > timeoutMaximum { + return nil, fmt.Errorf("credentials: invalid `timeout_millis` field — executable timeout must be between %v and %v seconds", timeoutMinimum.Seconds(), timeoutMaximum.Seconds()) + } + } + execProvider.OutputFile = ec.OutputFile + execProvider.client = o.Client + execProvider.opts = o + execProvider.env = runtimeEnvironment{} + return execProvider, nil + } else if o.CredentialSource.Certificate != nil { + cert := o.CredentialSource.Certificate + if !cert.UseDefaultCertificateConfig && cert.CertificateConfigLocation == "" { + return nil, errors.New("credentials: \"certificate\" object must either specify a certificate_config_location or use_default_certificate_config should be true") + } + if cert.UseDefaultCertificateConfig && cert.CertificateConfigLocation != "" { + return nil, errors.New("credentials: \"certificate\" object cannot specify both a certificate_config_location and use_default_certificate_config=true") + } + return &x509Provider{ + TrustChainPath: o.CredentialSource.Certificate.TrustChainPath, + ConfigFilePath: o.CredentialSource.Certificate.CertificateConfigLocation, + }, nil + } + return nil, errors.New("credentials: unable to parse credential source") +} + +func getGoogHeaderValue(conf *Options, p subjectTokenProvider) string { + return fmt.Sprintf("gl-go/%s auth/%s google-byoid-sdk source/%s sa-impersonation/%t config-lifetime/%t", + goVersion(), + "unknown", + p.providerType(), + conf.ServiceAccountImpersonationURL != "", + conf.ServiceAccountImpersonationLifetimeSeconds != 0) +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/file_provider.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/file_provider.go new file mode 100644 index 000000000..8186939fe --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/file_provider.go @@ -0,0 +1,78 @@ +// Copyright 2023 Google LLC +// +// 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 externalaccount + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "os" + + "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/credsfile" +) + +const ( + fileProviderType = "file" +) + +type fileSubjectProvider struct { + File string + Format *credsfile.Format +} + +func (sp *fileSubjectProvider) subjectToken(context.Context) (string, error) { + tokenFile, err := os.Open(sp.File) + if err != nil { + return "", fmt.Errorf("credentials: failed to open credential file %q: %w", sp.File, err) + } + defer tokenFile.Close() + tokenBytes, err := internal.ReadAll(tokenFile) + if err != nil { + return "", fmt.Errorf("credentials: failed to read credential file: %w", err) + } + tokenBytes = bytes.TrimSpace(tokenBytes) + + if sp.Format == nil { + return string(tokenBytes), nil + } + switch sp.Format.Type { + case fileTypeJSON: + jsonData := make(map[string]interface{}) + err = json.Unmarshal(tokenBytes, &jsonData) + if err != nil { + return "", fmt.Errorf("credentials: failed to unmarshal subject token file: %w", err) + } + val, ok := jsonData[sp.Format.SubjectTokenFieldName] + if !ok { + return "", errors.New("credentials: provided subject_token_field_name not found in credentials") + } + token, ok := val.(string) + if !ok { + return "", errors.New("credentials: improperly formatted subject token") + } + return token, nil + case fileTypeText: + return string(tokenBytes), nil + default: + return "", errors.New("credentials: invalid credential_source file format type: " + sp.Format.Type) + } +} + +func (sp *fileSubjectProvider) providerType() string { + return fileProviderType +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/info.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/info.go new file mode 100644 index 000000000..8e4b4379b --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/info.go @@ -0,0 +1,74 @@ +// Copyright 2023 Google LLC +// +// 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 externalaccount + +import ( + "runtime" + "strings" + "unicode" +) + +var ( + // version is a package internal global variable for testing purposes. + version = runtime.Version +) + +// versionUnknown is only used when the runtime version cannot be determined. +const versionUnknown = "UNKNOWN" + +// goVersion returns a Go runtime version derived from the runtime environment +// that is modified to be suitable for reporting in a header, meaning it has no +// whitespace. If it is unable to determine the Go runtime version, it returns +// versionUnknown. +func goVersion() string { + const develPrefix = "devel +" + + s := version() + if strings.HasPrefix(s, develPrefix) { + s = s[len(develPrefix):] + if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { + s = s[:p] + } + return s + } else if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { + s = s[:p] + } + + notSemverRune := func(r rune) bool { + return !strings.ContainsRune("0123456789.", r) + } + + if strings.HasPrefix(s, "go1") { + s = s[2:] + var prerelease string + if p := strings.IndexFunc(s, notSemverRune); p >= 0 { + s, prerelease = s[:p], s[p:] + } + if strings.HasSuffix(s, ".") { + s += "0" + } else if strings.Count(s, ".") < 2 { + s += ".0" + } + if prerelease != "" { + // Some release candidates already have a dash in them. + if !strings.HasPrefix(prerelease, "-") { + prerelease = "-" + prerelease + } + s += prerelease + } + return s + } + return versionUnknown +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/programmatic_provider.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/programmatic_provider.go new file mode 100644 index 000000000..be3c87351 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/programmatic_provider.go @@ -0,0 +1,30 @@ +// Copyright 2024 Google LLC +// +// 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 externalaccount + +import "context" + +type programmaticProvider struct { + opts *RequestOptions + stp SubjectTokenProvider +} + +func (pp *programmaticProvider) providerType() string { + return programmaticProviderType +} + +func (pp *programmaticProvider) subjectToken(ctx context.Context) (string, error) { + return pp.stp.SubjectToken(ctx, pp.opts) +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/url_provider.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/url_provider.go new file mode 100644 index 000000000..754ecf4fe --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/url_provider.go @@ -0,0 +1,93 @@ +// Copyright 2023 Google LLC +// +// 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 externalaccount + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "log/slog" + "net/http" + + "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/credsfile" + "github.com/googleapis/gax-go/v2/internallog" +) + +const ( + fileTypeText = "text" + fileTypeJSON = "json" + urlProviderType = "url" + programmaticProviderType = "programmatic" + x509ProviderType = "x509" +) + +type urlSubjectProvider struct { + URL string + Headers map[string]string + Format *credsfile.Format + Client *http.Client + Logger *slog.Logger +} + +func (sp *urlSubjectProvider) subjectToken(ctx context.Context) (string, error) { + req, err := http.NewRequestWithContext(ctx, "GET", sp.URL, nil) + if err != nil { + return "", fmt.Errorf("credentials: HTTP request for URL-sourced credential failed: %w", err) + } + + for key, val := range sp.Headers { + req.Header.Add(key, val) + } + sp.Logger.DebugContext(ctx, "url subject token request", "request", internallog.HTTPRequest(req, nil)) + resp, body, err := internal.DoRequest(sp.Client, req) + if err != nil { + return "", fmt.Errorf("credentials: invalid response when retrieving subject token: %w", err) + } + sp.Logger.DebugContext(ctx, "url subject token response", "response", internallog.HTTPResponse(resp, body)) + if c := resp.StatusCode; c < http.StatusOK || c >= http.StatusMultipleChoices { + return "", fmt.Errorf("credentials: status code %d: %s", c, body) + } + + if sp.Format == nil { + return string(body), nil + } + switch sp.Format.Type { + case "json": + jsonData := make(map[string]interface{}) + err = json.Unmarshal(body, &jsonData) + if err != nil { + return "", fmt.Errorf("credentials: failed to unmarshal subject token file: %w", err) + } + val, ok := jsonData[sp.Format.SubjectTokenFieldName] + if !ok { + return "", errors.New("credentials: provided subject_token_field_name not found in credentials") + } + token, ok := val.(string) + if !ok { + return "", errors.New("credentials: improperly formatted subject token") + } + return token, nil + case fileTypeText: + return string(body), nil + default: + return "", errors.New("credentials: invalid credential_source file format type: " + sp.Format.Type) + } +} + +func (sp *urlSubjectProvider) providerType() string { + return urlProviderType +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/x509_provider.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/x509_provider.go new file mode 100644 index 000000000..d86ca593c --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/x509_provider.go @@ -0,0 +1,220 @@ +// Copyright 2024 Google LLC +// +// 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 externalaccount + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/base64" + "encoding/json" + "encoding/pem" + "errors" + "fmt" + "io/fs" + "net/http" + "os" + "strings" + "time" + + "cloud.google.com/go/auth/internal/transport/cert" +) + +// x509Provider implements the subjectTokenProvider type for x509 workload +// identity credentials. This provider retrieves and formats a JSON array +// containing the leaf certificate and trust chain (if provided) as +// base64-encoded strings. This JSON array serves as the subject token for +// mTLS authentication. +type x509Provider struct { + // TrustChainPath is the path to the file containing the trust chain certificates. + // The file should contain one or more PEM-encoded certificates. + TrustChainPath string + // ConfigFilePath is the path to the configuration file containing the path + // to the leaf certificate file. + ConfigFilePath string +} + +const pemCertificateHeader = "-----BEGIN CERTIFICATE-----" + +func (xp *x509Provider) providerType() string { + return x509ProviderType +} + +// loadLeafCertificate loads and parses the leaf certificate from the specified +// configuration file. It retrieves the certificate path from the config file, +// reads the certificate file, and parses the certificate data. +func loadLeafCertificate(configFilePath string) (*x509.Certificate, error) { + // Get the path to the certificate file from the configuration file. + path, err := cert.GetCertificatePath(configFilePath) + if err != nil { + return nil, fmt.Errorf("failed to get certificate path from config file: %w", err) + } + leafCertBytes, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("failed to read leaf certificate file: %w", err) + } + // Parse the certificate bytes. + return parseCertificate(leafCertBytes) +} + +// encodeCert encodes a x509.Certificate to a base64 string. +func encodeCert(cert *x509.Certificate) string { + // cert.Raw contains the raw DER-encoded certificate. Encode the raw certificate bytes to base64. + return base64.StdEncoding.EncodeToString(cert.Raw) +} + +// parseCertificate parses a PEM-encoded certificate from the given byte slice. +func parseCertificate(certData []byte) (*x509.Certificate, error) { + if len(certData) == 0 { + return nil, errors.New("invalid certificate data: empty input") + } + // Decode the PEM-encoded data. + block, _ := pem.Decode(certData) + if block == nil { + return nil, errors.New("invalid PEM-encoded certificate data: no PEM block found") + } + if block.Type != "CERTIFICATE" { + return nil, fmt.Errorf("invalid PEM-encoded certificate data: expected CERTIFICATE block type, got %s", block.Type) + } + // Parse the DER-encoded certificate. + certificate, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, fmt.Errorf("failed to parse certificate: %w", err) + } + return certificate, nil +} + +// readTrustChain reads a file of PEM-encoded X.509 certificates and returns a slice of parsed certificates. +// It splits the file content into PEM certificate blocks and parses each one. +func readTrustChain(trustChainPath string) ([]*x509.Certificate, error) { + certificateTrustChain := []*x509.Certificate{} + + // If no trust chain path is provided, return an empty slice. + if trustChainPath == "" { + return certificateTrustChain, nil + } + + // Read the trust chain file. + trustChainData, err := os.ReadFile(trustChainPath) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return nil, fmt.Errorf("trust chain file not found: %w", err) + } + return nil, fmt.Errorf("failed to read trust chain file: %w", err) + } + + // Split the file content into PEM certificate blocks. + certBlocks := strings.Split(string(trustChainData), pemCertificateHeader) + + // Iterate over each certificate block. + for _, certBlock := range certBlocks { + // Trim whitespace from the block. + certBlock = strings.TrimSpace(certBlock) + + if certBlock != "" { + // Add the PEM header to the block. + certData := pemCertificateHeader + "\n" + certBlock + + // Parse the certificate data. + cert, err := parseCertificate([]byte(certData)) + if err != nil { + return nil, fmt.Errorf("error parsing certificate from trust chain file: %w", err) + } + + // Append the certificate to the trust chain. + certificateTrustChain = append(certificateTrustChain, cert) + } + } + + return certificateTrustChain, nil +} + +// subjectToken retrieves the X.509 subject token. It loads the leaf +// certificate and, if a trust chain path is configured, the trust chain +// certificates. It then constructs a JSON array containing the base64-encoded +// leaf certificate and each base64-encoded certificate in the trust chain. +// The leaf certificate must be at the top of the trust chain file. This JSON +// array is used as the subject token for mTLS authentication. +func (xp *x509Provider) subjectToken(context.Context) (string, error) { + // Load the leaf certificate. + leafCert, err := loadLeafCertificate(xp.ConfigFilePath) + if err != nil { + return "", fmt.Errorf("failed to load leaf certificate: %w", err) + } + + // Read the trust chain. + trustChain, err := readTrustChain(xp.TrustChainPath) + if err != nil { + return "", fmt.Errorf("failed to read trust chain: %w", err) + } + + // Initialize the certificate chain with the leaf certificate. + certChain := []string{encodeCert(leafCert)} + + // If there is a trust chain, add certificates to the certificate chain. + if len(trustChain) > 0 { + firstCert := encodeCert(trustChain[0]) + + // If the first certificate in the trust chain is not the same as the leaf certificate, add it to the chain. + if firstCert != certChain[0] { + certChain = append(certChain, firstCert) + } + + // Iterate over the remaining certificates in the trust chain. + for i := 1; i < len(trustChain); i++ { + encoded := encodeCert(trustChain[i]) + + // Return an error if the current certificate is the same as the leaf certificate. + if encoded == certChain[0] { + return "", errors.New("the leaf certificate must be at the top of the trust chain file") + } + + // Add the current certificate to the chain. + certChain = append(certChain, encoded) + } + } + + // Convert the certificate chain to a JSON array of base64-encoded strings. + jsonChain, err := json.Marshal(certChain) + if err != nil { + return "", fmt.Errorf("failed to format certificate data: %w", err) + } + + // Return the JSON-formatted certificate chain. + return string(jsonChain), nil + +} + +// createX509Client creates a new client that is configured with mTLS, using the +// certificate configuration specified in the credential source. +func createX509Client(certificateConfigLocation string) (*http.Client, error) { + certProvider, err := cert.NewWorkloadX509CertProvider(certificateConfigLocation) + if err != nil { + return nil, err + } + trans := http.DefaultTransport.(*http.Transport).Clone() + + trans.TLSClientConfig = &tls.Config{ + GetClientCertificate: certProvider, + } + + // Create a client with default settings plus the X509 workload cert and key. + client := &http.Client{ + Transport: trans, + Timeout: 30 * time.Second, + } + + return client, nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccountuser/externalaccountuser.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccountuser/externalaccountuser.go new file mode 100644 index 000000000..ae39206e5 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/externalaccountuser/externalaccountuser.go @@ -0,0 +1,115 @@ +// Copyright 2023 Google LLC +// +// 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 externalaccountuser + +import ( + "context" + "errors" + "log/slog" + "net/http" + "time" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/credentials/internal/stsexchange" + "cloud.google.com/go/auth/internal" + "github.com/googleapis/gax-go/v2/internallog" +) + +// Options stores the configuration for fetching tokens with external authorized +// user credentials. +type Options struct { + // Audience is the Secure Token Service (STS) audience which contains the + // resource name for the workforce pool and the provider identifier in that + // pool. + Audience string + // RefreshToken is the OAuth 2.0 refresh token. + RefreshToken string + // TokenURL is the STS token exchange endpoint for refresh. + TokenURL string + // TokenInfoURL is the STS endpoint URL for token introspection. Optional. + TokenInfoURL string + // ClientID is only required in conjunction with ClientSecret, as described + // below. + ClientID string + // ClientSecret is currently only required if token_info endpoint also needs + // to be called with the generated a cloud access token. When provided, STS + // will be called with additional basic authentication using client_id as + // username and client_secret as password. + ClientSecret string + // Scopes contains the desired scopes for the returned access token. + Scopes []string + + // Client for token request. + Client *http.Client + // Logger for logging. + Logger *slog.Logger +} + +func (c *Options) validate() bool { + return c.ClientID != "" && c.ClientSecret != "" && c.RefreshToken != "" && c.TokenURL != "" +} + +// NewTokenProvider returns a [cloud.google.com/go/auth.TokenProvider] +// configured with the provided options. +func NewTokenProvider(opts *Options) (auth.TokenProvider, error) { + if !opts.validate() { + return nil, errors.New("credentials: invalid external_account_authorized_user configuration") + } + + tp := &tokenProvider{ + o: opts, + } + return auth.NewCachedTokenProvider(tp, nil), nil +} + +type tokenProvider struct { + o *Options +} + +func (tp *tokenProvider) Token(ctx context.Context) (*auth.Token, error) { + opts := tp.o + + clientAuth := stsexchange.ClientAuthentication{ + AuthStyle: auth.StyleInHeader, + ClientID: opts.ClientID, + ClientSecret: opts.ClientSecret, + } + headers := make(http.Header) + headers.Set("Content-Type", "application/x-www-form-urlencoded") + stsResponse, err := stsexchange.RefreshAccessToken(ctx, &stsexchange.Options{ + Client: opts.Client, + Endpoint: opts.TokenURL, + RefreshToken: opts.RefreshToken, + Authentication: clientAuth, + Headers: headers, + Logger: internallog.New(tp.o.Logger), + }) + if err != nil { + return nil, err + } + if stsResponse.ExpiresIn < 0 { + return nil, errors.New("credentials: invalid expiry from security token service") + } + + // guarded by the wrapping with CachedTokenProvider + if stsResponse.RefreshToken != "" { + opts.RefreshToken = stsResponse.RefreshToken + } + return &auth.Token{ + Value: stsResponse.AccessToken, + Expiry: time.Now().UTC().Add(time.Duration(stsResponse.ExpiresIn) * time.Second), + Type: internal.TokenTypeBearer, + }, nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/gdch/gdch.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/gdch/gdch.go new file mode 100644 index 000000000..19a205141 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/gdch/gdch.go @@ -0,0 +1,198 @@ +// Copyright 2023 Google LLC +// +// 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 gdch + +import ( + "bytes" + "context" + "crypto" + "crypto/tls" + "crypto/x509" + "encoding/json" + "errors" + "fmt" + "log/slog" + "net/http" + "os" + "time" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/credsfile" + "cloud.google.com/go/auth/internal/jwt" + "github.com/googleapis/gax-go/v2/internallog" +) + +const ( + // GrantType is the grant type for the token request. + GrantType = "urn:ietf:params:oauth:token-type:token-exchange" + requestTokenType = "urn:ietf:params:oauth:token-type:access_token" + subjectTokenType = "urn:k8s:params:oauth:token-type:serviceaccount" +) + +var ( + gdchSupportFormatVersions map[string]bool = map[string]bool{ + "1": true, + } +) + +// Options for [NewTokenProvider]. +type Options struct { + STSAudience string + Client *http.Client + Logger *slog.Logger +} + +// NewTokenProvider returns a [cloud.google.com/go/auth.TokenProvider] from a +// GDCH cred file. +func NewTokenProvider(f *credsfile.GDCHServiceAccountFile, o *Options) (auth.TokenProvider, error) { + if !gdchSupportFormatVersions[f.FormatVersion] { + return nil, fmt.Errorf("credentials: unsupported gdch_service_account format %q", f.FormatVersion) + } + if o.STSAudience == "" { + return nil, errors.New("credentials: STSAudience must be set for the GDCH auth flows") + } + signer, err := internal.ParseKey([]byte(f.PrivateKey)) + if err != nil { + return nil, err + } + certPool, err := loadCertPool(f.CertPath) + if err != nil { + return nil, err + } + + tp := gdchProvider{ + serviceIdentity: fmt.Sprintf("system:serviceaccount:%s:%s", f.Project, f.Name), + tokenURL: f.TokenURL, + aud: o.STSAudience, + signer: signer, + pkID: f.PrivateKeyID, + certPool: certPool, + client: o.Client, + logger: internallog.New(o.Logger), + } + return tp, nil +} + +func loadCertPool(path string) (*x509.CertPool, error) { + pool := x509.NewCertPool() + pem, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("credentials: failed to read certificate: %w", err) + } + pool.AppendCertsFromPEM(pem) + return pool, nil +} + +type gdchProvider struct { + serviceIdentity string + tokenURL string + aud string + signer crypto.Signer + pkID string + certPool *x509.CertPool + + client *http.Client + logger *slog.Logger +} + +func (g gdchProvider) Token(ctx context.Context) (*auth.Token, error) { + addCertToTransport(g.client, g.certPool) + iat := time.Now() + exp := iat.Add(time.Hour) + claims := jwt.Claims{ + Iss: g.serviceIdentity, + Sub: g.serviceIdentity, + Aud: g.tokenURL, + Iat: iat.Unix(), + Exp: exp.Unix(), + } + h := jwt.Header{ + Algorithm: jwt.HeaderAlgES256, + Type: jwt.HeaderType, + KeyID: g.pkID, + } + payload, err := jwt.EncodeJWS(&h, &claims, g.signer) + if err != nil { + return nil, err + } + + v := map[string]string{ + "grant_type": GrantType, + "audience": g.aud, + "requested_token_type": requestTokenType, + "subject_token": payload, + "subject_token_type": subjectTokenType, + } + + r, err := json.Marshal(v) + if err != nil { + return nil, fmt.Errorf("credentials: cannot marshal token request: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "POST", g.tokenURL, bytes.NewReader(r)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + g.logger.DebugContext(ctx, "gdch token request", "request", internallog.HTTPRequest(req, r)) + resp, body, err := internal.DoRequest(g.client, req) + if err != nil { + return nil, fmt.Errorf("credentials: cannot fetch token: %w", err) + } + g.logger.DebugContext(ctx, "gdch token response", "response", internallog.HTTPResponse(resp, body)) + if c := resp.StatusCode; c < http.StatusOK || c > http.StatusMultipleChoices { + return nil, &auth.Error{ + Response: resp, + Body: body, + } + } + + var tokenRes struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + ExpiresIn int64 `json:"expires_in"` // relative seconds from now + } + if err := json.Unmarshal(body, &tokenRes); err != nil { + return nil, fmt.Errorf("credentials: cannot fetch token: %w", err) + } + token := &auth.Token{ + Value: tokenRes.AccessToken, + Type: tokenRes.TokenType, + } + raw := make(map[string]interface{}) + json.Unmarshal(body, &raw) // no error checks for optional fields + token.Metadata = raw + + if secs := tokenRes.ExpiresIn; secs > 0 { + token.Expiry = time.Now().Add(time.Duration(secs) * time.Second) + } + return token, nil +} + +// addCertToTransport makes a best effort attempt at adding in the cert info to +// the client. It tries to keep all configured transport settings if the +// underlying transport is an http.Transport. Or else it overwrites the +// transport with defaults adding in the certs. +func addCertToTransport(hc *http.Client, certPool *x509.CertPool) { + trans, ok := hc.Transport.(*http.Transport) + if !ok { + trans = http.DefaultTransport.(*http.Transport).Clone() + } + trans.TLSClientConfig = &tls.Config{ + RootCAs: certPool, + } + hc.Transport = trans +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/idtoken.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/idtoken.go new file mode 100644 index 000000000..705462c16 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/idtoken.go @@ -0,0 +1,105 @@ +// Copyright 2025 Google LLC +// +// 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 impersonate + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "strings" + "time" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/internal" + "github.com/googleapis/gax-go/v2/internallog" +) + +var ( + universeDomainPlaceholder = "UNIVERSE_DOMAIN" + iamCredentialsUniverseDomainEndpoint = "https://iamcredentials.UNIVERSE_DOMAIN" +) + +// IDTokenIAMOptions provides configuration for [IDTokenIAMOptions.Token]. +type IDTokenIAMOptions struct { + // Client is required. + Client *http.Client + // Logger is required. + Logger *slog.Logger + UniverseDomain auth.CredentialsPropertyProvider + ServiceAccountEmail string + GenerateIDTokenRequest +} + +// GenerateIDTokenRequest holds the request to the IAM generateIdToken RPC. +type GenerateIDTokenRequest struct { + Audience string `json:"audience"` + IncludeEmail bool `json:"includeEmail"` + // Delegates are the ordered, fully-qualified resource name for service + // accounts in a delegation chain. Each service account must be granted + // roles/iam.serviceAccountTokenCreator on the next service account in the + // chain. The delegates must have the following format: + // projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}. The - wildcard + // character is required; replacing it with a project ID is invalid. + // Optional. + Delegates []string `json:"delegates,omitempty"` +} + +// GenerateIDTokenResponse holds the response from the IAM generateIdToken RPC. +type GenerateIDTokenResponse struct { + Token string `json:"token"` +} + +// Token call IAM generateIdToken with the configuration provided in [IDTokenIAMOptions]. +func (o IDTokenIAMOptions) Token(ctx context.Context) (*auth.Token, error) { + universeDomain, err := o.UniverseDomain.GetProperty(ctx) + if err != nil { + return nil, err + } + endpoint := strings.Replace(iamCredentialsUniverseDomainEndpoint, universeDomainPlaceholder, universeDomain, 1) + url := fmt.Sprintf("%s/v1/%s:generateIdToken", endpoint, internal.FormatIAMServiceAccountResource(o.ServiceAccountEmail)) + + bodyBytes, err := json.Marshal(o.GenerateIDTokenRequest) + if err != nil { + return nil, fmt.Errorf("impersonate: unable to marshal request: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(bodyBytes)) + if err != nil { + return nil, fmt.Errorf("impersonate: unable to create request: %w", err) + } + req.Header.Set("Content-Type", "application/json") + o.Logger.DebugContext(ctx, "impersonated idtoken request", "request", internallog.HTTPRequest(req, bodyBytes)) + resp, body, err := internal.DoRequest(o.Client, req) + if err != nil { + return nil, fmt.Errorf("impersonate: unable to generate ID token: %w", err) + } + o.Logger.DebugContext(ctx, "impersonated idtoken response", "response", internallog.HTTPResponse(resp, body)) + if c := resp.StatusCode; c < 200 || c > 299 { + return nil, fmt.Errorf("impersonate: status code %d: %s", c, body) + } + + var tokenResp GenerateIDTokenResponse + if err := json.Unmarshal(body, &tokenResp); err != nil { + return nil, fmt.Errorf("impersonate: unable to parse response: %w", err) + } + return &auth.Token{ + Value: tokenResp.Token, + // Generated ID tokens are good for one hour. + Expiry: time.Now().Add(1 * time.Hour), + }, nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go new file mode 100644 index 000000000..8253376ef --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go @@ -0,0 +1,168 @@ +// Copyright 2023 Google LLC +// +// 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 impersonate + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "log/slog" + "net/http" + "regexp" + "time" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/transport/headers" + "github.com/googleapis/gax-go/v2/internallog" +) + +const ( + defaultTokenLifetime = "3600s" + authHeaderKey = "Authorization" +) + +var serviceAccountEmailRegex = regexp.MustCompile(`serviceAccounts/(.+?):generateAccessToken`) + +// generateAccesstokenReq is used for service account impersonation +type generateAccessTokenReq struct { + Delegates []string `json:"delegates,omitempty"` + Lifetime string `json:"lifetime,omitempty"` + Scope []string `json:"scope,omitempty"` +} + +type impersonateTokenResponse struct { + AccessToken string `json:"accessToken"` + ExpireTime string `json:"expireTime"` +} + +// NewTokenProvider uses a source credential, stored in Ts, to request an access token to the provided URL. +// Scopes can be defined when the access token is requested. +func NewTokenProvider(opts *Options) (auth.TokenProvider, error) { + if err := opts.validate(); err != nil { + return nil, err + } + return opts, nil +} + +// Options for [NewTokenProvider]. +type Options struct { + // Tp is the source credential used to generate a token on the + // impersonated service account. Required. + Tp auth.TokenProvider + + // URL is the endpoint to call to generate a token + // on behalf of the service account. Required. + URL string + // Scopes that the impersonated credential should have. Required. + Scopes []string + // Delegates are the service account email addresses in a delegation chain. + // Each service account must be granted roles/iam.serviceAccountTokenCreator + // on the next service account in the chain. Optional. + Delegates []string + // TokenLifetimeSeconds is the number of seconds the impersonation token will + // be valid for. Defaults to 1 hour if unset. Optional. + TokenLifetimeSeconds int + // Client configures the underlying client used to make network requests + // when fetching tokens. Required. + Client *http.Client + // Logger is used for debug logging. If provided, logging will be enabled + // at the loggers configured level. By default logging is disabled unless + // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default + // logger will be used. Optional. + Logger *slog.Logger + // UniverseDomain is the default service domain for a given Cloud universe. + UniverseDomain string +} + +func (o *Options) validate() error { + if o.Tp == nil { + return errors.New("credentials: missing required 'source_credentials' field in impersonated credentials") + } + if o.URL == "" { + return errors.New("credentials: missing required 'service_account_impersonation_url' field in impersonated credentials") + } + return nil +} + +// Token performs the exchange to get a temporary service account token to allow access to GCP. +func (o *Options) Token(ctx context.Context) (*auth.Token, error) { + logger := internallog.New(o.Logger) + lifetime := defaultTokenLifetime + if o.TokenLifetimeSeconds != 0 { + lifetime = fmt.Sprintf("%ds", o.TokenLifetimeSeconds) + } + reqBody := generateAccessTokenReq{ + Lifetime: lifetime, + Scope: o.Scopes, + Delegates: o.Delegates, + } + b, err := json.Marshal(reqBody) + if err != nil { + return nil, fmt.Errorf("credentials: unable to marshal request: %w", err) + } + req, err := http.NewRequestWithContext(ctx, "POST", o.URL, bytes.NewReader(b)) + if err != nil { + return nil, fmt.Errorf("credentials: unable to create impersonation request: %w", err) + } + req.Header.Set("Content-Type", "application/json") + sourceToken, err := o.Tp.Token(ctx) + if err != nil { + return nil, err + } + headers.SetAuthHeader(sourceToken, req) + logger.DebugContext(ctx, "impersonated token request", "request", internallog.HTTPRequest(req, b)) + resp, body, err := internal.DoRequest(o.Client, req) + if err != nil { + return nil, fmt.Errorf("credentials: unable to generate access token: %w", err) + } + logger.DebugContext(ctx, "impersonated token response", "response", internallog.HTTPResponse(resp, body)) + if c := resp.StatusCode; c < http.StatusOK || c >= http.StatusMultipleChoices { + return nil, fmt.Errorf("credentials: status code %d: %s", c, body) + } + + var accessTokenResp impersonateTokenResponse + if err := json.Unmarshal(body, &accessTokenResp); err != nil { + return nil, fmt.Errorf("credentials: unable to parse response: %w", err) + } + expiry, err := time.Parse(time.RFC3339, accessTokenResp.ExpireTime) + if err != nil { + return nil, fmt.Errorf("credentials: unable to parse expiry: %w", err) + } + token := &auth.Token{ + Value: accessTokenResp.AccessToken, + Expiry: expiry, + Type: internal.TokenTypeBearer, + } + return token, nil +} + +// ExtractServiceAccountEmail extracts the service account email from the impersonation URL. +// The impersonation URL is expected to be in the format: +// https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{SERVICE_ACCOUNT_EMAIL}:generateAccessToken +// or +// https://iamcredentials.googleapis.com/v1/projects/{PROJECT_ID}/serviceAccounts/{SERVICE_ACCOUNT_EMAIL}:generateAccessToken +// Returns an error if the email cannot be extracted. +func ExtractServiceAccountEmail(impersonationURL string) (string, error) { + matches := serviceAccountEmailRegex.FindStringSubmatch(impersonationURL) + + if len(matches) < 2 { + return "", fmt.Errorf("credentials: invalid impersonation URL format: %s", impersonationURL) + } + + return matches[1], nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/stsexchange/sts_exchange.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/stsexchange/sts_exchange.go new file mode 100644 index 000000000..e1d2b1503 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/internal/stsexchange/sts_exchange.go @@ -0,0 +1,167 @@ +// Copyright 2023 Google LLC +// +// 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 stsexchange + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "net/url" + "strconv" + "strings" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/internal" + "github.com/googleapis/gax-go/v2/internallog" +) + +const ( + // GrantType for a sts exchange. + GrantType = "urn:ietf:params:oauth:grant-type:token-exchange" + // TokenType for a sts exchange. + TokenType = "urn:ietf:params:oauth:token-type:access_token" + + jwtTokenType = "urn:ietf:params:oauth:token-type:jwt" +) + +// Options stores the configuration for making an sts exchange request. +type Options struct { + Client *http.Client + Logger *slog.Logger + Endpoint string + Request *TokenRequest + Authentication ClientAuthentication + Headers http.Header + // ExtraOpts are optional fields marshalled into the `options` field of the + // request body. + ExtraOpts map[string]interface{} + RefreshToken string +} + +// RefreshAccessToken performs the token exchange using a refresh token flow. +func RefreshAccessToken(ctx context.Context, opts *Options) (*TokenResponse, error) { + data := url.Values{} + data.Set("grant_type", "refresh_token") + data.Set("refresh_token", opts.RefreshToken) + return doRequest(ctx, opts, data) +} + +// ExchangeToken performs an oauth2 token exchange with the provided endpoint. +func ExchangeToken(ctx context.Context, opts *Options) (*TokenResponse, error) { + data := url.Values{} + data.Set("audience", opts.Request.Audience) + data.Set("grant_type", GrantType) + data.Set("requested_token_type", TokenType) + data.Set("subject_token_type", opts.Request.SubjectTokenType) + data.Set("subject_token", opts.Request.SubjectToken) + data.Set("scope", strings.Join(opts.Request.Scope, " ")) + if opts.ExtraOpts != nil { + opts, err := json.Marshal(opts.ExtraOpts) + if err != nil { + return nil, fmt.Errorf("credentials: failed to marshal additional options: %w", err) + } + data.Set("options", string(opts)) + } + return doRequest(ctx, opts, data) +} + +func doRequest(ctx context.Context, opts *Options, data url.Values) (*TokenResponse, error) { + opts.Authentication.InjectAuthentication(data, opts.Headers) + encodedData := data.Encode() + logger := internallog.New(opts.Logger) + + req, err := http.NewRequestWithContext(ctx, "POST", opts.Endpoint, strings.NewReader(encodedData)) + if err != nil { + return nil, fmt.Errorf("credentials: failed to properly build http request: %w", err) + + } + for key, list := range opts.Headers { + for _, val := range list { + req.Header.Add(key, val) + } + } + req.Header.Set("Content-Length", strconv.Itoa(len(encodedData))) + + logger.DebugContext(ctx, "sts token request", "request", internallog.HTTPRequest(req, []byte(encodedData))) + resp, body, err := internal.DoRequest(opts.Client, req) + if err != nil { + return nil, fmt.Errorf("credentials: invalid response from Secure Token Server: %w", err) + } + logger.DebugContext(ctx, "sts token response", "response", internallog.HTTPResponse(resp, body)) + if c := resp.StatusCode; c < http.StatusOK || c > http.StatusMultipleChoices { + return nil, fmt.Errorf("credentials: status code %d: %s", c, body) + } + var stsResp TokenResponse + if err := json.Unmarshal(body, &stsResp); err != nil { + return nil, fmt.Errorf("credentials: failed to unmarshal response body from Secure Token Server: %w", err) + } + + return &stsResp, nil +} + +// TokenRequest contains fields necessary to make an oauth2 token +// exchange. +type TokenRequest struct { + ActingParty struct { + ActorToken string + ActorTokenType string + } + GrantType string + Resource string + Audience string + Scope []string + RequestedTokenType string + SubjectToken string + SubjectTokenType string +} + +// TokenResponse is used to decode the remote server response during +// an oauth2 token exchange. +type TokenResponse struct { + AccessToken string `json:"access_token"` + IssuedTokenType string `json:"issued_token_type"` + TokenType string `json:"token_type"` + ExpiresIn int `json:"expires_in"` + Scope string `json:"scope"` + RefreshToken string `json:"refresh_token"` +} + +// ClientAuthentication represents an OAuth client ID and secret and the +// mechanism for passing these credentials as stated in rfc6749#2.3.1. +type ClientAuthentication struct { + AuthStyle auth.Style + ClientID string + ClientSecret string +} + +// InjectAuthentication is used to add authentication to a Secure Token Service +// exchange request. It modifies either the passed url.Values or http.Header +// depending on the desired authentication format. +func (c *ClientAuthentication) InjectAuthentication(values url.Values, headers http.Header) { + if c.ClientID == "" || c.ClientSecret == "" || values == nil || headers == nil { + return + } + switch c.AuthStyle { + case auth.StyleInHeader: + plainHeader := c.ClientID + ":" + c.ClientSecret + headers.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(plainHeader))) + default: + values.Set("client_id", c.ClientID) + values.Set("client_secret", c.ClientSecret) + } +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/selfsignedjwt.go b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/selfsignedjwt.go new file mode 100644 index 000000000..8d335ccec --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/credentials/selfsignedjwt.go @@ -0,0 +1,89 @@ +// Copyright 2023 Google LLC +// +// 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 credentials + +import ( + "context" + "crypto" + "errors" + "fmt" + "log/slog" + "strings" + "time" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/credsfile" + "cloud.google.com/go/auth/internal/jwt" +) + +var ( + // for testing + now func() time.Time = time.Now +) + +// configureSelfSignedJWT uses the private key in the service account to create +// a JWT without making a network call. +func configureSelfSignedJWT(f *credsfile.ServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { + if len(opts.scopes()) == 0 && opts.Audience == "" { + return nil, errors.New("credentials: both scopes and audience are empty") + } + signer, err := internal.ParseKey([]byte(f.PrivateKey)) + if err != nil { + return nil, fmt.Errorf("credentials: could not parse key: %w", err) + } + return &selfSignedTokenProvider{ + email: f.ClientEmail, + audience: opts.Audience, + scopes: opts.scopes(), + signer: signer, + pkID: f.PrivateKeyID, + logger: opts.logger(), + }, nil +} + +type selfSignedTokenProvider struct { + email string + audience string + scopes []string + signer crypto.Signer + pkID string + logger *slog.Logger +} + +func (tp *selfSignedTokenProvider) Token(context.Context) (*auth.Token, error) { + iat := now() + exp := iat.Add(time.Hour) + scope := strings.Join(tp.scopes, " ") + c := &jwt.Claims{ + Iss: tp.email, + Sub: tp.email, + Aud: tp.audience, + Scope: scope, + Iat: iat.Unix(), + Exp: exp.Unix(), + } + h := &jwt.Header{ + Algorithm: jwt.HeaderAlgRSA256, + Type: jwt.HeaderType, + KeyID: string(tp.pkID), + } + tok, err := jwt.EncodeJWS(h, c, tp.signer) + if err != nil { + return nil, fmt.Errorf("credentials: could not encode JWT: %w", err) + } + tp.logger.Debug("created self-signed JWT", "token", tok) + return &auth.Token{Value: tok, Type: internal.TokenTypeBearer, Expiry: exp}, nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/httptransport/httptransport.go b/plugins/traefik/vendor/cloud.google.com/go/auth/httptransport/httptransport.go new file mode 100644 index 000000000..bd693907f --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/httptransport/httptransport.go @@ -0,0 +1,254 @@ +// Copyright 2023 Google LLC +// +// 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 httptransport provides functionality for managing HTTP client +// connections to Google Cloud services. +package httptransport + +import ( + "crypto/tls" + "errors" + "fmt" + "log/slog" + "net/http" + + "cloud.google.com/go/auth" + detect "cloud.google.com/go/auth/credentials" + "cloud.google.com/go/auth/internal/transport" + "cloud.google.com/go/auth/internal/transport/headers" + "github.com/googleapis/gax-go/v2/internallog" +) + +// ClientCertProvider is a function that returns a TLS client certificate to be +// used when opening TLS connections. It follows the same semantics as +// [crypto/tls.Config.GetClientCertificate]. +type ClientCertProvider = func(*tls.CertificateRequestInfo) (*tls.Certificate, error) + +// Options used to configure a [net/http.Client] from [NewClient]. +type Options struct { + // DisableTelemetry disables default telemetry (OpenTelemetry). An example + // reason to do so would be to bind custom telemetry that overrides the + // defaults. + DisableTelemetry bool + // DisableAuthentication specifies that no authentication should be used. It + // is suitable only for testing and for accessing public resources, like + // public Google Cloud Storage buckets. + DisableAuthentication bool + // Headers are extra HTTP headers that will be appended to every outgoing + // request. + Headers http.Header + // BaseRoundTripper overrides the base transport used for serving requests. + // If specified ClientCertProvider is ignored. + BaseRoundTripper http.RoundTripper + // Endpoint overrides the default endpoint to be used for a service. + Endpoint string + // APIKey specifies an API key to be used as the basis for authentication. + // If set DetectOpts are ignored. + APIKey string + // Credentials used to add Authorization header to all requests. If set + // DetectOpts are ignored. + Credentials *auth.Credentials + // ClientCertProvider is a function that returns a TLS client certificate to + // be used when opening TLS connections. It follows the same semantics as + // crypto/tls.Config.GetClientCertificate. + ClientCertProvider ClientCertProvider + // DetectOpts configures settings for detect Application Default + // Credentials. + DetectOpts *detect.DetectOptions + // UniverseDomain is the default service domain for a given Cloud universe. + // The default value is "googleapis.com". This is the universe domain + // configured for the client, which will be compared to the universe domain + // that is separately configured for the credentials. + UniverseDomain string + // Logger is used for debug logging. If provided, logging will be enabled + // at the loggers configured level. By default logging is disabled unless + // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default + // logger will be used. Optional. + Logger *slog.Logger + + // InternalOptions are NOT meant to be set directly by consumers of this + // package, they should only be set by generated client code. + InternalOptions *InternalOptions +} + +func (o *Options) validate() error { + if o == nil { + return errors.New("httptransport: opts required to be non-nil") + } + if o.InternalOptions != nil && o.InternalOptions.SkipValidation { + return nil + } + hasCreds := o.APIKey != "" || + o.Credentials != nil || + (o.DetectOpts != nil && len(o.DetectOpts.CredentialsJSON) > 0) || + (o.DetectOpts != nil && o.DetectOpts.CredentialsFile != "") + if o.DisableAuthentication && hasCreds { + return errors.New("httptransport: DisableAuthentication is incompatible with options that set or detect credentials") + } + return nil +} + +// client returns the client a user set for the detect options or nil if one was +// not set. +func (o *Options) client() *http.Client { + if o.DetectOpts != nil && o.DetectOpts.Client != nil { + return o.DetectOpts.Client + } + return nil +} + +func (o *Options) logger() *slog.Logger { + return internallog.New(o.Logger) +} + +func (o *Options) resolveDetectOptions() *detect.DetectOptions { + io := o.InternalOptions + // soft-clone these so we are not updating a ref the user holds and may reuse + do := transport.CloneDetectOptions(o.DetectOpts) + + // If scoped JWTs are enabled user provided an aud, allow self-signed JWT. + if (io != nil && io.EnableJWTWithScope) || do.Audience != "" { + do.UseSelfSignedJWT = true + } + // Only default scopes if user did not also set an audience. + if len(do.Scopes) == 0 && do.Audience == "" && io != nil && len(io.DefaultScopes) > 0 { + do.Scopes = make([]string, len(io.DefaultScopes)) + copy(do.Scopes, io.DefaultScopes) + } + if len(do.Scopes) == 0 && do.Audience == "" && io != nil { + do.Audience = o.InternalOptions.DefaultAudience + } + if o.ClientCertProvider != nil { + tlsConfig := &tls.Config{ + GetClientCertificate: o.ClientCertProvider, + } + do.Client = transport.DefaultHTTPClientWithTLS(tlsConfig) + do.TokenURL = detect.GoogleMTLSTokenURL + } + if do.Logger == nil { + do.Logger = o.logger() + } + return do +} + +// InternalOptions are only meant to be set by generated client code. These are +// not meant to be set directly by consumers of this package. Configuration in +// this type is considered EXPERIMENTAL and may be removed at any time in the +// future without warning. +type InternalOptions struct { + // EnableJWTWithScope specifies if scope can be used with self-signed JWT. + EnableJWTWithScope bool + // DefaultAudience specifies a default audience to be used as the audience + // field ("aud") for the JWT token authentication. + DefaultAudience string + // DefaultEndpointTemplate combined with UniverseDomain specifies the + // default endpoint. + DefaultEndpointTemplate string + // DefaultMTLSEndpoint specifies the default mTLS endpoint. + DefaultMTLSEndpoint string + // DefaultScopes specifies the default OAuth2 scopes to be used for a + // service. + DefaultScopes []string + // SkipValidation bypasses validation on Options. It should only be used + // internally for clients that need more control over their transport. + SkipValidation bool + // SkipUniverseDomainValidation skips the verification that the universe + // domain configured for the client matches the universe domain configured + // for the credentials. It should only be used internally for clients that + // need more control over their transport. The default is false. + SkipUniverseDomainValidation bool + // TelemetryAttributes specifies a map of telemetry attributes to be added + // to all OpenTelemetry signals, such as tracing and metrics, for purposes + // including representing the static identity of the client (e.g., service + // name, version). These attributes are expected to be consistent across all + // signals to enable cross-signal correlation. + // + // It should only be used internally by generated clients. Callers should not + // modify the map after it is passed in. + TelemetryAttributes map[string]string +} + +// AddAuthorizationMiddleware adds a middleware to the provided client's +// transport that sets the Authorization header with the value produced by the +// provided [cloud.google.com/go/auth.Credentials]. An error is returned only +// if client or creds is nil. +// +// This function does not support setting a universe domain value on the client. +func AddAuthorizationMiddleware(client *http.Client, creds *auth.Credentials) error { + if client == nil || creds == nil { + return fmt.Errorf("httptransport: client and tp must not be nil") + } + base := client.Transport + if base == nil { + if dt, ok := http.DefaultTransport.(*http.Transport); ok { + base = dt.Clone() + } else { + // Directly reuse the DefaultTransport if the application has + // replaced it with an implementation of RoundTripper other than + // http.Transport. + base = http.DefaultTransport + } + } + client.Transport = &authTransport{ + creds: creds, + base: base, + } + return nil +} + +// NewClient returns a [net/http.Client] that can be used to communicate with a +// Google cloud service, configured with the provided [Options]. It +// automatically appends Authorization headers to all outgoing requests. +func NewClient(opts *Options) (*http.Client, error) { + if err := opts.validate(); err != nil { + return nil, err + } + + tOpts := &transport.Options{ + Endpoint: opts.Endpoint, + ClientCertProvider: opts.ClientCertProvider, + Client: opts.client(), + UniverseDomain: opts.UniverseDomain, + Logger: opts.logger(), + } + if io := opts.InternalOptions; io != nil { + tOpts.DefaultEndpointTemplate = io.DefaultEndpointTemplate + tOpts.DefaultMTLSEndpoint = io.DefaultMTLSEndpoint + } + clientCertProvider, dialTLSContext, err := transport.GetHTTPTransportConfig(tOpts) + if err != nil { + return nil, err + } + baseRoundTripper := opts.BaseRoundTripper + if baseRoundTripper == nil { + baseRoundTripper = defaultBaseTransport(clientCertProvider, dialTLSContext) + } + // Ensure the token exchange transport uses the same ClientCertProvider as the API transport. + opts.ClientCertProvider = clientCertProvider + trans, err := newTransport(baseRoundTripper, opts) + if err != nil { + return nil, err + } + return &http.Client{ + Transport: trans, + }, nil +} + +// SetAuthHeader uses the provided token to set the Authorization and trust +// boundary headers on an http.Request. If the token.Type is empty, the type is +// assumed to be Bearer. This is the recommended way to set authorization +// headers on a custom http.Request. +func SetAuthHeader(token *auth.Token, req *http.Request) { + headers.SetAuthHeader(token, req) +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/httptransport/transport.go b/plugins/traefik/vendor/cloud.google.com/go/auth/httptransport/transport.go new file mode 100644 index 000000000..3feb997c7 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/httptransport/transport.go @@ -0,0 +1,235 @@ +// Copyright 2023 Google LLC +// +// 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 httptransport + +import ( + "context" + "crypto/tls" + "net" + "net/http" + "os" + "time" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/credentials" + "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/transport" + "cloud.google.com/go/auth/internal/transport/cert" + "cloud.google.com/go/auth/internal/transport/headers" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + "golang.org/x/net/http2" +) + +const ( + quotaProjectHeaderKey = "X-goog-user-project" +) + +func newTransport(base http.RoundTripper, opts *Options) (http.RoundTripper, error) { + var headers = opts.Headers + ht := &headerTransport{ + base: base, + headers: headers, + } + var trans http.RoundTripper = ht + trans = addOpenTelemetryTransport(trans, opts) + switch { + case opts.DisableAuthentication: + // Do nothing. + case opts.APIKey != "": + qp := internal.GetQuotaProject(nil, opts.Headers.Get(quotaProjectHeaderKey)) + if qp != "" { + if headers == nil { + headers = make(map[string][]string, 1) + } + headers.Set(quotaProjectHeaderKey, qp) + } + trans = &apiKeyTransport{ + Transport: trans, + Key: opts.APIKey, + } + default: + var creds *auth.Credentials + if opts.Credentials != nil { + creds = opts.Credentials + } else { + var err error + creds, err = credentials.DetectDefault(opts.resolveDetectOptions()) + if err != nil { + return nil, err + } + } + qp, err := creds.QuotaProjectID(context.Background()) + if err != nil { + return nil, err + } + if qp != "" { + if headers == nil { + headers = make(map[string][]string, 1) + } + // Don't overwrite user specified quota + if v := headers.Get(quotaProjectHeaderKey); v == "" { + headers.Set(quotaProjectHeaderKey, qp) + } + } + var skipUD bool + if iOpts := opts.InternalOptions; iOpts != nil { + skipUD = iOpts.SkipUniverseDomainValidation + } + creds.TokenProvider = auth.NewCachedTokenProvider(creds.TokenProvider, nil) + trans = &authTransport{ + base: trans, + creds: creds, + clientUniverseDomain: opts.UniverseDomain, + skipUniverseDomainValidation: skipUD, + } + } + return trans, nil +} + +// defaultBaseTransport returns the base HTTP transport. +// On App Engine, this is urlfetch.Transport. +// Otherwise, use a default transport, taking most defaults from +// http.DefaultTransport. +// If TLSCertificate is available, set TLSClientConfig as well. +func defaultBaseTransport(clientCertSource cert.Provider, dialTLSContext func(context.Context, string, string) (net.Conn, error)) http.RoundTripper { + defaultTransport, ok := http.DefaultTransport.(*http.Transport) + if !ok { + defaultTransport = transport.BaseTransport() + } + trans := defaultTransport.Clone() + trans.MaxIdleConnsPerHost = 100 + + if clientCertSource != nil { + trans.TLSClientConfig = &tls.Config{ + GetClientCertificate: clientCertSource, + } + } + if dialTLSContext != nil { + // If DialTLSContext is set, TLSClientConfig wil be ignored + trans.DialTLSContext = dialTLSContext + } + + // Configures the ReadIdleTimeout HTTP/2 option for the + // transport. This allows broken idle connections to be pruned more quickly, + // preventing the client from attempting to re-use connections that will no + // longer work. + http2Trans, err := http2.ConfigureTransports(trans) + if err == nil { + http2Trans.ReadIdleTimeout = time.Second * 31 + } + + return trans +} + +type apiKeyTransport struct { + // Key is the API Key to set on requests. + Key string + // Transport is the underlying HTTP transport. + // If nil, http.DefaultTransport is used. + Transport http.RoundTripper +} + +func (t *apiKeyTransport) RoundTrip(req *http.Request) (*http.Response, error) { + newReq := *req + args := newReq.URL.Query() + args.Set("key", t.Key) + newReq.URL.RawQuery = args.Encode() + return t.Transport.RoundTrip(&newReq) +} + +type headerTransport struct { + headers http.Header + base http.RoundTripper +} + +func (t *headerTransport) RoundTrip(req *http.Request) (*http.Response, error) { + rt := t.base + newReq := *req + newReq.Header = make(http.Header) + for k, vv := range req.Header { + newReq.Header[k] = vv + } + + for k, v := range t.headers { + newReq.Header[k] = v + } + + return rt.RoundTrip(&newReq) +} + +func addOpenTelemetryTransport(trans http.RoundTripper, opts *Options) http.RoundTripper { + if opts.DisableTelemetry { + return trans + } + return otelhttp.NewTransport(trans) +} + +type authTransport struct { + creds *auth.Credentials + base http.RoundTripper + clientUniverseDomain string + skipUniverseDomainValidation bool +} + +// getClientUniverseDomain returns the default service domain for a given Cloud +// universe, with the following precedence: +// +// 1. A non-empty option.WithUniverseDomain or similar client option. +// 2. A non-empty environment variable GOOGLE_CLOUD_UNIVERSE_DOMAIN. +// 3. The default value "googleapis.com". +// +// This is the universe domain configured for the client, which will be compared +// to the universe domain that is separately configured for the credentials. +func (t *authTransport) getClientUniverseDomain() string { + if t.clientUniverseDomain != "" { + return t.clientUniverseDomain + } + if envUD := os.Getenv(internal.UniverseDomainEnvVar); envUD != "" { + return envUD + } + return internal.DefaultUniverseDomain +} + +// RoundTrip authorizes and authenticates the request with an +// access token from Transport's Source. Per the RoundTripper contract we must +// not modify the initial request, so we clone it, and we must close the body +// on any errors that happens during our token logic. +func (t *authTransport) RoundTrip(req *http.Request) (*http.Response, error) { + reqBodyClosed := false + if req.Body != nil { + defer func() { + if !reqBodyClosed { + req.Body.Close() + } + }() + } + token, err := t.creds.Token(req.Context()) + if err != nil { + return nil, err + } + if !t.skipUniverseDomainValidation && token.MetadataString("auth.google.tokenSource") != "compute-metadata" { + credentialsUniverseDomain, err := t.creds.UniverseDomain(req.Context()) + if err != nil { + return nil, err + } + if err := transport.ValidateUniverseDomain(t.getClientUniverseDomain(), credentialsUniverseDomain); err != nil { + return nil, err + } + } + req2 := req.Clone(req.Context()) + headers.SetAuthHeader(token, req2) + reqBodyClosed = true + return t.base.RoundTrip(req2) +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/credsfile/credsfile.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/credsfile/credsfile.go new file mode 100644 index 000000000..84aab8472 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/credsfile/credsfile.go @@ -0,0 +1,63 @@ +// Copyright 2023 Google LLC +// +// 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 credsfile is meant to hide implementation details from the pubic +// surface of the detect package. It should not import any other packages in +// this module. It is located under the main internal package so other +// sub-packages can use these parsed types as well. +package credsfile + +import ( + "os" + "os/user" + "path/filepath" + "runtime" +) + +const ( + // GoogleAppCredsEnvVar is the environment variable for setting the + // application default credentials. + GoogleAppCredsEnvVar = "GOOGLE_APPLICATION_CREDENTIALS" + userCredsFilename = "application_default_credentials.json" +) + +// GetFileNameFromEnv returns the override if provided or detects a filename +// from the environment. +func GetFileNameFromEnv(override string) string { + if override != "" { + return override + } + return os.Getenv(GoogleAppCredsEnvVar) +} + +// GetWellKnownFileName tries to locate the filepath for the user credential +// file based on the environment. +func GetWellKnownFileName() string { + if runtime.GOOS == "windows" { + return filepath.Join(os.Getenv("APPDATA"), "gcloud", userCredsFilename) + } + return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", userCredsFilename) +} + +// guessUnixHomeDir default to checking for HOME, but not all unix systems have +// this set, do have a fallback. +func guessUnixHomeDir() string { + if v := os.Getenv("HOME"); v != "" { + return v + } + if u, err := user.Current(); err == nil { + return u.HomeDir + } + return "" +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/credsfile/filetype.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/credsfile/filetype.go new file mode 100644 index 000000000..cbba2eb97 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/credsfile/filetype.go @@ -0,0 +1,159 @@ +// Copyright 2023 Google LLC +// +// 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 credsfile + +import ( + "encoding/json" +) + +// Config3LO is the internals of a client creds file. +type Config3LO struct { + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + RedirectURIs []string `json:"redirect_uris"` + AuthURI string `json:"auth_uri"` + TokenURI string `json:"token_uri"` +} + +// ClientCredentialsFile representation. +type ClientCredentialsFile struct { + Web *Config3LO `json:"web"` + Installed *Config3LO `json:"installed"` + UniverseDomain string `json:"universe_domain"` +} + +// ServiceAccountFile representation. +type ServiceAccountFile struct { + Type string `json:"type"` + ProjectID string `json:"project_id"` + PrivateKeyID string `json:"private_key_id"` + PrivateKey string `json:"private_key"` + ClientEmail string `json:"client_email"` + ClientID string `json:"client_id"` + AuthURL string `json:"auth_uri"` + TokenURL string `json:"token_uri"` + UniverseDomain string `json:"universe_domain"` +} + +// UserCredentialsFile representation. +type UserCredentialsFile struct { + Type string `json:"type"` + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + QuotaProjectID string `json:"quota_project_id"` + RefreshToken string `json:"refresh_token"` + UniverseDomain string `json:"universe_domain"` +} + +// ExternalAccountFile representation. +type ExternalAccountFile struct { + Type string `json:"type"` + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + Audience string `json:"audience"` + SubjectTokenType string `json:"subject_token_type"` + ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"` + TokenURL string `json:"token_url"` + CredentialSource *CredentialSource `json:"credential_source,omitempty"` + TokenInfoURL string `json:"token_info_url"` + ServiceAccountImpersonation *ServiceAccountImpersonationInfo `json:"service_account_impersonation,omitempty"` + QuotaProjectID string `json:"quota_project_id"` + WorkforcePoolUserProject string `json:"workforce_pool_user_project"` + UniverseDomain string `json:"universe_domain"` +} + +// ExternalAccountAuthorizedUserFile representation. +type ExternalAccountAuthorizedUserFile struct { + Type string `json:"type"` + Audience string `json:"audience"` + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + RefreshToken string `json:"refresh_token"` + TokenURL string `json:"token_url"` + TokenInfoURL string `json:"token_info_url"` + RevokeURL string `json:"revoke_url"` + QuotaProjectID string `json:"quota_project_id"` + UniverseDomain string `json:"universe_domain"` +} + +// CredentialSource stores the information necessary to retrieve the credentials for the STS exchange. +// +// One field amongst File, URL, Certificate, and Executable should be filled, depending on the kind of credential in question. +// The EnvironmentID should start with AWS if being used for an AWS credential. +type CredentialSource struct { + File string `json:"file"` + URL string `json:"url"` + Headers map[string]string `json:"headers"` + Executable *ExecutableConfig `json:"executable,omitempty"` + Certificate *CertificateConfig `json:"certificate"` + EnvironmentID string `json:"environment_id"` // TODO: Make type for this + RegionURL string `json:"region_url"` + RegionalCredVerificationURL string `json:"regional_cred_verification_url"` + CredVerificationURL string `json:"cred_verification_url"` + IMDSv2SessionTokenURL string `json:"imdsv2_session_token_url"` + Format *Format `json:"format,omitempty"` +} + +// Format describes the format of a [CredentialSource]. +type Format struct { + // Type is either "text" or "json". When not provided "text" type is assumed. + Type string `json:"type"` + // SubjectTokenFieldName is only required for JSON format. This would be "access_token" for azure. + SubjectTokenFieldName string `json:"subject_token_field_name"` +} + +// ExecutableConfig represents the command to run for an executable +// [CredentialSource]. +type ExecutableConfig struct { + Command string `json:"command"` + TimeoutMillis int `json:"timeout_millis"` + OutputFile string `json:"output_file"` +} + +// CertificateConfig represents the options used to set up X509 based workload +// [CredentialSource] +type CertificateConfig struct { + UseDefaultCertificateConfig bool `json:"use_default_certificate_config"` + CertificateConfigLocation string `json:"certificate_config_location"` + TrustChainPath string `json:"trust_chain_path"` +} + +// ServiceAccountImpersonationInfo has impersonation configuration. +type ServiceAccountImpersonationInfo struct { + TokenLifetimeSeconds int `json:"token_lifetime_seconds"` +} + +// ImpersonatedServiceAccountFile representation. +type ImpersonatedServiceAccountFile struct { + Type string `json:"type"` + ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"` + Delegates []string `json:"delegates"` + Scopes []string `json:"scopes"` + CredSource json.RawMessage `json:"source_credentials"` + UniverseDomain string `json:"universe_domain"` +} + +// GDCHServiceAccountFile represents the Google Distributed Cloud Hosted (GDCH) service identity file. +type GDCHServiceAccountFile struct { + Type string `json:"type"` + FormatVersion string `json:"format_version"` + Project string `json:"project"` + Name string `json:"name"` + CertPath string `json:"ca_cert_path"` + PrivateKeyID string `json:"private_key_id"` + PrivateKey string `json:"private_key"` + TokenURL string `json:"token_uri"` + UniverseDomain string `json:"universe_domain"` +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/credsfile/parse.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/credsfile/parse.go new file mode 100644 index 000000000..f2cedb731 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/credsfile/parse.go @@ -0,0 +1,99 @@ +// Copyright 2023 Google LLC +// +// 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 credsfile + +import ( + "encoding/json" +) + +// ParseServiceAccount parses bytes into a [ServiceAccountFile]. +func ParseServiceAccount(b []byte) (*ServiceAccountFile, error) { + var f *ServiceAccountFile + if err := json.Unmarshal(b, &f); err != nil { + return nil, err + } + return f, nil +} + +// ParseClientCredentials parses bytes into a +// [credsfile.ClientCredentialsFile]. +func ParseClientCredentials(b []byte) (*ClientCredentialsFile, error) { + var f *ClientCredentialsFile + if err := json.Unmarshal(b, &f); err != nil { + return nil, err + } + return f, nil +} + +// ParseUserCredentials parses bytes into a [UserCredentialsFile]. +func ParseUserCredentials(b []byte) (*UserCredentialsFile, error) { + var f *UserCredentialsFile + if err := json.Unmarshal(b, &f); err != nil { + return nil, err + } + return f, nil +} + +// ParseExternalAccount parses bytes into a [ExternalAccountFile]. +func ParseExternalAccount(b []byte) (*ExternalAccountFile, error) { + var f *ExternalAccountFile + if err := json.Unmarshal(b, &f); err != nil { + return nil, err + } + return f, nil +} + +// ParseExternalAccountAuthorizedUser parses bytes into a +// [ExternalAccountAuthorizedUserFile]. +func ParseExternalAccountAuthorizedUser(b []byte) (*ExternalAccountAuthorizedUserFile, error) { + var f *ExternalAccountAuthorizedUserFile + if err := json.Unmarshal(b, &f); err != nil { + return nil, err + } + return f, nil +} + +// ParseImpersonatedServiceAccount parses bytes into a +// [ImpersonatedServiceAccountFile]. +func ParseImpersonatedServiceAccount(b []byte) (*ImpersonatedServiceAccountFile, error) { + var f *ImpersonatedServiceAccountFile + if err := json.Unmarshal(b, &f); err != nil { + return nil, err + } + return f, nil +} + +// ParseGDCHServiceAccount parses bytes into a [GDCHServiceAccountFile]. +func ParseGDCHServiceAccount(b []byte) (*GDCHServiceAccountFile, error) { + var f *GDCHServiceAccountFile + if err := json.Unmarshal(b, &f); err != nil { + return nil, err + } + return f, nil +} + +type fileTypeChecker struct { + Type string `json:"type"` +} + +// ParseFileType determines the [CredentialType] based on bytes provided. +// Only returns error for json.Unmarshal. +func ParseFileType(b []byte) (string, error) { + var f fileTypeChecker + if err := json.Unmarshal(b, &f); err != nil { + return "", err + } + return f.Type, nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/internal.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/internal.go new file mode 100644 index 000000000..48e9bd9ec --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/internal.go @@ -0,0 +1,285 @@ +// Copyright 2023 Google LLC +// +// 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 internal + +import ( + "context" + "crypto" + "crypto/x509" + "encoding/json" + "encoding/pem" + "errors" + "fmt" + "io" + "net/http" + "os" + "sync" + "time" + + "cloud.google.com/go/compute/metadata" +) + +const ( + // TokenTypeBearer is the auth header prefix for bearer tokens. + TokenTypeBearer = "Bearer" + + // QuotaProjectEnvVar is the environment variable for setting the quota + // project. + QuotaProjectEnvVar = "GOOGLE_CLOUD_QUOTA_PROJECT" + // UniverseDomainEnvVar is the environment variable for setting the default + // service domain for a given Cloud universe. + UniverseDomainEnvVar = "GOOGLE_CLOUD_UNIVERSE_DOMAIN" + projectEnvVar = "GOOGLE_CLOUD_PROJECT" + maxBodySize = 1 << 20 + + // DefaultUniverseDomain is the default value for universe domain. + // Universe domain is the default service domain for a given Cloud universe. + DefaultUniverseDomain = "googleapis.com" + + // TrustBoundaryNoOp is a constant indicating no trust boundary is enforced. + TrustBoundaryNoOp = "0x0" + + // TrustBoundaryDataKey is the key used to store trust boundary data in a token's metadata. + TrustBoundaryDataKey = "google.auth.trust_boundary_data" +) + +type clonableTransport interface { + Clone() *http.Transport +} + +// DefaultClient returns an [http.Client] with some defaults set. If +// the current [http.DefaultTransport] is a [clonableTransport], as +// is the case for an [*http.Transport], the clone will be used. +// Otherwise the [http.DefaultTransport] is used directly. +func DefaultClient() *http.Client { + if transport, ok := http.DefaultTransport.(clonableTransport); ok { + return &http.Client{ + Transport: transport.Clone(), + Timeout: 30 * time.Second, + } + } + + return &http.Client{ + Transport: http.DefaultTransport, + Timeout: 30 * time.Second, + } +} + +// ParseKey converts the binary contents of a private key file +// to an crypto.Signer. It detects whether the private key is in a +// PEM container or not. If so, it extracts the the private key +// from PEM container before conversion. It only supports PEM +// containers with no passphrase. +func ParseKey(key []byte) (crypto.Signer, error) { + block, _ := pem.Decode(key) + if block != nil { + key = block.Bytes + } + var parsedKey crypto.PrivateKey + + var errPKCS8, errPKCS1, errEC error + if parsedKey, errPKCS8 = x509.ParsePKCS8PrivateKey(key); errPKCS8 != nil { + if parsedKey, errPKCS1 = x509.ParsePKCS1PrivateKey(key); errPKCS1 != nil { + if parsedKey, errEC = x509.ParseECPrivateKey(key); errEC != nil { + return nil, fmt.Errorf("failed to parse private key. Tried PKCS8, PKCS1, and EC formats. Errors: [PKCS8: %v], [PKCS1: %v], [EC: %v]", errPKCS8, errPKCS1, errEC) + } + } + } + parsed, ok := parsedKey.(crypto.Signer) + if !ok { + return nil, errors.New("private key is not a signer") + } + return parsed, nil +} + +// GetQuotaProject retrieves quota project with precedence being: override, +// environment variable, creds json file. +func GetQuotaProject(b []byte, override string) string { + if override != "" { + return override + } + if env := os.Getenv(QuotaProjectEnvVar); env != "" { + return env + } + if b == nil { + return "" + } + var v struct { + QuotaProject string `json:"quota_project_id"` + } + if err := json.Unmarshal(b, &v); err != nil { + return "" + } + return v.QuotaProject +} + +// GetProjectID retrieves project with precedence being: override, +// environment variable, creds json file. +func GetProjectID(b []byte, override string) string { + if override != "" { + return override + } + if env := os.Getenv(projectEnvVar); env != "" { + return env + } + if b == nil { + return "" + } + var v struct { + ProjectID string `json:"project_id"` // standard service account key + Project string `json:"project"` // gdch key + } + if err := json.Unmarshal(b, &v); err != nil { + return "" + } + if v.ProjectID != "" { + return v.ProjectID + } + return v.Project +} + +// DoRequest executes the provided req with the client. It reads the response +// body, closes it, and returns it. +func DoRequest(client *http.Client, req *http.Request) (*http.Response, []byte, error) { + resp, err := client.Do(req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := ReadAll(io.LimitReader(resp.Body, maxBodySize)) + if err != nil { + return nil, nil, err + } + return resp, body, nil +} + +// ReadAll consumes the whole reader and safely reads the content of its body +// with some overflow protection. +func ReadAll(r io.Reader) ([]byte, error) { + return io.ReadAll(io.LimitReader(r, maxBodySize)) +} + +// StaticCredentialsProperty is a helper for creating static credentials +// properties. +func StaticCredentialsProperty(s string) StaticProperty { + return StaticProperty(s) +} + +// StaticProperty always returns that value of the underlying string. +type StaticProperty string + +// GetProperty loads the properly value provided the given context. +func (p StaticProperty) GetProperty(context.Context) (string, error) { + return string(p), nil +} + +// ComputeUniverseDomainProvider fetches the credentials universe domain from +// the google cloud metadata service. +type ComputeUniverseDomainProvider struct { + MetadataClient *metadata.Client + universeDomainOnce sync.Once + universeDomain string + universeDomainErr error +} + +// GetProperty fetches the credentials universe domain from the google cloud +// metadata service. +func (c *ComputeUniverseDomainProvider) GetProperty(ctx context.Context) (string, error) { + c.universeDomainOnce.Do(func() { + c.universeDomain, c.universeDomainErr = getMetadataUniverseDomain(ctx, c.MetadataClient) + }) + if c.universeDomainErr != nil { + return "", c.universeDomainErr + } + return c.universeDomain, nil +} + +// httpGetMetadataUniverseDomain is a package var for unit test substitution. +var httpGetMetadataUniverseDomain = func(ctx context.Context, client *metadata.Client) (string, error) { + ctx, cancel := context.WithTimeout(ctx, 1*time.Second) + defer cancel() + return client.GetWithContext(ctx, "universe/universe-domain") +} + +func getMetadataUniverseDomain(ctx context.Context, client *metadata.Client) (string, error) { + universeDomain, err := httpGetMetadataUniverseDomain(ctx, client) + if err == nil { + return universeDomain, nil + } + if _, ok := err.(metadata.NotDefinedError); ok { + // http.StatusNotFound (404) + return DefaultUniverseDomain, nil + } + return "", err +} + +// FormatIAMServiceAccountResource sets a service account name in an IAM resource +// name. +func FormatIAMServiceAccountResource(name string) string { + return fmt.Sprintf("projects/-/serviceAccounts/%s", name) +} + +// TrustBoundaryData represents the trust boundary data associated with a token. +// It contains information about the regions or environments where the token is valid. +type TrustBoundaryData struct { + // Locations is the list of locations that the token is allowed to be used in. + Locations []string + // EncodedLocations represents the locations in an encoded format. + EncodedLocations string +} + +// NewTrustBoundaryData returns a new TrustBoundaryData with the specified locations and encoded locations. +func NewTrustBoundaryData(locations []string, encodedLocations string) *TrustBoundaryData { + // Ensure consistency by treating a nil slice as an empty slice. + if locations == nil { + locations = []string{} + } + locationsCopy := make([]string, len(locations)) + copy(locationsCopy, locations) + return &TrustBoundaryData{ + Locations: locationsCopy, + EncodedLocations: encodedLocations, + } +} + +// NewNoOpTrustBoundaryData returns a new TrustBoundaryData with no restrictions. +func NewNoOpTrustBoundaryData() *TrustBoundaryData { + return &TrustBoundaryData{ + Locations: []string{}, + EncodedLocations: TrustBoundaryNoOp, + } +} + +// TrustBoundaryHeader returns the value for the x-allowed-locations header and a bool +// indicating if the header should be set. The return values are structured to +// handle three distinct states required by the backend: +// 1. Header not set: (value="", present=false) -> data is empty. +// 2. Header set to an empty string: (value="", present=true) -> data is a no-op. +// 3. Header set to a value: (value="...", present=true) -> data has locations. +func (t TrustBoundaryData) TrustBoundaryHeader() (value string, present bool) { + if t.EncodedLocations == "" { + // If the data is empty, the header should not be present. + return "", false + } + + // If data is not empty, the header should always be present. + present = true + value = "" + if t.EncodedLocations != TrustBoundaryNoOp { + value = t.EncodedLocations + } + // For a no-op, the backend requires an empty string. + return value, present +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/jwt/jwt.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/jwt/jwt.go new file mode 100644 index 000000000..027c0dae0 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/jwt/jwt.go @@ -0,0 +1,208 @@ +// Copyright 2023 Google LLC +// +// 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 jwt + +import ( + "bytes" + "crypto" + "crypto/ecdsa" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "encoding/asn1" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "math/big" + "strings" + "time" +) + +const ( + // HeaderAlgRSA256 is the RS256 [Header.Algorithm]. + HeaderAlgRSA256 = "RS256" + // HeaderAlgES256 is the ES256 [Header.Algorithm]. + HeaderAlgES256 = "ES256" + // HeaderType is the standard [Header.Type]. + HeaderType = "JWT" + // ES256 key size + es256KeySize = 32 +) + +// Header represents a JWT header. +type Header struct { + Algorithm string `json:"alg"` + Type string `json:"typ"` + KeyID string `json:"kid"` +} + +func (h *Header) encode() (string, error) { + b, err := json.Marshal(h) + if err != nil { + return "", err + } + return base64.RawURLEncoding.EncodeToString(b), nil +} + +// Claims represents the claims set of a JWT. +type Claims struct { + // Iss is the issuer JWT claim. + Iss string `json:"iss"` + // Scope is the scope JWT claim. + Scope string `json:"scope,omitempty"` + // Exp is the expiry JWT claim. If unset, default is in one hour from now. + Exp int64 `json:"exp"` + // Iat is the subject issued at claim. If unset, default is now. + Iat int64 `json:"iat"` + // Aud is the audience JWT claim. Optional. + Aud string `json:"aud"` + // Sub is the subject JWT claim. Optional. + Sub string `json:"sub,omitempty"` + // AdditionalClaims contains any additional non-standard JWT claims. Optional. + AdditionalClaims map[string]interface{} `json:"-"` +} + +func (c *Claims) encode() (string, error) { + // Compensate for skew + now := time.Now().Add(-10 * time.Second) + if c.Iat == 0 { + c.Iat = now.Unix() + } + if c.Exp == 0 { + c.Exp = now.Add(time.Hour).Unix() + } + if c.Exp < c.Iat { + return "", fmt.Errorf("jwt: invalid Exp = %d; must be later than Iat = %d", c.Exp, c.Iat) + } + + b, err := json.Marshal(c) + if err != nil { + return "", err + } + + if len(c.AdditionalClaims) == 0 { + return base64.RawURLEncoding.EncodeToString(b), nil + } + + // Marshal private claim set and then append it to b. + prv, err := json.Marshal(c.AdditionalClaims) + if err != nil { + return "", fmt.Errorf("invalid map of additional claims %v: %w", c.AdditionalClaims, err) + } + + // Concatenate public and private claim JSON objects. + if !bytes.HasSuffix(b, []byte{'}'}) { + return "", fmt.Errorf("invalid JSON %s", b) + } + if !bytes.HasPrefix(prv, []byte{'{'}) { + return "", fmt.Errorf("invalid JSON %s", prv) + } + b[len(b)-1] = ',' // Replace closing curly brace with a comma. + b = append(b, prv[1:]...) // Append private claims. + return base64.RawURLEncoding.EncodeToString(b), nil +} + +// EncodeJWS encodes the data using the provided key as a JSON web signature. +func EncodeJWS(header *Header, c *Claims, signer crypto.Signer) (string, error) { + head, err := header.encode() + if err != nil { + return "", err + } + claims, err := c.encode() + if err != nil { + return "", err + } + ss := fmt.Sprintf("%s.%s", head, claims) + h := sha256.New() + h.Write([]byte(ss)) + sig, err := signer.Sign(rand.Reader, h.Sum(nil), crypto.SHA256) + if err != nil { + return "", err + } + + if header.Algorithm == HeaderAlgES256 { + var ecSig struct { + R, S *big.Int + } + if _, err := asn1.Unmarshal(sig, &ecSig); err != nil { + return "", err + } + + rawSig := make([]byte, es256KeySize*2) + + ecSig.R.FillBytes(rawSig[:es256KeySize]) + ecSig.S.FillBytes(rawSig[es256KeySize:]) + + sig = rawSig + } + return fmt.Sprintf("%s.%s", ss, base64.RawURLEncoding.EncodeToString(sig)), nil +} + +// DecodeJWS decodes a claim set from a JWS payload. +func DecodeJWS(payload string) (*Claims, error) { + // decode returned id token to get expiry + s := strings.Split(payload, ".") + if len(s) < 2 { + return nil, errors.New("invalid token received") + } + decoded, err := base64.RawURLEncoding.DecodeString(s[1]) + if err != nil { + return nil, err + } + c := &Claims{} + if err := json.NewDecoder(bytes.NewBuffer(decoded)).Decode(c); err != nil { + return nil, err + } + if err := json.NewDecoder(bytes.NewBuffer(decoded)).Decode(&c.AdditionalClaims); err != nil { + return nil, err + } + return c, err +} + +// VerifyJWS tests whether the provided JWT token's signature was produced by +// the private key associated with the provided public key. +func VerifyJWS(token string, key crypto.PublicKey) error { + parts := strings.Split(token, ".") + if len(parts) != 3 { + return errors.New("jwt: invalid token received, token must have 3 parts") + } + + signedContent := parts[0] + "." + parts[1] + signatureString, err := base64.RawURLEncoding.DecodeString(parts[2]) + if err != nil { + return err + } + + h := sha256.New() + h.Write([]byte(signedContent)) + hashed := h.Sum(nil) + + switch pub := key.(type) { + case *rsa.PublicKey: + return rsa.VerifyPKCS1v15(pub, crypto.SHA256, hashed, signatureString) + case *ecdsa.PublicKey: + if len(signatureString) != 2*32 { + return fmt.Errorf("jwt: ecdsa signature size should be 64 bytes, got %d", len(signatureString)) + } + r := new(big.Int).SetBytes(signatureString[:32]) + s := new(big.Int).SetBytes(signatureString[32:]) + if !ecdsa.Verify(pub, hashed, r, s) { + return errors.New("jwt: ecdsa signature verification failed") + } + return nil + } + return fmt.Errorf("jwt: unsupported public key type: %T", key) +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/retry/retry.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/retry/retry.go new file mode 100644 index 000000000..276cc4a3e --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/retry/retry.go @@ -0,0 +1,117 @@ +// Copyright 2025 Google LLC +// +// 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 retry + +import ( + "context" + "io" + "math/rand" + "net/http" + "time" +) + +const ( + maxRetryAttempts = 5 +) + +var ( + syscallRetryable = func(error) bool { return false } +) + +// defaultBackoff is basically equivalent to gax.Backoff without the need for +// the dependency. +type defaultBackoff struct { + max time.Duration + mul float64 + cur time.Duration +} + +func (b *defaultBackoff) Pause() time.Duration { + d := time.Duration(1 + rand.Int63n(int64(b.cur))) + b.cur = time.Duration(float64(b.cur) * b.mul) + if b.cur > b.max { + b.cur = b.max + } + return d +} + +// Sleep is the equivalent of gax.Sleep without the need for the dependency. +func Sleep(ctx context.Context, d time.Duration) error { + t := time.NewTimer(d) + select { + case <-ctx.Done(): + t.Stop() + return ctx.Err() + case <-t.C: + return nil + } +} + +// New returns a new Retryer with the default backoff strategy. +func New() *Retryer { + return &Retryer{bo: &defaultBackoff{ + cur: 100 * time.Millisecond, + max: 30 * time.Second, + mul: 2, + }} +} + +type backoff interface { + Pause() time.Duration +} + +// Retryer is a retryer for HTTP requests. +type Retryer struct { + bo backoff + attempts int +} + +// Retry determines if a request should be retried. +func (r *Retryer) Retry(status int, err error) (time.Duration, bool) { + if status == http.StatusOK { + return 0, false + } + retryOk := shouldRetry(status, err) + if !retryOk { + return 0, false + } + if r.attempts == maxRetryAttempts { + return 0, false + } + r.attempts++ + return r.bo.Pause(), true +} + +func shouldRetry(status int, err error) bool { + if 500 <= status && status <= 599 { + return true + } + if err == io.ErrUnexpectedEOF { + return true + } + // Transient network errors should be retried. + if syscallRetryable(err) { + return true + } + if err, ok := err.(interface{ Temporary() bool }); ok { + if err.Temporary() { + return true + } + } + if err, ok := err.(interface{ Unwrap() error }); ok { + return shouldRetry(status, err.Unwrap()) + } + return false +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cba.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cba.go new file mode 100644 index 000000000..14bca966e --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cba.go @@ -0,0 +1,361 @@ +// Copyright 2023 Google LLC +// +// 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 transport + +import ( + "context" + "crypto/tls" + "crypto/x509" + "errors" + "log" + "log/slog" + "net" + "net/http" + "net/url" + "os" + "strconv" + "strings" + + "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/transport/cert" + "github.com/google/s2a-go" + "google.golang.org/grpc/credentials" +) + +const ( + mTLSModeAlways = "always" + mTLSModeNever = "never" + mTLSModeAuto = "auto" + + // Experimental: if true, the code will try MTLS with S2A as the default for transport security. Default value is false. + googleAPIUseS2AEnv = "EXPERIMENTAL_GOOGLE_API_USE_S2A" + googleAPIUseCertSource = "GOOGLE_API_USE_CLIENT_CERTIFICATE" + googleAPIUseMTLS = "GOOGLE_API_USE_MTLS_ENDPOINT" + googleAPIUseMTLSOld = "GOOGLE_API_USE_MTLS" + + universeDomainPlaceholder = "UNIVERSE_DOMAIN" + + mtlsMDSRoot = "/run/google-mds-mtls/root.crt" + mtlsMDSKey = "/run/google-mds-mtls/client.key" +) + +// Type represents the type of transport used. +type Type int + +const ( + // TransportTypeUnknown represents an unknown transport type and is the default option. + TransportTypeUnknown Type = iota + // TransportTypeMTLSS2A represents the mTLS transport type using S2A. + TransportTypeMTLSS2A +) + +// Options is a struct that is duplicated information from the individual +// transport packages in order to avoid cyclic deps. It correlates 1:1 with +// fields on httptransport.Options and grpctransport.Options. +type Options struct { + Endpoint string + DefaultEndpointTemplate string + DefaultMTLSEndpoint string + ClientCertProvider cert.Provider + Client *http.Client + UniverseDomain string + EnableDirectPath bool + EnableDirectPathXds bool + Logger *slog.Logger +} + +// getUniverseDomain returns the default service domain for a given Cloud +// universe. +func (o *Options) getUniverseDomain() string { + if o.UniverseDomain == "" { + return internal.DefaultUniverseDomain + } + return o.UniverseDomain +} + +// isUniverseDomainGDU returns true if the universe domain is the default Google +// universe. +func (o *Options) isUniverseDomainGDU() bool { + return o.getUniverseDomain() == internal.DefaultUniverseDomain +} + +// defaultEndpoint returns the DefaultEndpointTemplate merged with the +// universe domain if the DefaultEndpointTemplate is set, otherwise returns an +// empty string. +func (o *Options) defaultEndpoint() string { + if o.DefaultEndpointTemplate == "" { + return "" + } + return strings.Replace(o.DefaultEndpointTemplate, universeDomainPlaceholder, o.getUniverseDomain(), 1) +} + +// defaultMTLSEndpoint returns the DefaultMTLSEndpointTemplate merged with the +// universe domain if the DefaultMTLSEndpointTemplate is set, otherwise returns an +// empty string. +func (o *Options) defaultMTLSEndpoint() string { + if o.DefaultMTLSEndpoint == "" { + return "" + } + return strings.Replace(o.DefaultMTLSEndpoint, universeDomainPlaceholder, o.getUniverseDomain(), 1) +} + +// mergedEndpoint merges a user-provided Endpoint of format host[:port] with the +// default endpoint. +func (o *Options) mergedEndpoint() (string, error) { + defaultEndpoint := o.defaultEndpoint() + u, err := url.Parse(fixScheme(defaultEndpoint)) + if err != nil { + return "", err + } + return strings.Replace(defaultEndpoint, u.Host, o.Endpoint, 1), nil +} + +func fixScheme(baseURL string) string { + if !strings.Contains(baseURL, "://") { + baseURL = "https://" + baseURL + } + return baseURL +} + +// GRPCTransportCredentials embeds interface TransportCredentials with additional data. +type GRPCTransportCredentials struct { + credentials.TransportCredentials + Endpoint string + TransportType Type +} + +// GetGRPCTransportCredsAndEndpoint returns an instance of +// [google.golang.org/grpc/credentials.TransportCredentials], and the +// corresponding endpoint and transport type to use for GRPC client. +func GetGRPCTransportCredsAndEndpoint(opts *Options) (*GRPCTransportCredentials, error) { + config, err := getTransportConfig(opts) + if err != nil { + return nil, err + } + + defaultTransportCreds := credentials.NewTLS(&tls.Config{ + GetClientCertificate: config.clientCertSource, + }) + + var s2aAddr string + var transportCredsForS2A credentials.TransportCredentials + + if config.mtlsS2AAddress != "" { + s2aAddr = config.mtlsS2AAddress + transportCredsForS2A, err = loadMTLSMDSTransportCreds(mtlsMDSRoot, mtlsMDSKey) + if err != nil { + log.Printf("Loading MTLS MDS credentials failed: %v", err) + if config.s2aAddress != "" { + s2aAddr = config.s2aAddress + } else { + return &GRPCTransportCredentials{defaultTransportCreds, config.endpoint, TransportTypeUnknown}, nil + } + } + } else if config.s2aAddress != "" { + s2aAddr = config.s2aAddress + } else { + return &GRPCTransportCredentials{defaultTransportCreds, config.endpoint, TransportTypeUnknown}, nil + } + + s2aTransportCreds, err := s2a.NewClientCreds(&s2a.ClientOptions{ + S2AAddress: s2aAddr, + TransportCreds: transportCredsForS2A, + }) + if err != nil { + // Use default if we cannot initialize S2A client transport credentials. + return &GRPCTransportCredentials{defaultTransportCreds, config.endpoint, TransportTypeUnknown}, nil + } + return &GRPCTransportCredentials{s2aTransportCreds, config.s2aMTLSEndpoint, TransportTypeMTLSS2A}, nil +} + +// GetHTTPTransportConfig returns a client certificate source and a function for +// dialing MTLS with S2A. +func GetHTTPTransportConfig(opts *Options) (cert.Provider, func(context.Context, string, string) (net.Conn, error), error) { + config, err := getTransportConfig(opts) + if err != nil { + return nil, nil, err + } + + var s2aAddr string + var transportCredsForS2A credentials.TransportCredentials + + if config.mtlsS2AAddress != "" { + s2aAddr = config.mtlsS2AAddress + transportCredsForS2A, err = loadMTLSMDSTransportCreds(mtlsMDSRoot, mtlsMDSKey) + if err != nil { + log.Printf("Loading MTLS MDS credentials failed: %v", err) + if config.s2aAddress != "" { + s2aAddr = config.s2aAddress + } else { + return config.clientCertSource, nil, nil + } + } + } else if config.s2aAddress != "" { + s2aAddr = config.s2aAddress + } else { + return config.clientCertSource, nil, nil + } + + dialTLSContextFunc := s2a.NewS2ADialTLSContextFunc(&s2a.ClientOptions{ + S2AAddress: s2aAddr, + TransportCreds: transportCredsForS2A, + }) + return nil, dialTLSContextFunc, nil +} + +func loadMTLSMDSTransportCreds(mtlsMDSRootFile, mtlsMDSKeyFile string) (credentials.TransportCredentials, error) { + rootPEM, err := os.ReadFile(mtlsMDSRootFile) + if err != nil { + return nil, err + } + caCertPool := x509.NewCertPool() + ok := caCertPool.AppendCertsFromPEM(rootPEM) + if !ok { + return nil, errors.New("failed to load MTLS MDS root certificate") + } + // The mTLS MDS credentials are formatted as the concatenation of a PEM-encoded certificate chain + // followed by a PEM-encoded private key. For this reason, the concatenation is passed in to the + // tls.X509KeyPair function as both the certificate chain and private key arguments. + cert, err := tls.LoadX509KeyPair(mtlsMDSKeyFile, mtlsMDSKeyFile) + if err != nil { + return nil, err + } + tlsConfig := tls.Config{ + RootCAs: caCertPool, + Certificates: []tls.Certificate{cert}, + MinVersion: tls.VersionTLS13, + } + return credentials.NewTLS(&tlsConfig), nil +} + +func getTransportConfig(opts *Options) (*transportConfig, error) { + clientCertSource, err := GetClientCertificateProvider(opts) + if err != nil { + return nil, err + } + endpoint, err := getEndpoint(opts, clientCertSource) + if err != nil { + return nil, err + } + defaultTransportConfig := transportConfig{ + clientCertSource: clientCertSource, + endpoint: endpoint, + } + + if !shouldUseS2A(clientCertSource, opts) { + return &defaultTransportConfig, nil + } + + s2aAddress := GetS2AAddress(opts.Logger) + mtlsS2AAddress := GetMTLSS2AAddress(opts.Logger) + if s2aAddress == "" && mtlsS2AAddress == "" { + return &defaultTransportConfig, nil + } + return &transportConfig{ + clientCertSource: clientCertSource, + endpoint: endpoint, + s2aAddress: s2aAddress, + mtlsS2AAddress: mtlsS2AAddress, + s2aMTLSEndpoint: opts.defaultMTLSEndpoint(), + }, nil +} + +// GetClientCertificateProvider returns a default client certificate source, if +// not provided by the user. +// +// A nil default source can be returned if the source does not exist. Any exceptions +// encountered while initializing the default source will be reported as client +// error (ex. corrupt metadata file). +func GetClientCertificateProvider(opts *Options) (cert.Provider, error) { + if !isClientCertificateEnabled(opts) { + return nil, nil + } else if opts.ClientCertProvider != nil { + return opts.ClientCertProvider, nil + } + return cert.DefaultProvider() + +} + +// isClientCertificateEnabled returns true by default for all GDU universe domain, unless explicitly overridden by env var +func isClientCertificateEnabled(opts *Options) bool { + if value, ok := os.LookupEnv(googleAPIUseCertSource); ok { + // error as false is OK + b, _ := strconv.ParseBool(value) + return b + } + return opts.isUniverseDomainGDU() +} + +type transportConfig struct { + // The client certificate source. + clientCertSource cert.Provider + // The corresponding endpoint to use based on client certificate source. + endpoint string + // The plaintext S2A address if it can be used, otherwise an empty string. + s2aAddress string + // The MTLS S2A address if it can be used, otherwise an empty string. + mtlsS2AAddress string + // The MTLS endpoint to use with S2A. + s2aMTLSEndpoint string +} + +// getEndpoint returns the endpoint for the service, taking into account the +// user-provided endpoint override "settings.Endpoint". +// +// If no endpoint override is specified, we will either return the default +// endpoint or the default mTLS endpoint if a client certificate is available. +// +// You can override the default endpoint choice (mTLS vs. regular) by setting +// the GOOGLE_API_USE_MTLS_ENDPOINT environment variable. +// +// If the endpoint override is an address (host:port) rather than full base +// URL (ex. https://...), then the user-provided address will be merged into +// the default endpoint. For example, WithEndpoint("myhost:8000") and +// DefaultEndpointTemplate("https://UNIVERSE_DOMAIN/bar/baz") will return +// "https://myhost:8080/bar/baz". Note that this does not apply to the mTLS +// endpoint. +func getEndpoint(opts *Options, clientCertSource cert.Provider) (string, error) { + if opts.Endpoint == "" { + mtlsMode := getMTLSMode() + if mtlsMode == mTLSModeAlways || (clientCertSource != nil && mtlsMode == mTLSModeAuto) { + return opts.defaultMTLSEndpoint(), nil + } + return opts.defaultEndpoint(), nil + } + if strings.Contains(opts.Endpoint, "://") { + // User passed in a full URL path, use it verbatim. + return opts.Endpoint, nil + } + if opts.defaultEndpoint() == "" { + // If DefaultEndpointTemplate is not configured, + // use the user provided endpoint verbatim. This allows a naked + // "host[:port]" URL to be used with GRPC Direct Path. + return opts.Endpoint, nil + } + + // Assume user-provided endpoint is host[:port], merge it with the default endpoint. + return opts.mergedEndpoint() +} + +func getMTLSMode() string { + mode := os.Getenv(googleAPIUseMTLS) + if mode == "" { + mode = os.Getenv(googleAPIUseMTLSOld) // Deprecated. + } + if mode == "" { + return mTLSModeAuto + } + return strings.ToLower(mode) +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/default_cert.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/default_cert.go new file mode 100644 index 000000000..5cedc50f1 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/default_cert.go @@ -0,0 +1,65 @@ +// Copyright 2023 Google LLC +// +// 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 cert + +import ( + "crypto/tls" + "errors" + "sync" +) + +// defaultCertData holds all the variables pertaining to +// the default certificate provider created by [DefaultProvider]. +// +// A singleton model is used to allow the provider to be reused +// by the transport layer. As mentioned in [DefaultProvider] (provider nil, nil) +// may be returned to indicate a default provider could not be found, which +// will skip extra tls config in the transport layer . +type defaultCertData struct { + once sync.Once + provider Provider + err error +} + +var ( + defaultCert defaultCertData +) + +// Provider is a function that can be passed into crypto/tls.Config.GetClientCertificate. +type Provider func(*tls.CertificateRequestInfo) (*tls.Certificate, error) + +// errSourceUnavailable is a sentinel error to indicate certificate source is unavailable. +var errSourceUnavailable = errors.New("certificate source is unavailable") + +// DefaultProvider returns a certificate source using the preferred EnterpriseCertificateProxySource. +// If EnterpriseCertificateProxySource is not available, fall back to the legacy SecureConnectSource. +// +// If neither source is available (due to missing configurations), a nil Source and a nil Error are +// returned to indicate that a default certificate source is unavailable. +func DefaultProvider() (Provider, error) { + defaultCert.once.Do(func() { + defaultCert.provider, defaultCert.err = NewWorkloadX509CertProvider("") + if errors.Is(defaultCert.err, errSourceUnavailable) { + defaultCert.provider, defaultCert.err = NewEnterpriseCertificateProxyProvider("") + if errors.Is(defaultCert.err, errSourceUnavailable) { + defaultCert.provider, defaultCert.err = NewSecureConnectProvider("") + if errors.Is(defaultCert.err, errSourceUnavailable) { + defaultCert.provider, defaultCert.err = nil, nil + } + } + } + }) + return defaultCert.provider, defaultCert.err +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/enterprise_cert.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/enterprise_cert.go new file mode 100644 index 000000000..6c954ae19 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/enterprise_cert.go @@ -0,0 +1,54 @@ +// Copyright 2023 Google LLC +// +// 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 cert + +import ( + "crypto/tls" + + "github.com/googleapis/enterprise-certificate-proxy/client" +) + +type ecpSource struct { + key *client.Key +} + +// NewEnterpriseCertificateProxyProvider creates a certificate source +// using the Enterprise Certificate Proxy client, which delegates +// certifcate related operations to an OS-specific "signer binary" +// that communicates with the native keystore (ex. keychain on MacOS). +// +// The configFilePath points to a config file containing relevant parameters +// such as the certificate issuer and the location of the signer binary. +// If configFilePath is empty, the client will attempt to load the config from +// a well-known gcloud location. +func NewEnterpriseCertificateProxyProvider(configFilePath string) (Provider, error) { + key, err := client.Cred(configFilePath) + if err != nil { + // TODO(codyoss): once this is fixed upstream can handle this error a + // little better here. But be safe for now and assume unavailable. + return nil, errSourceUnavailable + } + + return (&ecpSource{ + key: key, + }).getClientCertificate, nil +} + +func (s *ecpSource) getClientCertificate(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { + var cert tls.Certificate + cert.PrivateKey = s.key + cert.Certificate = s.key.CertificateChain() + return &cert, nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/secureconnect_cert.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/secureconnect_cert.go new file mode 100644 index 000000000..738cb2161 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/secureconnect_cert.go @@ -0,0 +1,124 @@ +// Copyright 2023 Google LLC +// +// 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 cert + +import ( + "crypto/tls" + "crypto/x509" + "encoding/json" + "errors" + "fmt" + "os" + "os/exec" + "os/user" + "path/filepath" + "sync" + "time" +) + +const ( + metadataPath = ".secureConnect" + metadataFile = "context_aware_metadata.json" +) + +type secureConnectSource struct { + metadata secureConnectMetadata + + // Cache the cert to avoid executing helper command repeatedly. + cachedCertMutex sync.Mutex + cachedCert *tls.Certificate +} + +type secureConnectMetadata struct { + Cmd []string `json:"cert_provider_command"` +} + +// NewSecureConnectProvider creates a certificate source using +// the Secure Connect Helper and its associated metadata file. +// +// The configFilePath points to the location of the context aware metadata file. +// If configFilePath is empty, use the default context aware metadata location. +func NewSecureConnectProvider(configFilePath string) (Provider, error) { + if configFilePath == "" { + user, err := user.Current() + if err != nil { + // Error locating the default config means Secure Connect is not supported. + return nil, errSourceUnavailable + } + configFilePath = filepath.Join(user.HomeDir, metadataPath, metadataFile) + } + + file, err := os.ReadFile(configFilePath) + if err != nil { + // Config file missing means Secure Connect is not supported. + // There are non-os.ErrNotExist errors that may be returned. + // (e.g. if the home directory is /dev/null, *nix systems will + // return ENOTDIR instead of ENOENT) + return nil, errSourceUnavailable + } + + var metadata secureConnectMetadata + if err := json.Unmarshal(file, &metadata); err != nil { + return nil, fmt.Errorf("cert: could not parse JSON in %q: %w", configFilePath, err) + } + if err := validateMetadata(metadata); err != nil { + return nil, fmt.Errorf("cert: invalid config in %q: %w", configFilePath, err) + } + return (&secureConnectSource{ + metadata: metadata, + }).getClientCertificate, nil +} + +func validateMetadata(metadata secureConnectMetadata) error { + if len(metadata.Cmd) == 0 { + return errors.New("empty cert_provider_command") + } + return nil +} + +func (s *secureConnectSource) getClientCertificate(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { + s.cachedCertMutex.Lock() + defer s.cachedCertMutex.Unlock() + if s.cachedCert != nil && !isCertificateExpired(s.cachedCert) { + return s.cachedCert, nil + } + // Expand OS environment variables in the cert provider command such as "$HOME". + for i := 0; i < len(s.metadata.Cmd); i++ { + s.metadata.Cmd[i] = os.ExpandEnv(s.metadata.Cmd[i]) + } + command := s.metadata.Cmd + data, err := exec.Command(command[0], command[1:]...).Output() + if err != nil { + return nil, err + } + cert, err := tls.X509KeyPair(data, data) + if err != nil { + return nil, err + } + s.cachedCert = &cert + return &cert, nil +} + +// isCertificateExpired returns true if the given cert is expired or invalid. +func isCertificateExpired(cert *tls.Certificate) bool { + if len(cert.Certificate) == 0 { + return true + } + parsed, err := x509.ParseCertificate(cert.Certificate[0]) + if err != nil { + return true + } + return time.Now().After(parsed.NotAfter) +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/workload_cert.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/workload_cert.go new file mode 100644 index 000000000..b2a3be23c --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/cert/workload_cert.go @@ -0,0 +1,138 @@ +// Copyright 2024 Google LLC +// +// 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 cert + +import ( + "crypto/tls" + "encoding/json" + "errors" + "io" + "os" + + "github.com/googleapis/enterprise-certificate-proxy/client/util" +) + +type certConfigs struct { + Workload *workloadSource `json:"workload"` +} + +type workloadSource struct { + CertPath string `json:"cert_path"` + KeyPath string `json:"key_path"` +} + +type certificateConfig struct { + CertConfigs certConfigs `json:"cert_configs"` +} + +// getconfigFilePath determines the path to the certificate configuration file. +// It first checks for the presence of an environment variable that specifies +// the file path. If the environment variable is not set, it falls back to +// a default configuration file path. +func getconfigFilePath() string { + envFilePath := util.GetConfigFilePathFromEnv() + if envFilePath != "" { + return envFilePath + } + return util.GetDefaultConfigFilePath() + +} + +// GetCertificatePath retrieves the certificate file path from the provided +// configuration file. If the configFilePath is empty, it attempts to load +// the configuration from a well-known gcloud location. +// This function is exposed to allow other packages, such as the +// externalaccount package, to retrieve the certificate path without needing +// to load the entire certificate configuration. +func GetCertificatePath(configFilePath string) (string, error) { + if configFilePath == "" { + configFilePath = getconfigFilePath() + } + certFile, _, err := getCertAndKeyFiles(configFilePath) + if err != nil { + return "", err + } + return certFile, nil +} + +// NewWorkloadX509CertProvider creates a certificate source +// that reads a certificate and private key file from the local file system. +// This is intended to be used for workload identity federation. +// +// The configFilePath points to a config file containing relevant parameters +// such as the certificate and key file paths. +// If configFilePath is empty, the client will attempt to load the config from +// a well-known gcloud location. +func NewWorkloadX509CertProvider(configFilePath string) (Provider, error) { + if configFilePath == "" { + configFilePath = getconfigFilePath() + } + certFile, keyFile, err := getCertAndKeyFiles(configFilePath) + if err != nil { + return nil, err + } + + source := &workloadSource{ + CertPath: certFile, + KeyPath: keyFile, + } + return source.getClientCertificate, nil +} + +// getClientCertificate attempts to load the certificate and key from the files specified in the +// certificate config. +func (s *workloadSource) getClientCertificate(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { + cert, err := tls.LoadX509KeyPair(s.CertPath, s.KeyPath) + if err != nil { + return nil, err + } + return &cert, nil +} + +// getCertAndKeyFiles attempts to read the provided config file and return the certificate and private +// key file paths. +func getCertAndKeyFiles(configFilePath string) (string, string, error) { + jsonFile, err := os.Open(configFilePath) + if err != nil { + return "", "", errSourceUnavailable + } + + byteValue, err := io.ReadAll(jsonFile) + if err != nil { + return "", "", err + } + + var config certificateConfig + if err := json.Unmarshal(byteValue, &config); err != nil { + return "", "", err + } + + if config.CertConfigs.Workload == nil { + return "", "", errSourceUnavailable + } + + certFile := config.CertConfigs.Workload.CertPath + keyFile := config.CertConfigs.Workload.KeyPath + + if certFile == "" { + return "", "", errors.New("certificate configuration is missing the certificate file location") + } + + if keyFile == "" { + return "", "", errors.New("certificate configuration is missing the key file location") + } + + return certFile, keyFile, nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/headers/headers.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/headers/headers.go new file mode 100644 index 000000000..5483a763c --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/headers/headers.go @@ -0,0 +1,61 @@ +// Copyright 2025 Google LLC +// +// 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 headers + +import ( + "net/http" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/internal" +) + +// SetAuthHeader uses the provided token to set the Authorization and trust +// boundary headers on a request. If the token.Type is empty, the type is +// assumed to be Bearer. +func SetAuthHeader(token *auth.Token, req *http.Request) { + typ := token.Type + if typ == "" { + typ = internal.TokenTypeBearer + } + req.Header.Set("Authorization", typ+" "+token.Value) + + if headerVal, setHeader := getTrustBoundaryHeader(token); setHeader { + req.Header.Set("x-allowed-locations", headerVal) + } +} + +// SetAuthMetadata uses the provided token to set the Authorization and trust +// boundary metadata. If the token.Type is empty, the type is assumed to be +// Bearer. +func SetAuthMetadata(token *auth.Token, m map[string]string) { + typ := token.Type + if typ == "" { + typ = internal.TokenTypeBearer + } + m["authorization"] = typ + " " + token.Value + + if headerVal, setHeader := getTrustBoundaryHeader(token); setHeader { + m["x-allowed-locations"] = headerVal + } +} + +func getTrustBoundaryHeader(token *auth.Token) (val string, present bool) { + if data, ok := token.Metadata[internal.TrustBoundaryDataKey]; ok { + if tbd, ok := data.(internal.TrustBoundaryData); ok { + return tbd.TrustBoundaryHeader() + } + } + return "", false +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/s2a.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/s2a.go new file mode 100644 index 000000000..a63309956 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/s2a.go @@ -0,0 +1,138 @@ +// Copyright 2023 Google LLC +// +// 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 transport + +import ( + "context" + "encoding/json" + "fmt" + "log" + "log/slog" + "os" + "strconv" + "sync" + + "cloud.google.com/go/auth/internal/transport/cert" + "cloud.google.com/go/compute/metadata" +) + +const ( + configEndpointSuffix = "instance/platform-security/auto-mtls-configuration" +) + +var ( + mtlsConfiguration *mtlsConfig + + mtlsOnce sync.Once +) + +// GetS2AAddress returns the S2A address to be reached via plaintext connection. +// Returns empty string if not set or invalid. +func GetS2AAddress(logger *slog.Logger) string { + getMetadataMTLSAutoConfig(logger) + if !mtlsConfiguration.valid() { + return "" + } + return mtlsConfiguration.S2A.PlaintextAddress +} + +// GetMTLSS2AAddress returns the S2A address to be reached via MTLS connection. +// Returns empty string if not set or invalid. +func GetMTLSS2AAddress(logger *slog.Logger) string { + getMetadataMTLSAutoConfig(logger) + if !mtlsConfiguration.valid() { + return "" + } + return mtlsConfiguration.S2A.MTLSAddress +} + +// mtlsConfig contains the configuration for establishing MTLS connections with Google APIs. +type mtlsConfig struct { + S2A *s2aAddresses `json:"s2a"` +} + +func (c *mtlsConfig) valid() bool { + return c != nil && c.S2A != nil +} + +// s2aAddresses contains the plaintext and/or MTLS S2A addresses. +type s2aAddresses struct { + // PlaintextAddress is the plaintext address to reach S2A + PlaintextAddress string `json:"plaintext_address"` + // MTLSAddress is the MTLS address to reach S2A + MTLSAddress string `json:"mtls_address"` +} + +func getMetadataMTLSAutoConfig(logger *slog.Logger) { + var err error + mtlsOnce.Do(func() { + mtlsConfiguration, err = queryConfig(logger) + if err != nil { + log.Printf("Getting MTLS config failed: %v", err) + } + }) +} + +var httpGetMetadataMTLSConfig = func(logger *slog.Logger) (string, error) { + metadataClient := metadata.NewWithOptions(&metadata.Options{ + Logger: logger, + }) + return metadataClient.GetWithContext(context.Background(), configEndpointSuffix) +} + +func queryConfig(logger *slog.Logger) (*mtlsConfig, error) { + resp, err := httpGetMetadataMTLSConfig(logger) + if err != nil { + return nil, fmt.Errorf("querying MTLS config from MDS endpoint failed: %w", err) + } + var config mtlsConfig + err = json.Unmarshal([]byte(resp), &config) + if err != nil { + return nil, fmt.Errorf("unmarshalling MTLS config from MDS endpoint failed: %w", err) + } + if config.S2A == nil { + return nil, fmt.Errorf("returned MTLS config from MDS endpoint is invalid: %v", config) + } + return &config, nil +} + +func shouldUseS2A(clientCertSource cert.Provider, opts *Options) bool { + // If client cert is found, use that over S2A. + if clientCertSource != nil { + return false + } + // If EXPERIMENTAL_GOOGLE_API_USE_S2A is not set to true, skip S2A. + if !isGoogleS2AEnabled() { + return false + } + // If DefaultMTLSEndpoint is not set or has endpoint override, skip S2A. + if opts.DefaultMTLSEndpoint == "" || opts.Endpoint != "" { + return false + } + // If custom HTTP client is provided, skip S2A. + if opts.Client != nil { + return false + } + // If directPath is enabled, skip S2A. + return !opts.EnableDirectPath && !opts.EnableDirectPathXds +} + +func isGoogleS2AEnabled() bool { + b, err := strconv.ParseBool(os.Getenv(googleAPIUseS2AEnv)) + if err != nil { + return false + } + return b +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/transport.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/transport.go new file mode 100644 index 000000000..5c8721efa --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/transport/transport.go @@ -0,0 +1,107 @@ +// Copyright 2023 Google LLC +// +// 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 transport provided internal helpers for the two transport packages +// (grpctransport and httptransport). +package transport + +import ( + "crypto/tls" + "fmt" + "net" + "net/http" + "time" + + "cloud.google.com/go/auth/credentials" +) + +// CloneDetectOptions clones a user set detect option into some new memory that +// we can internally manipulate before sending onto the detect package. +func CloneDetectOptions(oldDo *credentials.DetectOptions) *credentials.DetectOptions { + if oldDo == nil { + // it is valid for users not to set this, but we will need to to default + // some options for them in this case so return some initialized memory + // to work with. + return &credentials.DetectOptions{} + } + newDo := &credentials.DetectOptions{ + // Simple types + TokenBindingType: oldDo.TokenBindingType, + Audience: oldDo.Audience, + Subject: oldDo.Subject, + EarlyTokenRefresh: oldDo.EarlyTokenRefresh, + TokenURL: oldDo.TokenURL, + STSAudience: oldDo.STSAudience, + CredentialsFile: oldDo.CredentialsFile, + UseSelfSignedJWT: oldDo.UseSelfSignedJWT, + UniverseDomain: oldDo.UniverseDomain, + + // These fields are pointer types that we just want to use exactly as + // the user set, copy the ref + Client: oldDo.Client, + Logger: oldDo.Logger, + AuthHandlerOptions: oldDo.AuthHandlerOptions, + } + + // Smartly size this memory and copy below. + if len(oldDo.CredentialsJSON) > 0 { + newDo.CredentialsJSON = make([]byte, len(oldDo.CredentialsJSON)) + copy(newDo.CredentialsJSON, oldDo.CredentialsJSON) + } + if len(oldDo.Scopes) > 0 { + newDo.Scopes = make([]string, len(oldDo.Scopes)) + copy(newDo.Scopes, oldDo.Scopes) + } + + return newDo +} + +// ValidateUniverseDomain verifies that the universe domain configured for the +// client matches the universe domain configured for the credentials. +func ValidateUniverseDomain(clientUniverseDomain, credentialsUniverseDomain string) error { + if clientUniverseDomain != credentialsUniverseDomain { + return fmt.Errorf( + "the configured universe domain (%q) does not match the universe "+ + "domain found in the credentials (%q). If you haven't configured "+ + "the universe domain explicitly, \"googleapis.com\" is the default", + clientUniverseDomain, + credentialsUniverseDomain) + } + return nil +} + +// DefaultHTTPClientWithTLS constructs an HTTPClient using the provided tlsConfig, to support mTLS. +func DefaultHTTPClientWithTLS(tlsConfig *tls.Config) *http.Client { + trans := BaseTransport() + trans.TLSClientConfig = tlsConfig + return &http.Client{Transport: trans} +} + +// BaseTransport returns a default [http.Transport] which can be used if +// [http.DefaultTransport] has been overwritten. +func BaseTransport() *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + MaxIdleConns: 100, + MaxIdleConnsPerHost: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/trustboundary/external_accounts_config_providers.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/trustboundary/external_accounts_config_providers.go new file mode 100644 index 000000000..8fa5600bd --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/trustboundary/external_accounts_config_providers.go @@ -0,0 +1,100 @@ +// Copyright 2025 Google LLC +// +// 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 trustboundary + +import ( + "context" + "fmt" + "regexp" +) + +const ( + workloadAllowedLocationsEndpoint = "https://iamcredentials.%s/v1/projects/%s/locations/global/workloadIdentityPools/%s/allowedLocations" + workforceAllowedLocationsEndpoint = "https://iamcredentials.%s/v1/locations/global/workforcePools/%s/allowedLocations" +) + +var ( + workforceAudiencePattern = regexp.MustCompile(`//iam\.([^/]+)/locations/global/workforcePools/([^/]+)`) + workloadAudiencePattern = regexp.MustCompile(`//iam\.([^/]+)/projects/([^/]+)/locations/global/workloadIdentityPools/([^/]+)`) +) + +// NewExternalAccountConfigProvider creates a new ConfigProvider for external accounts. +func NewExternalAccountConfigProvider(audience, inputUniverseDomain string) (ConfigProvider, error) { + var audienceDomain, projectNumber, poolID string + var isWorkload bool + + matches := workloadAudiencePattern.FindStringSubmatch(audience) + if len(matches) == 4 { // Expecting full match, domain, projectNumber, poolID + audienceDomain = matches[1] + projectNumber = matches[2] + poolID = matches[3] + isWorkload = true + } else { + matches = workforceAudiencePattern.FindStringSubmatch(audience) + if len(matches) == 3 { // Expecting full match, domain, poolID + audienceDomain = matches[1] + poolID = matches[2] + isWorkload = false + } else { + return nil, fmt.Errorf("trustboundary: unknown audience format: %q", audience) + } + } + + effectiveUniverseDomain := inputUniverseDomain + if effectiveUniverseDomain == "" { + effectiveUniverseDomain = audienceDomain + } else if audienceDomain != "" && effectiveUniverseDomain != audienceDomain { + return nil, fmt.Errorf("trustboundary: provided universe domain (%q) does not match domain in audience (%q)", inputUniverseDomain, audienceDomain) + } + + if isWorkload { + return &workloadIdentityPoolConfigProvider{ + projectNumber: projectNumber, + poolID: poolID, + universeDomain: effectiveUniverseDomain, + }, nil + } + return &workforcePoolConfigProvider{ + poolID: poolID, + universeDomain: effectiveUniverseDomain, + }, nil +} + +type workforcePoolConfigProvider struct { + poolID string + universeDomain string +} + +func (p *workforcePoolConfigProvider) GetTrustBoundaryEndpoint(ctx context.Context) (string, error) { + return fmt.Sprintf(workforceAllowedLocationsEndpoint, p.universeDomain, p.poolID), nil +} + +func (p *workforcePoolConfigProvider) GetUniverseDomain(ctx context.Context) (string, error) { + return p.universeDomain, nil +} + +type workloadIdentityPoolConfigProvider struct { + projectNumber string + poolID string + universeDomain string +} + +func (p *workloadIdentityPoolConfigProvider) GetTrustBoundaryEndpoint(ctx context.Context) (string, error) { + return fmt.Sprintf(workloadAllowedLocationsEndpoint, p.universeDomain, p.projectNumber, p.poolID), nil +} + +func (p *workloadIdentityPoolConfigProvider) GetUniverseDomain(ctx context.Context) (string, error) { + return p.universeDomain, nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/trustboundary/trust_boundary.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/trustboundary/trust_boundary.go new file mode 100644 index 000000000..bf898fffd --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/trustboundary/trust_boundary.go @@ -0,0 +1,392 @@ +// Copyright 2025 Google LLC +// +// 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 trustboundary + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "os" + "strings" + "sync" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/retry" + "cloud.google.com/go/auth/internal/transport/headers" + "github.com/googleapis/gax-go/v2/internallog" +) + +const ( + // serviceAccountAllowedLocationsEndpoint is the URL for fetching allowed locations for a given service account email. + serviceAccountAllowedLocationsEndpoint = "https://iamcredentials.%s/v1/projects/-/serviceAccounts/%s/allowedLocations" +) + +// isEnabled wraps isTrustBoundaryEnabled with sync.OnceValues to ensure it's +// called only once. +var isEnabled = sync.OnceValues(isTrustBoundaryEnabled) + +// IsEnabled returns if the trust boundary feature is enabled and an error if +// the configuration is invalid. The underlying check is performed only once. +func IsEnabled() (bool, error) { + return isEnabled() +} + +// isTrustBoundaryEnabled checks if the trust boundary feature is enabled via +// GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED environment variable. +// +// If the environment variable is not set, it is considered false. +// +// The environment variable is interpreted as a boolean with the following +// (case-insensitive) rules: +// - "true", "1" are considered true. +// - "false", "0" are considered false. +// +// Any other values will return an error. +func isTrustBoundaryEnabled() (bool, error) { + const envVar = "GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED" + val, ok := os.LookupEnv(envVar) + if !ok { + return false, nil + } + val = strings.ToLower(val) + switch val { + case "true", "1": + return true, nil + case "false", "0": + return false, nil + default: + return false, fmt.Errorf(`invalid value for %s: %q. Must be one of "true", "false", "1", or "0"`, envVar, val) + } +} + +// ConfigProvider provides specific configuration for trust boundary lookups. +type ConfigProvider interface { + // GetTrustBoundaryEndpoint returns the endpoint URL for the trust boundary lookup. + GetTrustBoundaryEndpoint(ctx context.Context) (url string, err error) + // GetUniverseDomain returns the universe domain associated with the credential. + // It may return an error if the universe domain cannot be determined. + GetUniverseDomain(ctx context.Context) (string, error) +} + +// AllowedLocationsResponse is the structure of the response from the Trust Boundary API. +type AllowedLocationsResponse struct { + // Locations is the list of allowed locations. + Locations []string `json:"locations"` + // EncodedLocations is the encoded representation of the allowed locations. + EncodedLocations string `json:"encodedLocations"` +} + +// fetchTrustBoundaryData fetches the trust boundary data from the API. +func fetchTrustBoundaryData(ctx context.Context, client *http.Client, url string, token *auth.Token, logger *slog.Logger) (*internal.TrustBoundaryData, error) { + if logger == nil { + logger = slog.New(slog.NewTextHandler(io.Discard, nil)) + } + if client == nil { + return nil, errors.New("trustboundary: HTTP client is required") + } + + if url == "" { + return nil, errors.New("trustboundary: URL cannot be empty") + } + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return nil, fmt.Errorf("trustboundary: failed to create trust boundary request: %w", err) + } + + if token == nil || token.Value == "" { + return nil, errors.New("trustboundary: access token required for lookup API authentication") + } + headers.SetAuthHeader(token, req) + logger.DebugContext(ctx, "trust boundary request", "request", internallog.HTTPRequest(req, nil)) + + retryer := retry.New() + var response *http.Response + for { + response, err = client.Do(req) + + var statusCode int + if response != nil { + statusCode = response.StatusCode + } + pause, shouldRetry := retryer.Retry(statusCode, err) + + if !shouldRetry { + break + } + + if response != nil { + // Drain and close the body to reuse the connection + io.Copy(io.Discard, response.Body) + response.Body.Close() + } + + if err := retry.Sleep(ctx, pause); err != nil { + return nil, err + } + } + + if err != nil { + return nil, fmt.Errorf("trustboundary: failed to fetch trust boundary: %w", err) + } + defer response.Body.Close() + + body, err := io.ReadAll(response.Body) + if err != nil { + return nil, fmt.Errorf("trustboundary: failed to read trust boundary response: %w", err) + } + + logger.DebugContext(ctx, "trust boundary response", "response", internallog.HTTPResponse(response, body)) + + if response.StatusCode != http.StatusOK { + return nil, fmt.Errorf("trustboundary: trust boundary request failed with status: %s, body: %s", response.Status, string(body)) + } + + apiResponse := AllowedLocationsResponse{} + if err := json.Unmarshal(body, &apiResponse); err != nil { + return nil, fmt.Errorf("trustboundary: failed to unmarshal trust boundary response: %w", err) + } + + if apiResponse.EncodedLocations == "" { + return nil, errors.New("trustboundary: invalid API response: encodedLocations is empty") + } + + return internal.NewTrustBoundaryData(apiResponse.Locations, apiResponse.EncodedLocations), nil +} + +// serviceAccountConfig holds configuration for SA trust boundary lookups. +// It implements the ConfigProvider interface. +type serviceAccountConfig struct { + ServiceAccountEmail string + UniverseDomain string +} + +// NewServiceAccountConfigProvider creates a new config for service accounts. +func NewServiceAccountConfigProvider(saEmail, universeDomain string) ConfigProvider { + return &serviceAccountConfig{ + ServiceAccountEmail: saEmail, + UniverseDomain: universeDomain, + } +} + +// GetTrustBoundaryEndpoint returns the formatted URL for fetching allowed locations +// for the configured service account and universe domain. +func (sac *serviceAccountConfig) GetTrustBoundaryEndpoint(ctx context.Context) (url string, err error) { + if sac.ServiceAccountEmail == "" { + return "", errors.New("trustboundary: service account email cannot be empty for config") + } + ud := sac.UniverseDomain + if ud == "" { + ud = internal.DefaultUniverseDomain + } + return fmt.Sprintf(serviceAccountAllowedLocationsEndpoint, ud, sac.ServiceAccountEmail), nil +} + +// GetUniverseDomain returns the configured universe domain, defaulting to +// [internal.DefaultUniverseDomain] if not explicitly set. +func (sac *serviceAccountConfig) GetUniverseDomain(ctx context.Context) (string, error) { + if sac.UniverseDomain == "" { + return internal.DefaultUniverseDomain, nil + } + return sac.UniverseDomain, nil +} + +// DataProvider fetches and caches trust boundary Data. +// It implements the DataProvider interface and uses a ConfigProvider +// to get type-specific details for the lookup. +type DataProvider struct { + client *http.Client + configProvider ConfigProvider + data *internal.TrustBoundaryData + logger *slog.Logger + base auth.TokenProvider +} + +// NewProvider wraps the provided base [auth.TokenProvider] to create a new +// provider that injects tokens with trust boundary data. It uses the provided +// HTTP client and configProvider to fetch the data and attach it to the token's +// metadata. +func NewProvider(client *http.Client, configProvider ConfigProvider, logger *slog.Logger, base auth.TokenProvider) (*DataProvider, error) { + if client == nil { + return nil, errors.New("trustboundary: HTTP client cannot be nil for DataProvider") + } + if configProvider == nil { + return nil, errors.New("trustboundary: ConfigProvider cannot be nil for DataProvider") + } + p := &DataProvider{ + client: client, + configProvider: configProvider, + logger: internallog.New(logger), + base: base, + } + return p, nil +} + +// Token retrieves a token from the base provider and injects it with trust +// boundary data. +func (p *DataProvider) Token(ctx context.Context) (*auth.Token, error) { + // Get the original token. + token, err := p.base.Token(ctx) + if err != nil { + return nil, err + } + + tbData, err := p.GetTrustBoundaryData(ctx, token) + if err != nil { + return nil, fmt.Errorf("trustboundary: error fetching the trust boundary data: %w", err) + } + if tbData != nil { + if token.Metadata == nil { + token.Metadata = make(map[string]interface{}) + } + token.Metadata[internal.TrustBoundaryDataKey] = *tbData + } + return token, nil +} + +// GetTrustBoundaryData retrieves the trust boundary data. +// It first checks the universe domain: if it's non-default, a NoOp is returned. +// Otherwise, it checks a local cache. If the data is not cached as NoOp, +// it fetches new data from the endpoint provided by its ConfigProvider, +// using the given accessToken for authentication. Results are cached. +// If fetching fails, it returns previously cached data if available, otherwise the fetch error. +func (p *DataProvider) GetTrustBoundaryData(ctx context.Context, token *auth.Token) (*internal.TrustBoundaryData, error) { + // Check the universe domain. + uniDomain, err := p.configProvider.GetUniverseDomain(ctx) + if err != nil { + return nil, fmt.Errorf("trustboundary: error getting universe domain: %w", err) + } + if uniDomain != "" && uniDomain != internal.DefaultUniverseDomain { + if p.data == nil || p.data.EncodedLocations != internal.TrustBoundaryNoOp { + p.data = internal.NewNoOpTrustBoundaryData() + } + return p.data, nil + } + + // Check cache for a no-op result from a previous API call. + cachedData := p.data + if cachedData != nil && cachedData.EncodedLocations == internal.TrustBoundaryNoOp { + return cachedData, nil + } + + // Get the endpoint + url, err := p.configProvider.GetTrustBoundaryEndpoint(ctx) + if err != nil { + return nil, fmt.Errorf("trustboundary: error getting the lookup endpoint: %w", err) + } + + // Proceed to fetch new data. + newData, fetchErr := fetchTrustBoundaryData(ctx, p.client, url, token, p.logger) + + if fetchErr != nil { + // Fetch failed. Fallback to cachedData if available. + if cachedData != nil { + return cachedData, nil // Successful fallback + } + // No cache to fallback to. + return nil, fmt.Errorf("trustboundary: failed to fetch trust boundary data for endpoint %s and no cache available: %w", url, fetchErr) + } + + // Fetch successful. Update cache. + p.data = newData + return newData, nil +} + +// GCEConfigProvider implements ConfigProvider for GCE environments. +// It lazily fetches and caches the necessary metadata (service account email, universe domain) +// from the GCE metadata server. +type GCEConfigProvider struct { + // universeDomainProvider provides the universe domain and underlying metadata client. + universeDomainProvider *internal.ComputeUniverseDomainProvider + + // Caching for service account email + saOnce sync.Once + saEmail string + saEmailErr error + + // Caching for universe domain + udOnce sync.Once + ud string + udErr error +} + +// NewGCEConfigProvider creates a new GCEConfigProvider +// which uses the provided gceUDP to interact with the GCE metadata server. +func NewGCEConfigProvider(gceUDP *internal.ComputeUniverseDomainProvider) *GCEConfigProvider { + // The validity of gceUDP and its internal MetadataClient will be checked + // within the GetTrustBoundaryEndpoint and GetUniverseDomain methods. + return &GCEConfigProvider{ + universeDomainProvider: gceUDP, + } +} + +func (g *GCEConfigProvider) fetchSA(ctx context.Context) { + if g.universeDomainProvider == nil || g.universeDomainProvider.MetadataClient == nil { + g.saEmailErr = errors.New("trustboundary: GCEConfigProvider not properly initialized (missing ComputeUniverseDomainProvider or MetadataClient)") + return + } + mdClient := g.universeDomainProvider.MetadataClient + saEmail, err := mdClient.EmailWithContext(ctx, "default") + if err != nil { + g.saEmailErr = fmt.Errorf("trustboundary: GCE config: failed to get service account email: %w", err) + return + } + g.saEmail = saEmail +} + +func (g *GCEConfigProvider) fetchUD(ctx context.Context) { + if g.universeDomainProvider == nil || g.universeDomainProvider.MetadataClient == nil { + g.udErr = errors.New("trustboundary: GCEConfigProvider not properly initialized (missing ComputeUniverseDomainProvider or MetadataClient)") + return + } + ud, err := g.universeDomainProvider.GetProperty(ctx) + if err != nil { + g.udErr = fmt.Errorf("trustboundary: GCE config: failed to get universe domain: %w", err) + return + } + if ud == "" { + ud = internal.DefaultUniverseDomain + } + g.ud = ud +} + +// GetTrustBoundaryEndpoint constructs the trust boundary lookup URL for a GCE environment. +// It uses cached metadata (service account email, universe domain) after the first call. +func (g *GCEConfigProvider) GetTrustBoundaryEndpoint(ctx context.Context) (string, error) { + g.saOnce.Do(func() { g.fetchSA(ctx) }) + if g.saEmailErr != nil { + return "", g.saEmailErr + } + g.udOnce.Do(func() { g.fetchUD(ctx) }) + if g.udErr != nil { + return "", g.udErr + } + return fmt.Sprintf(serviceAccountAllowedLocationsEndpoint, g.ud, g.saEmail), nil +} + +// GetUniverseDomain retrieves the universe domain from the GCE metadata server. +// It uses a cached value after the first call. +func (g *GCEConfigProvider) GetUniverseDomain(ctx context.Context) (string, error) { + g.udOnce.Do(func() { g.fetchUD(ctx) }) + if g.udErr != nil { + return "", g.udErr + } + return g.ud, nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/internal/version.go b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/version.go new file mode 100644 index 000000000..b73008694 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/internal/version.go @@ -0,0 +1,20 @@ +// Copyright 2026 Google LLC +// +// 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. + +// Code generated by gapicgen. DO NOT EDIT. + +package internal + +// Version is the current tagged release of the library. +const Version = "0.18.2" diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/oauth2adapt/CHANGES.md b/plugins/traefik/vendor/cloud.google.com/go/auth/oauth2adapt/CHANGES.md new file mode 100644 index 000000000..42716752e --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/oauth2adapt/CHANGES.md @@ -0,0 +1,82 @@ +# Changelog + +## [0.2.8](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.7...auth/oauth2adapt/v0.2.8) (2025-03-17) + + +### Bug Fixes + +* **auth/oauth2adapt:** Update golang.org/x/net to 0.37.0 ([1144978](https://github.com/googleapis/google-cloud-go/commit/11449782c7fb4896bf8b8b9cde8e7441c84fb2fd)) + +## [0.2.7](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.6...auth/oauth2adapt/v0.2.7) (2025-01-09) + + +### Bug Fixes + +* **auth/oauth2adapt:** Update golang.org/x/net to v0.33.0 ([e9b0b69](https://github.com/googleapis/google-cloud-go/commit/e9b0b69644ea5b276cacff0a707e8a5e87efafc9)) + +## [0.2.6](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.5...auth/oauth2adapt/v0.2.6) (2024-11-21) + + +### Bug Fixes + +* **auth/oauth2adapt:** Copy map in tokenSourceAdapter.Token ([#11164](https://github.com/googleapis/google-cloud-go/issues/11164)) ([8cb0cbc](https://github.com/googleapis/google-cloud-go/commit/8cb0cbccdc32886dfb3af49fee04012937d114d2)), refs [#11161](https://github.com/googleapis/google-cloud-go/issues/11161) + +## [0.2.5](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.4...auth/oauth2adapt/v0.2.5) (2024-10-30) + + +### Bug Fixes + +* **auth/oauth2adapt:** Convert token metadata where possible ([#11062](https://github.com/googleapis/google-cloud-go/issues/11062)) ([34bf1c1](https://github.com/googleapis/google-cloud-go/commit/34bf1c164465d66745c0cfdf7cd10a8e2da92e52)) + +## [0.2.4](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.3...auth/oauth2adapt/v0.2.4) (2024-08-08) + + +### Bug Fixes + +* **auth/oauth2adapt:** Update dependencies ([257c40b](https://github.com/googleapis/google-cloud-go/commit/257c40bd6d7e59730017cf32bda8823d7a232758)) + +## [0.2.3](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.2...auth/oauth2adapt/v0.2.3) (2024-07-10) + + +### Bug Fixes + +* **auth/oauth2adapt:** Bump google.golang.org/api@v0.187.0 ([8fa9e39](https://github.com/googleapis/google-cloud-go/commit/8fa9e398e512fd8533fd49060371e61b5725a85b)) + +## [0.2.2](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.1...auth/oauth2adapt/v0.2.2) (2024-04-23) + + +### Bug Fixes + +* **auth/oauth2adapt:** Bump x/net to v0.24.0 ([ba31ed5](https://github.com/googleapis/google-cloud-go/commit/ba31ed5fda2c9664f2e1cf972469295e63deb5b4)) + +## [0.2.1](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.0...auth/oauth2adapt/v0.2.1) (2024-04-18) + + +### Bug Fixes + +* **auth/oauth2adapt:** Adapt Token Types to be translated ([#9801](https://github.com/googleapis/google-cloud-go/issues/9801)) ([70f4115](https://github.com/googleapis/google-cloud-go/commit/70f411555ebbf2b71e6d425cc8d2030644c6b438)), refs [#9800](https://github.com/googleapis/google-cloud-go/issues/9800) + +## [0.2.0](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.1.0...auth/oauth2adapt/v0.2.0) (2024-04-16) + + +### Features + +* **auth/oauth2adapt:** Add helpers for working with credentials types ([#9694](https://github.com/googleapis/google-cloud-go/issues/9694)) ([cf33b55](https://github.com/googleapis/google-cloud-go/commit/cf33b5514423a2ac5c2a323a1cd99aac34fd4233)) + + +### Bug Fixes + +* **auth/oauth2adapt:** Update protobuf dep to v1.33.0 ([30b038d](https://github.com/googleapis/google-cloud-go/commit/30b038d8cac0b8cd5dd4761c87f3f298760dd33a)) + +## 0.1.0 (2023-10-19) + + +### Features + +* **auth/oauth2adapt:** Adds a new module to translate types ([#8595](https://github.com/googleapis/google-cloud-go/issues/8595)) ([6933c5a](https://github.com/googleapis/google-cloud-go/commit/6933c5a0c1fc8e58cbfff8bbca439d671b94672f)) +* **auth/oauth2adapt:** Fixup deps for release ([#8747](https://github.com/googleapis/google-cloud-go/issues/8747)) ([749d243](https://github.com/googleapis/google-cloud-go/commit/749d243862b025a6487a4d2d339219889b4cfe70)) + + +### Bug Fixes + +* **auth/oauth2adapt:** Update golang.org/x/net to v0.17.0 ([174da47](https://github.com/googleapis/google-cloud-go/commit/174da47254fefb12921bbfc65b7829a453af6f5d)) diff --git a/plugins/traefik/vendor/go.uber.org/mock/LICENSE b/plugins/traefik/vendor/cloud.google.com/go/auth/oauth2adapt/LICENSE similarity index 100% rename from plugins/traefik/vendor/go.uber.org/mock/LICENSE rename to plugins/traefik/vendor/cloud.google.com/go/auth/oauth2adapt/LICENSE diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/oauth2adapt/oauth2adapt.go b/plugins/traefik/vendor/cloud.google.com/go/auth/oauth2adapt/oauth2adapt.go new file mode 100644 index 000000000..9cc33e5ee --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/oauth2adapt/oauth2adapt.go @@ -0,0 +1,200 @@ +// Copyright 2023 Google LLC +// +// 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 oauth2adapt helps converts types used in [cloud.google.com/go/auth] +// and [golang.org/x/oauth2]. +package oauth2adapt + +import ( + "context" + "encoding/json" + "errors" + + "cloud.google.com/go/auth" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" +) + +const ( + oauth2TokenSourceKey = "oauth2.google.tokenSource" + oauth2ServiceAccountKey = "oauth2.google.serviceAccount" + authTokenSourceKey = "auth.google.tokenSource" + authServiceAccountKey = "auth.google.serviceAccount" +) + +// TokenProviderFromTokenSource converts any [golang.org/x/oauth2.TokenSource] +// into a [cloud.google.com/go/auth.TokenProvider]. +func TokenProviderFromTokenSource(ts oauth2.TokenSource) auth.TokenProvider { + return &tokenProviderAdapter{ts: ts} +} + +type tokenProviderAdapter struct { + ts oauth2.TokenSource +} + +// Token fulfills the [cloud.google.com/go/auth.TokenProvider] interface. It +// is a light wrapper around the underlying TokenSource. +func (tp *tokenProviderAdapter) Token(context.Context) (*auth.Token, error) { + tok, err := tp.ts.Token() + if err != nil { + var err2 *oauth2.RetrieveError + if ok := errors.As(err, &err2); ok { + return nil, AuthErrorFromRetrieveError(err2) + } + return nil, err + } + // Preserve compute token metadata, for both types of tokens. + metadata := map[string]interface{}{} + if val, ok := tok.Extra(oauth2TokenSourceKey).(string); ok { + metadata[authTokenSourceKey] = val + metadata[oauth2TokenSourceKey] = val + } + if val, ok := tok.Extra(oauth2ServiceAccountKey).(string); ok { + metadata[authServiceAccountKey] = val + metadata[oauth2ServiceAccountKey] = val + } + return &auth.Token{ + Value: tok.AccessToken, + Type: tok.Type(), + Expiry: tok.Expiry, + Metadata: metadata, + }, nil +} + +// TokenSourceFromTokenProvider converts any +// [cloud.google.com/go/auth.TokenProvider] into a +// [golang.org/x/oauth2.TokenSource]. +func TokenSourceFromTokenProvider(tp auth.TokenProvider) oauth2.TokenSource { + return &tokenSourceAdapter{tp: tp} +} + +type tokenSourceAdapter struct { + tp auth.TokenProvider +} + +// Token fulfills the [golang.org/x/oauth2.TokenSource] interface. It +// is a light wrapper around the underlying TokenProvider. +func (ts *tokenSourceAdapter) Token() (*oauth2.Token, error) { + tok, err := ts.tp.Token(context.Background()) + if err != nil { + var err2 *auth.Error + if ok := errors.As(err, &err2); ok { + return nil, AddRetrieveErrorToAuthError(err2) + } + return nil, err + } + tok2 := &oauth2.Token{ + AccessToken: tok.Value, + TokenType: tok.Type, + Expiry: tok.Expiry, + } + // Preserve token metadata. + m := tok.Metadata + if m != nil { + // Copy map to avoid concurrent map writes error (#11161). + metadata := make(map[string]interface{}, len(m)+2) + for k, v := range m { + metadata[k] = v + } + // Append compute token metadata in converted form. + if val, ok := metadata[authTokenSourceKey].(string); ok && val != "" { + metadata[oauth2TokenSourceKey] = val + } + if val, ok := metadata[authServiceAccountKey].(string); ok && val != "" { + metadata[oauth2ServiceAccountKey] = val + } + tok2 = tok2.WithExtra(metadata) + } + return tok2, nil +} + +// AuthCredentialsFromOauth2Credentials converts a [golang.org/x/oauth2/google.Credentials] +// to a [cloud.google.com/go/auth.Credentials]. +func AuthCredentialsFromOauth2Credentials(creds *google.Credentials) *auth.Credentials { + if creds == nil { + return nil + } + return auth.NewCredentials(&auth.CredentialsOptions{ + TokenProvider: TokenProviderFromTokenSource(creds.TokenSource), + JSON: creds.JSON, + ProjectIDProvider: auth.CredentialsPropertyFunc(func(ctx context.Context) (string, error) { + return creds.ProjectID, nil + }), + UniverseDomainProvider: auth.CredentialsPropertyFunc(func(ctx context.Context) (string, error) { + return creds.GetUniverseDomain() + }), + }) +} + +// Oauth2CredentialsFromAuthCredentials converts a [cloud.google.com/go/auth.Credentials] +// to a [golang.org/x/oauth2/google.Credentials]. +func Oauth2CredentialsFromAuthCredentials(creds *auth.Credentials) *google.Credentials { + if creds == nil { + return nil + } + // Throw away errors as old credentials are not request aware. Also, no + // network requests are currently happening for this use case. + projectID, _ := creds.ProjectID(context.Background()) + + return &google.Credentials{ + TokenSource: TokenSourceFromTokenProvider(creds.TokenProvider), + ProjectID: projectID, + JSON: creds.JSON(), + UniverseDomainProvider: func() (string, error) { + return creds.UniverseDomain(context.Background()) + }, + } +} + +type oauth2Error struct { + ErrorCode string `json:"error"` + ErrorDescription string `json:"error_description"` + ErrorURI string `json:"error_uri"` +} + +// AddRetrieveErrorToAuthError returns the same error provided and adds a +// [golang.org/x/oauth2.RetrieveError] to the error chain by setting the `Err` field on the +// [cloud.google.com/go/auth.Error]. +func AddRetrieveErrorToAuthError(err *auth.Error) *auth.Error { + if err == nil { + return nil + } + e := &oauth2.RetrieveError{ + Response: err.Response, + Body: err.Body, + } + err.Err = e + if len(err.Body) > 0 { + var oErr oauth2Error + // ignore the error as it only fills in extra details + json.Unmarshal(err.Body, &oErr) + e.ErrorCode = oErr.ErrorCode + e.ErrorDescription = oErr.ErrorDescription + e.ErrorURI = oErr.ErrorURI + } + return err +} + +// AuthErrorFromRetrieveError returns an [cloud.google.com/go/auth.Error] that +// wraps the provided [golang.org/x/oauth2.RetrieveError]. +func AuthErrorFromRetrieveError(err *oauth2.RetrieveError) *auth.Error { + if err == nil { + return nil + } + return &auth.Error{ + Response: err.Response, + Body: err.Body, + Err: err, + } +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/auth/threelegged.go b/plugins/traefik/vendor/cloud.google.com/go/auth/threelegged.go new file mode 100644 index 000000000..07804dc16 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/auth/threelegged.go @@ -0,0 +1,382 @@ +// Copyright 2023 Google LLC +// +// 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 auth + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "log/slog" + "mime" + "net/http" + "net/url" + "strconv" + "strings" + "time" + + "cloud.google.com/go/auth/internal" + "github.com/googleapis/gax-go/v2/internallog" +) + +// AuthorizationHandler is a 3-legged-OAuth helper that prompts the user for +// OAuth consent at the specified auth code URL and returns an auth code and +// state upon approval. +type AuthorizationHandler func(authCodeURL string) (code string, state string, err error) + +// Options3LO are the options for doing a 3-legged OAuth2 flow. +type Options3LO struct { + // ClientID is the application's ID. + ClientID string + // ClientSecret is the application's secret. Not required if AuthHandlerOpts + // is set. + ClientSecret string + // AuthURL is the URL for authenticating. + AuthURL string + // TokenURL is the URL for retrieving a token. + TokenURL string + // AuthStyle is used to describe how to client info in the token request. + AuthStyle Style + // RefreshToken is the token used to refresh the credential. Not required + // if AuthHandlerOpts is set. + RefreshToken string + // RedirectURL is the URL to redirect users to. Optional. + RedirectURL string + // Scopes specifies requested permissions for the Token. Optional. + Scopes []string + + // URLParams are the set of values to apply to the token exchange. Optional. + URLParams url.Values + // Client is the client to be used to make the underlying token requests. + // Optional. + Client *http.Client + // EarlyTokenExpiry is the time before the token expires that it should be + // refreshed. If not set the default value is 3 minutes and 45 seconds. + // Optional. + EarlyTokenExpiry time.Duration + + // AuthHandlerOpts provides a set of options for doing a + // 3-legged OAuth2 flow with a custom [AuthorizationHandler]. Optional. + AuthHandlerOpts *AuthorizationHandlerOptions + // Logger is used for debug logging. If provided, logging will be enabled + // at the loggers configured level. By default logging is disabled unless + // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default + // logger will be used. Optional. + Logger *slog.Logger +} + +func (o *Options3LO) validate() error { + if o == nil { + return errors.New("auth: options must be provided") + } + if o.ClientID == "" { + return errors.New("auth: client ID must be provided") + } + if o.AuthHandlerOpts == nil && o.ClientSecret == "" { + return errors.New("auth: client secret must be provided") + } + if o.AuthURL == "" { + return errors.New("auth: auth URL must be provided") + } + if o.TokenURL == "" { + return errors.New("auth: token URL must be provided") + } + if o.AuthStyle == StyleUnknown { + return errors.New("auth: auth style must be provided") + } + if o.AuthHandlerOpts == nil && o.RefreshToken == "" { + return errors.New("auth: refresh token must be provided") + } + return nil +} + +func (o *Options3LO) logger() *slog.Logger { + return internallog.New(o.Logger) +} + +// PKCEOptions holds parameters to support PKCE. +type PKCEOptions struct { + // Challenge is the un-padded, base64-url-encoded string of the encrypted code verifier. + Challenge string // The un-padded, base64-url-encoded string of the encrypted code verifier. + // ChallengeMethod is the encryption method (ex. S256). + ChallengeMethod string + // Verifier is the original, non-encrypted secret. + Verifier string // The original, non-encrypted secret. +} + +type tokenJSON struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + RefreshToken string `json:"refresh_token"` + ExpiresIn int `json:"expires_in"` + // error fields + ErrorCode string `json:"error"` + ErrorDescription string `json:"error_description"` + ErrorURI string `json:"error_uri"` +} + +func (e *tokenJSON) expiry() (t time.Time) { + if v := e.ExpiresIn; v != 0 { + return time.Now().Add(time.Duration(v) * time.Second) + } + return +} + +func (o *Options3LO) client() *http.Client { + if o.Client != nil { + return o.Client + } + return internal.DefaultClient() +} + +// authCodeURL returns a URL that points to a OAuth2 consent page. +func (o *Options3LO) authCodeURL(state string, values url.Values) string { + var buf bytes.Buffer + buf.WriteString(o.AuthURL) + v := url.Values{ + "response_type": {"code"}, + "client_id": {o.ClientID}, + } + if o.RedirectURL != "" { + v.Set("redirect_uri", o.RedirectURL) + } + if len(o.Scopes) > 0 { + v.Set("scope", strings.Join(o.Scopes, " ")) + } + if state != "" { + v.Set("state", state) + } + if o.AuthHandlerOpts != nil { + if o.AuthHandlerOpts.PKCEOpts != nil && + o.AuthHandlerOpts.PKCEOpts.Challenge != "" { + v.Set(codeChallengeKey, o.AuthHandlerOpts.PKCEOpts.Challenge) + } + if o.AuthHandlerOpts.PKCEOpts != nil && + o.AuthHandlerOpts.PKCEOpts.ChallengeMethod != "" { + v.Set(codeChallengeMethodKey, o.AuthHandlerOpts.PKCEOpts.ChallengeMethod) + } + } + for k := range values { + v.Set(k, v.Get(k)) + } + if strings.Contains(o.AuthURL, "?") { + buf.WriteByte('&') + } else { + buf.WriteByte('?') + } + buf.WriteString(v.Encode()) + return buf.String() +} + +// New3LOTokenProvider returns a [TokenProvider] based on the 3-legged OAuth2 +// configuration. The TokenProvider is caches and auto-refreshes tokens by +// default. +func New3LOTokenProvider(opts *Options3LO) (TokenProvider, error) { + if err := opts.validate(); err != nil { + return nil, err + } + if opts.AuthHandlerOpts != nil { + return new3LOTokenProviderWithAuthHandler(opts), nil + } + return NewCachedTokenProvider(&tokenProvider3LO{opts: opts, refreshToken: opts.RefreshToken, client: opts.client()}, &CachedTokenProviderOptions{ + ExpireEarly: opts.EarlyTokenExpiry, + }), nil +} + +// AuthorizationHandlerOptions provides a set of options to specify for doing a +// 3-legged OAuth2 flow with a custom [AuthorizationHandler]. +type AuthorizationHandlerOptions struct { + // AuthorizationHandler specifies the handler used to for the authorization + // part of the flow. + Handler AuthorizationHandler + // State is used verify that the "state" is identical in the request and + // response before exchanging the auth code for OAuth2 token. + State string + // PKCEOpts allows setting configurations for PKCE. Optional. + PKCEOpts *PKCEOptions +} + +func new3LOTokenProviderWithAuthHandler(opts *Options3LO) TokenProvider { + return NewCachedTokenProvider(&tokenProviderWithHandler{opts: opts, state: opts.AuthHandlerOpts.State}, &CachedTokenProviderOptions{ + ExpireEarly: opts.EarlyTokenExpiry, + }) +} + +// exchange handles the final exchange portion of the 3lo flow. Returns a Token, +// refreshToken, and error. +func (o *Options3LO) exchange(ctx context.Context, code string) (*Token, string, error) { + // Build request + v := url.Values{ + "grant_type": {"authorization_code"}, + "code": {code}, + } + if o.RedirectURL != "" { + v.Set("redirect_uri", o.RedirectURL) + } + if o.AuthHandlerOpts != nil && + o.AuthHandlerOpts.PKCEOpts != nil && + o.AuthHandlerOpts.PKCEOpts.Verifier != "" { + v.Set(codeVerifierKey, o.AuthHandlerOpts.PKCEOpts.Verifier) + } + for k := range o.URLParams { + v.Set(k, o.URLParams.Get(k)) + } + return fetchToken(ctx, o, v) +} + +// This struct is not safe for concurrent access alone, but the way it is used +// in this package by wrapping it with a cachedTokenProvider makes it so. +type tokenProvider3LO struct { + opts *Options3LO + client *http.Client + refreshToken string +} + +func (tp *tokenProvider3LO) Token(ctx context.Context) (*Token, error) { + if tp.refreshToken == "" { + return nil, errors.New("auth: token expired and refresh token is not set") + } + v := url.Values{ + "grant_type": {"refresh_token"}, + "refresh_token": {tp.refreshToken}, + } + for k := range tp.opts.URLParams { + v.Set(k, tp.opts.URLParams.Get(k)) + } + + tk, rt, err := fetchToken(ctx, tp.opts, v) + if err != nil { + return nil, err + } + if tp.refreshToken != rt && rt != "" { + tp.refreshToken = rt + } + return tk, err +} + +type tokenProviderWithHandler struct { + opts *Options3LO + state string +} + +func (tp tokenProviderWithHandler) Token(ctx context.Context) (*Token, error) { + url := tp.opts.authCodeURL(tp.state, nil) + code, state, err := tp.opts.AuthHandlerOpts.Handler(url) + if err != nil { + return nil, err + } + if state != tp.state { + return nil, errors.New("auth: state mismatch in 3-legged-OAuth flow") + } + tok, _, err := tp.opts.exchange(ctx, code) + return tok, err +} + +// fetchToken returns a Token, refresh token, and/or an error. +func fetchToken(ctx context.Context, o *Options3LO, v url.Values) (*Token, string, error) { + var refreshToken string + if o.AuthStyle == StyleInParams { + if o.ClientID != "" { + v.Set("client_id", o.ClientID) + } + if o.ClientSecret != "" { + v.Set("client_secret", o.ClientSecret) + } + } + req, err := http.NewRequestWithContext(ctx, "POST", o.TokenURL, strings.NewReader(v.Encode())) + if err != nil { + return nil, refreshToken, err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + if o.AuthStyle == StyleInHeader { + req.SetBasicAuth(url.QueryEscape(o.ClientID), url.QueryEscape(o.ClientSecret)) + } + logger := o.logger() + + logger.DebugContext(ctx, "3LO token request", "request", internallog.HTTPRequest(req, []byte(v.Encode()))) + // Make request + resp, body, err := internal.DoRequest(o.client(), req) + if err != nil { + return nil, refreshToken, err + } + logger.DebugContext(ctx, "3LO token response", "response", internallog.HTTPResponse(resp, body)) + failureStatus := resp.StatusCode < 200 || resp.StatusCode > 299 + tokError := &Error{ + Response: resp, + Body: body, + } + + var token *Token + // errors ignored because of default switch on content + content, _, _ := mime.ParseMediaType(resp.Header.Get("Content-Type")) + switch content { + case "application/x-www-form-urlencoded", "text/plain": + // some endpoints return a query string + vals, err := url.ParseQuery(string(body)) + if err != nil { + if failureStatus { + return nil, refreshToken, tokError + } + return nil, refreshToken, fmt.Errorf("auth: cannot parse response: %w", err) + } + tokError.code = vals.Get("error") + tokError.description = vals.Get("error_description") + tokError.uri = vals.Get("error_uri") + token = &Token{ + Value: vals.Get("access_token"), + Type: vals.Get("token_type"), + Metadata: make(map[string]interface{}, len(vals)), + } + for k, v := range vals { + token.Metadata[k] = v + } + refreshToken = vals.Get("refresh_token") + e := vals.Get("expires_in") + expires, _ := strconv.Atoi(e) + if expires != 0 { + token.Expiry = time.Now().Add(time.Duration(expires) * time.Second) + } + default: + var tj tokenJSON + if err = json.Unmarshal(body, &tj); err != nil { + if failureStatus { + return nil, refreshToken, tokError + } + return nil, refreshToken, fmt.Errorf("auth: cannot parse json: %w", err) + } + tokError.code = tj.ErrorCode + tokError.description = tj.ErrorDescription + tokError.uri = tj.ErrorURI + token = &Token{ + Value: tj.AccessToken, + Type: tj.TokenType, + Expiry: tj.expiry(), + Metadata: make(map[string]interface{}), + } + json.Unmarshal(body, &token.Metadata) // optional field, skip err check + refreshToken = tj.RefreshToken + } + // according to spec, servers should respond status 400 in error case + // https://www.rfc-editor.org/rfc/rfc6749#section-5.2 + // but some unorthodox servers respond 200 in error case + if failureStatus || tokError.code != "" { + return nil, refreshToken, tokError + } + if token.Value == "" { + return nil, refreshToken, errors.New("auth: server response missing access_token") + } + return token, refreshToken, nil +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/CHANGES.md b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/CHANGES.md new file mode 100644 index 000000000..e384683c5 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/CHANGES.md @@ -0,0 +1,115 @@ +# Changes + +## [0.9.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.8.4...compute/metadata/v0.9.0) (2025-09-24) + + +### Features + +* **compute/metadata:** Retry on HTTP 429 ([#12932](https://github.com/googleapis/google-cloud-go/issues/12932)) ([1e91f5c](https://github.com/googleapis/google-cloud-go/commit/1e91f5c07acacd38ecdd4ff3e83e092b745e0bc2)) + +## [0.8.4](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.8.3...compute/metadata/v0.8.4) (2025-09-18) + + +### Bug Fixes + +* **compute/metadata:** Set subClient for UseDefaultClient case ([#12911](https://github.com/googleapis/google-cloud-go/issues/12911)) ([9e2646b](https://github.com/googleapis/google-cloud-go/commit/9e2646b1821231183fd775bb107c062865eeaccd)) + +## [0.8.3](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.8.2...compute/metadata/v0.8.3) (2025-09-17) + + +### Bug Fixes + +* **compute/metadata:** Disable Client timeouts for subscription client ([#12910](https://github.com/googleapis/google-cloud-go/issues/12910)) ([187a58a](https://github.com/googleapis/google-cloud-go/commit/187a58a540494e1e8562b046325b8cad8cf7af4a)) + +## [0.8.2](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.8.1...compute/metadata/v0.8.2) (2025-09-17) + + +### Bug Fixes + +* **compute/metadata:** Racy test and uninitialized subClient ([#12892](https://github.com/googleapis/google-cloud-go/issues/12892)) ([4943ca2](https://github.com/googleapis/google-cloud-go/commit/4943ca2bf83908a23806247bc4252dfb440d09cc)), refs [#12888](https://github.com/googleapis/google-cloud-go/issues/12888) + +## [0.8.1](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.8.0...compute/metadata/v0.8.1) (2025-09-16) + + +### Bug Fixes + +* **compute/metadata:** Use separate client for subscribe methods ([#12885](https://github.com/googleapis/google-cloud-go/issues/12885)) ([76b80f8](https://github.com/googleapis/google-cloud-go/commit/76b80f8df9bf9339d175407e8c15936fe1ac1c9c)) + +## [0.8.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.7.0...compute/metadata/v0.8.0) (2025-08-06) + + +### Features + +* **compute/metadata:** Add Options.UseDefaultClient ([#12657](https://github.com/googleapis/google-cloud-go/issues/12657)) ([1a88209](https://github.com/googleapis/google-cloud-go/commit/1a8820900f20e038291c4bb2c5284a449196e81f)), refs [#11078](https://github.com/googleapis/google-cloud-go/issues/11078) + +## [0.7.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.6.0...compute/metadata/v0.7.0) (2025-05-13) + + +### Features + +* **compute/metadata:** Allow canceling GCE detection ([#11786](https://github.com/googleapis/google-cloud-go/issues/11786)) ([78100fe](https://github.com/googleapis/google-cloud-go/commit/78100fe7e28cd30f1e10b47191ac3c9839663b64)) + +## [0.6.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.5.2...compute/metadata/v0.6.0) (2024-12-13) + + +### Features + +* **compute/metadata:** Add debug logging ([#11078](https://github.com/googleapis/google-cloud-go/issues/11078)) ([a816814](https://github.com/googleapis/google-cloud-go/commit/a81681463906e4473570a2f426eb0dc2de64e53f)) + +## [0.5.2](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.5.1...compute/metadata/v0.5.2) (2024-09-20) + + +### Bug Fixes + +* **compute/metadata:** Close Response Body for failed request ([#10891](https://github.com/googleapis/google-cloud-go/issues/10891)) ([e91d45e](https://github.com/googleapis/google-cloud-go/commit/e91d45e4757a9e354114509ba9800085d9e0ff1f)) + +## [0.5.1](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.5.0...compute/metadata/v0.5.1) (2024-09-12) + + +### Bug Fixes + +* **compute/metadata:** Check error chain for retryable error ([#10840](https://github.com/googleapis/google-cloud-go/issues/10840)) ([2bdedef](https://github.com/googleapis/google-cloud-go/commit/2bdedeff621b223d63cebc4355fcf83bc68412cd)) + +## [0.5.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.4.0...compute/metadata/v0.5.0) (2024-07-10) + + +### Features + +* **compute/metadata:** Add sys check for windows OnGCE ([#10521](https://github.com/googleapis/google-cloud-go/issues/10521)) ([3b9a830](https://github.com/googleapis/google-cloud-go/commit/3b9a83063960d2a2ac20beb47cc15818a68bd302)) + +## [0.4.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.3.0...compute/metadata/v0.4.0) (2024-07-01) + + +### Features + +* **compute/metadata:** Add context for all functions/methods ([#10370](https://github.com/googleapis/google-cloud-go/issues/10370)) ([66b8efe](https://github.com/googleapis/google-cloud-go/commit/66b8efe7ad877e052b2987bb4475477e38c67bb3)) + + +### Documentation + +* **compute/metadata:** Update OnGCE description ([#10408](https://github.com/googleapis/google-cloud-go/issues/10408)) ([6a46dca](https://github.com/googleapis/google-cloud-go/commit/6a46dca4eae4f88ec6f88822e01e5bf8aeca787f)) + +## [0.3.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.2.3...compute/metadata/v0.3.0) (2024-04-15) + + +### Features + +* **compute/metadata:** Add context aware functions ([#9733](https://github.com/googleapis/google-cloud-go/issues/9733)) ([e4eb5b4](https://github.com/googleapis/google-cloud-go/commit/e4eb5b46ee2aec9d2fc18300bfd66015e25a0510)) + +## [0.2.3](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.2.2...compute/metadata/v0.2.3) (2022-12-15) + + +### Bug Fixes + +* **compute/metadata:** Switch DNS lookup to an absolute lookup ([119b410](https://github.com/googleapis/google-cloud-go/commit/119b41060c7895e45e48aee5621ad35607c4d021)), refs [#7165](https://github.com/googleapis/google-cloud-go/issues/7165) + +## [0.2.2](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.2.1...compute/metadata/v0.2.2) (2022-12-01) + + +### Bug Fixes + +* **compute/metadata:** Set IdleConnTimeout for http.Client ([#7084](https://github.com/googleapis/google-cloud-go/issues/7084)) ([766516a](https://github.com/googleapis/google-cloud-go/commit/766516aaf3816bfb3159efeea65aa3d1d205a3e2)), refs [#5430](https://github.com/googleapis/google-cloud-go/issues/5430) + +## [0.1.0] (2022-10-26) + +Initial release of metadata being it's own module. diff --git a/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/LICENSE b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/README.md b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/README.md new file mode 100644 index 000000000..f940fb2c8 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/README.md @@ -0,0 +1,27 @@ +# Compute API + +[![Go Reference](https://pkg.go.dev/badge/cloud.google.com/go/compute.svg)](https://pkg.go.dev/cloud.google.com/go/compute/metadata) + +This is a utility library for communicating with Google Cloud metadata service +on Google Cloud. + +## Install + +```bash +go get cloud.google.com/go/compute/metadata +``` + +## Go Version Support + +See the [Go Versions Supported](https://github.com/googleapis/google-cloud-go#go-versions-supported) +section in the root directory's README. + +## Contributing + +Contributions are welcome. Please, see the [CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md) +document for details. + +Please note that this project is released with a Contributor Code of Conduct. +By participating in this project you agree to abide by its terms. See +[Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md#contributor-code-of-conduct) +for more information. diff --git a/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/log.go b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/log.go new file mode 100644 index 000000000..8ec673b88 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/log.go @@ -0,0 +1,149 @@ +// Copyright 2024 Google LLC +// +// 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 metadata + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "strings" +) + +// Code below this point is copied from github.com/googleapis/gax-go/v2/internallog +// to avoid the dependency. The compute/metadata module is used by too many +// non-client library modules that can't justify the dependency. + +// The handler returned if logging is not enabled. +type noOpHandler struct{} + +func (h noOpHandler) Enabled(_ context.Context, _ slog.Level) bool { + return false +} + +func (h noOpHandler) Handle(_ context.Context, _ slog.Record) error { + return nil +} + +func (h noOpHandler) WithAttrs(_ []slog.Attr) slog.Handler { + return h +} + +func (h noOpHandler) WithGroup(_ string) slog.Handler { + return h +} + +// httpRequest returns a lazily evaluated [slog.LogValuer] for a +// [http.Request] and the associated body. +func httpRequest(req *http.Request, body []byte) slog.LogValuer { + return &request{ + req: req, + payload: body, + } +} + +type request struct { + req *http.Request + payload []byte +} + +func (r *request) LogValue() slog.Value { + if r == nil || r.req == nil { + return slog.Value{} + } + var groupValueAttrs []slog.Attr + groupValueAttrs = append(groupValueAttrs, slog.String("method", r.req.Method)) + groupValueAttrs = append(groupValueAttrs, slog.String("url", r.req.URL.String())) + + var headerAttr []slog.Attr + for k, val := range r.req.Header { + headerAttr = append(headerAttr, slog.String(k, strings.Join(val, ","))) + } + if len(headerAttr) > 0 { + groupValueAttrs = append(groupValueAttrs, slog.Any("headers", headerAttr)) + } + + if len(r.payload) > 0 { + if attr, ok := processPayload(r.payload); ok { + groupValueAttrs = append(groupValueAttrs, attr) + } + } + return slog.GroupValue(groupValueAttrs...) +} + +// httpResponse returns a lazily evaluated [slog.LogValuer] for a +// [http.Response] and the associated body. +func httpResponse(resp *http.Response, body []byte) slog.LogValuer { + return &response{ + resp: resp, + payload: body, + } +} + +type response struct { + resp *http.Response + payload []byte +} + +func (r *response) LogValue() slog.Value { + if r == nil { + return slog.Value{} + } + var groupValueAttrs []slog.Attr + groupValueAttrs = append(groupValueAttrs, slog.String("status", fmt.Sprint(r.resp.StatusCode))) + + var headerAttr []slog.Attr + for k, val := range r.resp.Header { + headerAttr = append(headerAttr, slog.String(k, strings.Join(val, ","))) + } + if len(headerAttr) > 0 { + groupValueAttrs = append(groupValueAttrs, slog.Any("headers", headerAttr)) + } + + if len(r.payload) > 0 { + if attr, ok := processPayload(r.payload); ok { + groupValueAttrs = append(groupValueAttrs, attr) + } + } + return slog.GroupValue(groupValueAttrs...) +} + +func processPayload(payload []byte) (slog.Attr, bool) { + peekChar := payload[0] + if peekChar == '{' { + // JSON object + var m map[string]any + if err := json.Unmarshal(payload, &m); err == nil { + return slog.Any("payload", m), true + } + } else if peekChar == '[' { + // JSON array + var m []any + if err := json.Unmarshal(payload, &m); err == nil { + return slog.Any("payload", m), true + } + } else { + // Everything else + buf := &bytes.Buffer{} + if err := json.Compact(buf, payload); err != nil { + // Write raw payload incase of error + buf.Write(payload) + } + return slog.String("payload", buf.String()), true + } + return slog.Attr{}, false +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/metadata.go b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/metadata.go new file mode 100644 index 000000000..6bd189166 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/metadata.go @@ -0,0 +1,937 @@ +// Copyright 2014 Google LLC +// +// 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 metadata provides access to Google Compute Engine (GCE) +// metadata and API service accounts. +// +// This package is a wrapper around the GCE metadata service, +// as documented at https://cloud.google.com/compute/docs/metadata/overview. +package metadata // import "cloud.google.com/go/compute/metadata" + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net" + "net/http" + "net/url" + "os" + "strings" + "sync" + "time" +) + +const ( + // metadataIP is the documented metadata server IP address. + metadataIP = "169.254.169.254" + + // metadataHostEnv is the environment variable specifying the + // GCE metadata hostname. If empty, the default value of + // metadataIP ("169.254.169.254") is used instead. + // This is variable name is not defined by any spec, as far as + // I know; it was made up for the Go package. + metadataHostEnv = "GCE_METADATA_HOST" + + userAgent = "gcloud-golang/0.1" +) + +type cachedValue struct { + k string + trim bool + mu sync.Mutex + v string +} + +var ( + projID = &cachedValue{k: "project/project-id", trim: true} + projNum = &cachedValue{k: "project/numeric-project-id", trim: true} + instID = &cachedValue{k: "instance/id", trim: true} +) + +var defaultClient = &Client{ + hc: newDefaultHTTPClient(true), + subClient: newDefaultHTTPClient(false), + logger: slog.New(noOpHandler{}), +} + +func newDefaultHTTPClient(enableTimeouts bool) *http.Client { + transport := &http.Transport{ + Dial: (&net.Dialer{ + Timeout: 2 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + } + c := &http.Client{ + Transport: transport, + } + if enableTimeouts { + transport.IdleConnTimeout = 60 * time.Second + c.Timeout = 5 * time.Second + } + return c +} + +// NotDefinedError is returned when requested metadata is not defined. +// +// The underlying string is the suffix after "/computeMetadata/v1/". +// +// This error is not returned if the value is defined to be the empty +// string. +type NotDefinedError string + +func (suffix NotDefinedError) Error() string { + return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix)) +} + +func (c *cachedValue) get(ctx context.Context, cl *Client) (v string, err error) { + defer c.mu.Unlock() + c.mu.Lock() + if c.v != "" { + return c.v, nil + } + if c.trim { + v, err = cl.getTrimmed(ctx, c.k) + } else { + v, err = cl.GetWithContext(ctx, c.k) + } + if err == nil { + c.v = v + } + return +} + +var ( + onGCEOnce sync.Once + onGCE bool +) + +// OnGCE reports whether this process is running on Google Compute Platforms. +// NOTE: True returned from `OnGCE` does not guarantee that the metadata server +// is accessible from this process and have all the metadata defined. +func OnGCE() bool { + return OnGCEWithContext(context.Background()) +} + +// OnGCEWithContext reports whether this process is running on Google Compute Platforms. +// This function's return value is memoized for better performance. +// NOTE: True returned from `OnGCEWithContext` does not guarantee that the metadata server +// is accessible from this process and have all the metadata defined. +func OnGCEWithContext(ctx context.Context) bool { + onGCEOnce.Do(func() { + onGCE = defaultClient.OnGCEWithContext(ctx) + }) + return onGCE +} + +// Subscribe calls Client.SubscribeWithContext on the default client. +// +// Deprecated: Please use the context aware variant [SubscribeWithContext]. +func Subscribe(suffix string, fn func(v string, ok bool) error) error { + return defaultClient.SubscribeWithContext(context.Background(), suffix, func(ctx context.Context, v string, ok bool) error { return fn(v, ok) }) +} + +// SubscribeWithContext calls Client.SubscribeWithContext on the default client. +func SubscribeWithContext(ctx context.Context, suffix string, fn func(ctx context.Context, v string, ok bool) error) error { + return defaultClient.SubscribeWithContext(ctx, suffix, fn) +} + +// Get calls Client.GetWithContext on the default client. +// +// Deprecated: Please use the context aware variant [GetWithContext]. +func Get(suffix string) (string, error) { + return defaultClient.GetWithContext(context.Background(), suffix) +} + +// GetWithContext calls Client.GetWithContext on the default client. +func GetWithContext(ctx context.Context, suffix string) (string, error) { + return defaultClient.GetWithContext(ctx, suffix) +} + +// ProjectID returns the current instance's project ID string. +// +// Deprecated: Please use the context aware variant [ProjectIDWithContext]. +func ProjectID() (string, error) { + return defaultClient.ProjectIDWithContext(context.Background()) +} + +// ProjectIDWithContext returns the current instance's project ID string. +func ProjectIDWithContext(ctx context.Context) (string, error) { + return defaultClient.ProjectIDWithContext(ctx) +} + +// NumericProjectID returns the current instance's numeric project ID. +// +// Deprecated: Please use the context aware variant [NumericProjectIDWithContext]. +func NumericProjectID() (string, error) { + return defaultClient.NumericProjectIDWithContext(context.Background()) +} + +// NumericProjectIDWithContext returns the current instance's numeric project ID. +func NumericProjectIDWithContext(ctx context.Context) (string, error) { + return defaultClient.NumericProjectIDWithContext(ctx) +} + +// InternalIP returns the instance's primary internal IP address. +// +// Deprecated: Please use the context aware variant [InternalIPWithContext]. +func InternalIP() (string, error) { + return defaultClient.InternalIPWithContext(context.Background()) +} + +// InternalIPWithContext returns the instance's primary internal IP address. +func InternalIPWithContext(ctx context.Context) (string, error) { + return defaultClient.InternalIPWithContext(ctx) +} + +// ExternalIP returns the instance's primary external (public) IP address. +// +// Deprecated: Please use the context aware variant [ExternalIPWithContext]. +func ExternalIP() (string, error) { + return defaultClient.ExternalIPWithContext(context.Background()) +} + +// ExternalIPWithContext returns the instance's primary external (public) IP address. +func ExternalIPWithContext(ctx context.Context) (string, error) { + return defaultClient.ExternalIPWithContext(ctx) +} + +// Email calls Client.EmailWithContext on the default client. +// +// Deprecated: Please use the context aware variant [EmailWithContext]. +func Email(serviceAccount string) (string, error) { + return defaultClient.EmailWithContext(context.Background(), serviceAccount) +} + +// EmailWithContext calls Client.EmailWithContext on the default client. +func EmailWithContext(ctx context.Context, serviceAccount string) (string, error) { + return defaultClient.EmailWithContext(ctx, serviceAccount) +} + +// Hostname returns the instance's hostname. This will be of the form +// ".c..internal". +// +// Deprecated: Please use the context aware variant [HostnameWithContext]. +func Hostname() (string, error) { + return defaultClient.HostnameWithContext(context.Background()) +} + +// HostnameWithContext returns the instance's hostname. This will be of the form +// ".c..internal". +func HostnameWithContext(ctx context.Context) (string, error) { + return defaultClient.HostnameWithContext(ctx) +} + +// InstanceTags returns the list of user-defined instance tags, +// assigned when initially creating a GCE instance. +// +// Deprecated: Please use the context aware variant [InstanceTagsWithContext]. +func InstanceTags() ([]string, error) { + return defaultClient.InstanceTagsWithContext(context.Background()) +} + +// InstanceTagsWithContext returns the list of user-defined instance tags, +// assigned when initially creating a GCE instance. +func InstanceTagsWithContext(ctx context.Context) ([]string, error) { + return defaultClient.InstanceTagsWithContext(ctx) +} + +// InstanceID returns the current VM's numeric instance ID. +// +// Deprecated: Please use the context aware variant [InstanceIDWithContext]. +func InstanceID() (string, error) { + return defaultClient.InstanceIDWithContext(context.Background()) +} + +// InstanceIDWithContext returns the current VM's numeric instance ID. +func InstanceIDWithContext(ctx context.Context) (string, error) { + return defaultClient.InstanceIDWithContext(ctx) +} + +// InstanceName returns the current VM's instance ID string. +// +// Deprecated: Please use the context aware variant [InstanceNameWithContext]. +func InstanceName() (string, error) { + return defaultClient.InstanceNameWithContext(context.Background()) +} + +// InstanceNameWithContext returns the current VM's instance ID string. +func InstanceNameWithContext(ctx context.Context) (string, error) { + return defaultClient.InstanceNameWithContext(ctx) +} + +// Zone returns the current VM's zone, such as "us-central1-b". +// +// Deprecated: Please use the context aware variant [ZoneWithContext]. +func Zone() (string, error) { + return defaultClient.ZoneWithContext(context.Background()) +} + +// ZoneWithContext returns the current VM's zone, such as "us-central1-b". +func ZoneWithContext(ctx context.Context) (string, error) { + return defaultClient.ZoneWithContext(ctx) +} + +// InstanceAttributes calls Client.InstanceAttributesWithContext on the default client. +// +// Deprecated: Please use the context aware variant [InstanceAttributesWithContext. +func InstanceAttributes() ([]string, error) { + return defaultClient.InstanceAttributesWithContext(context.Background()) +} + +// InstanceAttributesWithContext calls Client.ProjectAttributesWithContext on the default client. +func InstanceAttributesWithContext(ctx context.Context) ([]string, error) { + return defaultClient.InstanceAttributesWithContext(ctx) +} + +// ProjectAttributes calls Client.ProjectAttributesWithContext on the default client. +// +// Deprecated: Please use the context aware variant [ProjectAttributesWithContext]. +func ProjectAttributes() ([]string, error) { + return defaultClient.ProjectAttributesWithContext(context.Background()) +} + +// ProjectAttributesWithContext calls Client.ProjectAttributesWithContext on the default client. +func ProjectAttributesWithContext(ctx context.Context) ([]string, error) { + return defaultClient.ProjectAttributesWithContext(ctx) +} + +// InstanceAttributeValue calls Client.InstanceAttributeValueWithContext on the default client. +// +// Deprecated: Please use the context aware variant [InstanceAttributeValueWithContext]. +func InstanceAttributeValue(attr string) (string, error) { + return defaultClient.InstanceAttributeValueWithContext(context.Background(), attr) +} + +// InstanceAttributeValueWithContext calls Client.InstanceAttributeValueWithContext on the default client. +func InstanceAttributeValueWithContext(ctx context.Context, attr string) (string, error) { + return defaultClient.InstanceAttributeValueWithContext(ctx, attr) +} + +// ProjectAttributeValue calls Client.ProjectAttributeValueWithContext on the default client. +// +// Deprecated: Please use the context aware variant [ProjectAttributeValueWithContext]. +func ProjectAttributeValue(attr string) (string, error) { + return defaultClient.ProjectAttributeValueWithContext(context.Background(), attr) +} + +// ProjectAttributeValueWithContext calls Client.ProjectAttributeValueWithContext on the default client. +func ProjectAttributeValueWithContext(ctx context.Context, attr string) (string, error) { + return defaultClient.ProjectAttributeValueWithContext(ctx, attr) +} + +// Scopes calls Client.ScopesWithContext on the default client. +// +// Deprecated: Please use the context aware variant [ScopesWithContext]. +func Scopes(serviceAccount string) ([]string, error) { + return defaultClient.ScopesWithContext(context.Background(), serviceAccount) +} + +// ScopesWithContext calls Client.ScopesWithContext on the default client. +func ScopesWithContext(ctx context.Context, serviceAccount string) ([]string, error) { + return defaultClient.ScopesWithContext(ctx, serviceAccount) +} + +func strsContains(ss []string, s string) bool { + for _, v := range ss { + if v == s { + return true + } + } + return false +} + +// A Client provides metadata. +type Client struct { + hc *http.Client + // subClient by default is a HTTP Client that is only used for subscribe + // methods that should not specify a timeout. If the user specifies a client + // this with be the same as 'hc'. + subClient *http.Client + logger *slog.Logger +} + +// Options for configuring a [Client]. +type Options struct { + // Client is the HTTP client used to make requests. Optional. + // If UseDefaultClient is true, this field is ignored. + // If this field is nil, a new default http.Client will be created. + Client *http.Client + // Logger is used to log information about HTTP request and responses. + // If not provided, nothing will be logged. Optional. + Logger *slog.Logger + // UseDefaultClient specifies that the client should use the same default + // internal http.Client that is used in functions such as GetWithContext. + // This is useful for sharing a single TCP connection pool across requests. + // The difference vs GetWithContext is the ability to use this struct + // to provide a custom logger. If this field is true, the Client + // field is ignored. + UseDefaultClient bool +} + +// NewClient returns a Client that can be used to fetch metadata. +// Returns the client that uses the specified http.Client for HTTP requests. +// If nil is specified, returns the default internal Client that is +// also used in functions such as GetWithContext. This is useful for sharing +// a single TCP connection pool across requests. +func NewClient(c *http.Client) *Client { + if c == nil { + // Preserve original behavior for nil argument. + return defaultClient + } + // Return a new client with a no-op logger for backward compatibility. + return &Client{hc: c, subClient: c, logger: slog.New(noOpHandler{})} +} + +// NewWithOptions returns a Client that is configured with the provided Options. +func NewWithOptions(opts *Options) *Client { + // Preserve original behavior for nil opts. + if opts == nil { + return defaultClient + } + + // Handle explicit request for the internal default http.Client. + if opts.UseDefaultClient { + logger := opts.Logger + if logger == nil { + logger = slog.New(noOpHandler{}) + } + return &Client{hc: defaultClient.hc, subClient: defaultClient.subClient, logger: logger} + } + + // Handle isolated client creation. + client := opts.Client + subClient := opts.Client + if client == nil { + client = newDefaultHTTPClient(true) + subClient = newDefaultHTTPClient(false) + } + logger := opts.Logger + if logger == nil { + logger = slog.New(noOpHandler{}) + } + return &Client{hc: client, subClient: subClient, logger: logger} +} + +// NOTE: metadataRequestStrategy is assigned to a variable for test stubbing purposes. +var metadataRequestStrategy = func(ctx context.Context, httpClient *http.Client, resc chan bool) { + req, _ := http.NewRequest("GET", "http://"+metadataIP, nil) + req.Header.Set("User-Agent", userAgent) + res, err := httpClient.Do(req.WithContext(ctx)) + if err != nil { + resc <- false + return + } + defer res.Body.Close() + resc <- res.Header.Get("Metadata-Flavor") == "Google" +} + +// NOTE: dnsRequestStrategy is assigned to a variable for test stubbing purposes. +var dnsRequestStrategy = func(ctx context.Context, resc chan bool) { + resolver := &net.Resolver{} + addrs, err := resolver.LookupHost(ctx, "metadata.google.internal.") + if err != nil || len(addrs) == 0 { + resc <- false + return + } + resc <- strsContains(addrs, metadataIP) +} + +// OnGCEWithContext reports whether this process is running on Google Compute Platforms. +// NOTE: True returned from `OnGCEWithContext` does not guarantee that the metadata server +// is accessible from this process and have all the metadata defined. +func (c *Client) OnGCEWithContext(ctx context.Context) bool { + // The user explicitly said they're on GCE, so trust them. + if os.Getenv(metadataHostEnv) != "" { + return true + } + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + resc := make(chan bool, 2) + + // Try two strategies in parallel. + // See https://github.com/googleapis/google-cloud-go/issues/194 + go metadataRequestStrategy(ctx, c.hc, resc) + go dnsRequestStrategy(ctx, resc) + + tryHarder := systemInfoSuggestsGCE() + if tryHarder { + res := <-resc + if res { + // The first strategy succeeded, so let's use it. + return true + } + + // Wait for either the DNS or metadata server probe to + // contradict the other one and say we are running on + // GCE. Give it a lot of time to do so, since the system + // info already suggests we're running on a GCE BIOS. + // Ensure cancellations from the calling context are respected. + waitContext, cancelWait := context.WithTimeout(ctx, 5*time.Second) + defer cancelWait() + select { + case res = <-resc: + return res + case <-waitContext.Done(): + // Too slow. Who knows what this system is. + return false + } + } + + // There's no hint from the system info that we're running on + // GCE, so use the first probe's result as truth, whether it's + // true or false. The goal here is to optimize for speed for + // users who are NOT running on GCE. We can't assume that + // either a DNS lookup or an HTTP request to a blackholed IP + // address is fast. Worst case this should return when the + // metaClient's Transport.ResponseHeaderTimeout or + // Transport.Dial.Timeout fires (in two seconds). + return <-resc +} + +// getETag returns a value from the metadata service as well as the associated ETag. +// This func is otherwise equivalent to Get. +func (c *Client) getETag(ctx context.Context, suffix string) (value, etag string, err error) { + return c.getETagWithSubClient(ctx, suffix, false) +} + +func (c *Client) getETagWithSubClient(ctx context.Context, suffix string, enableSubClient bool) (value, etag string, err error) { + // Using a fixed IP makes it very difficult to spoof the metadata service in + // a container, which is an important use-case for local testing of cloud + // deployments. To enable spoofing of the metadata service, the environment + // variable GCE_METADATA_HOST is first inspected to decide where metadata + // requests shall go. + host := os.Getenv(metadataHostEnv) + if host == "" { + // Using 169.254.169.254 instead of "metadata" here because Go + // binaries built with the "netgo" tag and without cgo won't + // know the search suffix for "metadata" is + // ".google.internal", and this IP address is documented as + // being stable anyway. + host = metadataIP + } + suffix = strings.TrimLeft(suffix, "/") + u := "http://" + host + "/computeMetadata/v1/" + suffix + req, err := http.NewRequestWithContext(ctx, "GET", u, nil) + if err != nil { + return "", "", err + } + req.Header.Set("Metadata-Flavor", "Google") + req.Header.Set("User-Agent", userAgent) + var res *http.Response + var reqErr error + var body []byte + retryer := newRetryer() + hc := c.hc + if enableSubClient { + hc = c.subClient + } + for { + c.logger.DebugContext(ctx, "metadata request", "request", httpRequest(req, nil)) + res, reqErr = hc.Do(req) + var code int + if res != nil { + code = res.StatusCode + body, err = io.ReadAll(res.Body) + if err != nil { + res.Body.Close() + return "", "", err + } + c.logger.DebugContext(ctx, "metadata response", "response", httpResponse(res, body)) + res.Body.Close() + } + if delay, shouldRetry := retryer.Retry(code, reqErr); shouldRetry { + if res != nil && res.Body != nil { + res.Body.Close() + } + if err := sleep(ctx, delay); err != nil { + return "", "", err + } + continue + } + break + } + if reqErr != nil { + return "", "", reqErr + } + if res.StatusCode == http.StatusNotFound { + return "", "", NotDefinedError(suffix) + } + if res.StatusCode != 200 { + return "", "", &Error{Code: res.StatusCode, Message: string(body)} + } + return string(body), res.Header.Get("Etag"), nil +} + +// Get returns a value from the metadata service. +// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". +// +// If the GCE_METADATA_HOST environment variable is not defined, a default of +// 169.254.169.254 will be used instead. +// +// If the requested metadata is not defined, the returned error will +// be of type NotDefinedError. +// +// Deprecated: Please use the context aware variant [Client.GetWithContext]. +func (c *Client) Get(suffix string) (string, error) { + return c.GetWithContext(context.Background(), suffix) +} + +// GetWithContext returns a value from the metadata service. +// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". +// +// If the GCE_METADATA_HOST environment variable is not defined, a default of +// 169.254.169.254 will be used instead. +// +// If the requested metadata is not defined, the returned error will +// be of type NotDefinedError. +// +// NOTE: Without an extra deadline in the context this call can take in the +// worst case, with internal backoff retries, up to 15 seconds (e.g. when server +// is responding slowly). Pass context with additional timeouts when needed. +func (c *Client) GetWithContext(ctx context.Context, suffix string) (string, error) { + val, _, err := c.getETag(ctx, suffix) + return val, err +} + +func (c *Client) getTrimmed(ctx context.Context, suffix string) (s string, err error) { + s, err = c.GetWithContext(ctx, suffix) + s = strings.TrimSpace(s) + return +} + +func (c *Client) lines(ctx context.Context, suffix string) ([]string, error) { + j, err := c.GetWithContext(ctx, suffix) + if err != nil { + return nil, err + } + s := strings.Split(strings.TrimSpace(j), "\n") + for i := range s { + s[i] = strings.TrimSpace(s[i]) + } + return s, nil +} + +// ProjectID returns the current instance's project ID string. +// +// Deprecated: Please use the context aware variant [Client.ProjectIDWithContext]. +func (c *Client) ProjectID() (string, error) { return c.ProjectIDWithContext(context.Background()) } + +// ProjectIDWithContext returns the current instance's project ID string. +func (c *Client) ProjectIDWithContext(ctx context.Context) (string, error) { return projID.get(ctx, c) } + +// NumericProjectID returns the current instance's numeric project ID. +// +// Deprecated: Please use the context aware variant [Client.NumericProjectIDWithContext]. +func (c *Client) NumericProjectID() (string, error) { + return c.NumericProjectIDWithContext(context.Background()) +} + +// NumericProjectIDWithContext returns the current instance's numeric project ID. +func (c *Client) NumericProjectIDWithContext(ctx context.Context) (string, error) { + return projNum.get(ctx, c) +} + +// InstanceID returns the current VM's numeric instance ID. +// +// Deprecated: Please use the context aware variant [Client.InstanceIDWithContext]. +func (c *Client) InstanceID() (string, error) { + return c.InstanceIDWithContext(context.Background()) +} + +// InstanceIDWithContext returns the current VM's numeric instance ID. +func (c *Client) InstanceIDWithContext(ctx context.Context) (string, error) { + return instID.get(ctx, c) +} + +// InternalIP returns the instance's primary internal IP address. +// +// Deprecated: Please use the context aware variant [Client.InternalIPWithContext]. +func (c *Client) InternalIP() (string, error) { + return c.InternalIPWithContext(context.Background()) +} + +// InternalIPWithContext returns the instance's primary internal IP address. +func (c *Client) InternalIPWithContext(ctx context.Context) (string, error) { + return c.getTrimmed(ctx, "instance/network-interfaces/0/ip") +} + +// Email returns the email address associated with the service account. +// +// Deprecated: Please use the context aware variant [Client.EmailWithContext]. +func (c *Client) Email(serviceAccount string) (string, error) { + return c.EmailWithContext(context.Background(), serviceAccount) +} + +// EmailWithContext returns the email address associated with the service account. +// The serviceAccount parameter default value (empty string or "default" value) +// will use the instance's main account. +func (c *Client) EmailWithContext(ctx context.Context, serviceAccount string) (string, error) { + if serviceAccount == "" { + serviceAccount = "default" + } + return c.getTrimmed(ctx, "instance/service-accounts/"+serviceAccount+"/email") +} + +// ExternalIP returns the instance's primary external (public) IP address. +// +// Deprecated: Please use the context aware variant [Client.ExternalIPWithContext]. +func (c *Client) ExternalIP() (string, error) { + return c.ExternalIPWithContext(context.Background()) +} + +// ExternalIPWithContext returns the instance's primary external (public) IP address. +func (c *Client) ExternalIPWithContext(ctx context.Context) (string, error) { + return c.getTrimmed(ctx, "instance/network-interfaces/0/access-configs/0/external-ip") +} + +// Hostname returns the instance's hostname. This will be of the form +// ".c..internal". +// +// Deprecated: Please use the context aware variant [Client.HostnameWithContext]. +func (c *Client) Hostname() (string, error) { + return c.HostnameWithContext(context.Background()) +} + +// HostnameWithContext returns the instance's hostname. This will be of the form +// ".c..internal". +func (c *Client) HostnameWithContext(ctx context.Context) (string, error) { + return c.getTrimmed(ctx, "instance/hostname") +} + +// InstanceTags returns the list of user-defined instance tags. +// +// Deprecated: Please use the context aware variant [Client.InstanceTagsWithContext]. +func (c *Client) InstanceTags() ([]string, error) { + return c.InstanceTagsWithContext(context.Background()) +} + +// InstanceTagsWithContext returns the list of user-defined instance tags, +// assigned when initially creating a GCE instance. +func (c *Client) InstanceTagsWithContext(ctx context.Context) ([]string, error) { + var s []string + j, err := c.GetWithContext(ctx, "instance/tags") + if err != nil { + return nil, err + } + if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil { + return nil, err + } + return s, nil +} + +// InstanceName returns the current VM's instance ID string. +// +// Deprecated: Please use the context aware variant [Client.InstanceNameWithContext]. +func (c *Client) InstanceName() (string, error) { + return c.InstanceNameWithContext(context.Background()) +} + +// InstanceNameWithContext returns the current VM's instance ID string. +func (c *Client) InstanceNameWithContext(ctx context.Context) (string, error) { + return c.getTrimmed(ctx, "instance/name") +} + +// Zone returns the current VM's zone, such as "us-central1-b". +// +// Deprecated: Please use the context aware variant [Client.ZoneWithContext]. +func (c *Client) Zone() (string, error) { + return c.ZoneWithContext(context.Background()) +} + +// ZoneWithContext returns the current VM's zone, such as "us-central1-b". +func (c *Client) ZoneWithContext(ctx context.Context) (string, error) { + zone, err := c.getTrimmed(ctx, "instance/zone") + // zone is of the form "projects//zones/". + if err != nil { + return "", err + } + return zone[strings.LastIndex(zone, "/")+1:], nil +} + +// InstanceAttributes returns the list of user-defined attributes, +// assigned when initially creating a GCE VM instance. The value of an +// attribute can be obtained with InstanceAttributeValue. +// +// Deprecated: Please use the context aware variant [Client.InstanceAttributesWithContext]. +func (c *Client) InstanceAttributes() ([]string, error) { + return c.InstanceAttributesWithContext(context.Background()) +} + +// InstanceAttributesWithContext returns the list of user-defined attributes, +// assigned when initially creating a GCE VM instance. The value of an +// attribute can be obtained with InstanceAttributeValue. +func (c *Client) InstanceAttributesWithContext(ctx context.Context) ([]string, error) { + return c.lines(ctx, "instance/attributes/") +} + +// ProjectAttributes returns the list of user-defined attributes +// applying to the project as a whole, not just this VM. The value of +// an attribute can be obtained with ProjectAttributeValue. +// +// Deprecated: Please use the context aware variant [Client.ProjectAttributesWithContext]. +func (c *Client) ProjectAttributes() ([]string, error) { + return c.ProjectAttributesWithContext(context.Background()) +} + +// ProjectAttributesWithContext returns the list of user-defined attributes +// applying to the project as a whole, not just this VM. The value of +// an attribute can be obtained with ProjectAttributeValue. +func (c *Client) ProjectAttributesWithContext(ctx context.Context) ([]string, error) { + return c.lines(ctx, "project/attributes/") +} + +// InstanceAttributeValue returns the value of the provided VM +// instance attribute. +// +// If the requested attribute is not defined, the returned error will +// be of type NotDefinedError. +// +// InstanceAttributeValue may return ("", nil) if the attribute was +// defined to be the empty string. +// +// Deprecated: Please use the context aware variant [Client.InstanceAttributeValueWithContext]. +func (c *Client) InstanceAttributeValue(attr string) (string, error) { + return c.InstanceAttributeValueWithContext(context.Background(), attr) +} + +// InstanceAttributeValueWithContext returns the value of the provided VM +// instance attribute. +// +// If the requested attribute is not defined, the returned error will +// be of type NotDefinedError. +// +// InstanceAttributeValue may return ("", nil) if the attribute was +// defined to be the empty string. +func (c *Client) InstanceAttributeValueWithContext(ctx context.Context, attr string) (string, error) { + return c.GetWithContext(ctx, "instance/attributes/"+attr) +} + +// ProjectAttributeValue returns the value of the provided +// project attribute. +// +// If the requested attribute is not defined, the returned error will +// be of type NotDefinedError. +// +// ProjectAttributeValue may return ("", nil) if the attribute was +// defined to be the empty string. +// +// Deprecated: Please use the context aware variant [Client.ProjectAttributeValueWithContext]. +func (c *Client) ProjectAttributeValue(attr string) (string, error) { + return c.ProjectAttributeValueWithContext(context.Background(), attr) +} + +// ProjectAttributeValueWithContext returns the value of the provided +// project attribute. +// +// If the requested attribute is not defined, the returned error will +// be of type NotDefinedError. +// +// ProjectAttributeValue may return ("", nil) if the attribute was +// defined to be the empty string. +func (c *Client) ProjectAttributeValueWithContext(ctx context.Context, attr string) (string, error) { + return c.GetWithContext(ctx, "project/attributes/"+attr) +} + +// Scopes returns the service account scopes for the given account. +// The account may be empty or the string "default" to use the instance's +// main account. +// +// Deprecated: Please use the context aware variant [Client.ScopesWithContext]. +func (c *Client) Scopes(serviceAccount string) ([]string, error) { + return c.ScopesWithContext(context.Background(), serviceAccount) +} + +// ScopesWithContext returns the service account scopes for the given account. +// The account may be empty or the string "default" to use the instance's +// main account. +func (c *Client) ScopesWithContext(ctx context.Context, serviceAccount string) ([]string, error) { + if serviceAccount == "" { + serviceAccount = "default" + } + return c.lines(ctx, "instance/service-accounts/"+serviceAccount+"/scopes") +} + +// Subscribe subscribes to a value from the metadata service. +// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". +// The suffix may contain query parameters. +// +// Deprecated: Please use the context aware variant [Client.SubscribeWithContext]. +func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) error { + return c.SubscribeWithContext(context.Background(), suffix, func(ctx context.Context, v string, ok bool) error { return fn(v, ok) }) +} + +// SubscribeWithContext subscribes to a value from the metadata service. +// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". +// The suffix may contain query parameters. +// +// SubscribeWithContext calls fn with the latest metadata value indicated by the +// provided suffix. If the metadata value is deleted, fn is called with the +// empty string and ok false. Subscribe blocks until fn returns a non-nil error +// or the value is deleted. Subscribe returns the error value returned from the +// last call to fn, which may be nil when ok == false. +func (c *Client) SubscribeWithContext(ctx context.Context, suffix string, fn func(ctx context.Context, v string, ok bool) error) error { + const failedSubscribeSleep = time.Second * 5 + + // First check to see if the metadata value exists at all. + val, lastETag, err := c.getETagWithSubClient(ctx, suffix, true) + if err != nil { + return err + } + + if err := fn(ctx, val, true); err != nil { + return err + } + + ok := true + if strings.ContainsRune(suffix, '?') { + suffix += "&wait_for_change=true&last_etag=" + } else { + suffix += "?wait_for_change=true&last_etag=" + } + for { + val, etag, err := c.getETagWithSubClient(ctx, suffix+url.QueryEscape(lastETag), true) + if err != nil { + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return err + } + if _, deleted := err.(NotDefinedError); !deleted { + time.Sleep(failedSubscribeSleep) + continue // Retry on other errors. + } + ok = false + } + lastETag = etag + + if err := fn(ctx, val, ok); err != nil || !ok { + return err + } + } +} + +// Error contains an error response from the server. +type Error struct { + // Code is the HTTP response status code. + Code int + // Message is the server response message. + Message string +} + +func (e *Error) Error() string { + return fmt.Sprintf("compute: Received %d `%s`", e.Code, e.Message) +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/retry.go b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/retry.go new file mode 100644 index 000000000..d516f30f8 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/retry.go @@ -0,0 +1,117 @@ +// Copyright 2021 Google LLC +// +// 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 metadata + +import ( + "context" + "io" + "math/rand" + "net/http" + "time" +) + +const ( + maxRetryAttempts = 5 +) + +var ( + syscallRetryable = func(error) bool { return false } +) + +// defaultBackoff is basically equivalent to gax.Backoff without the need for +// the dependency. +type defaultBackoff struct { + max time.Duration + mul float64 + cur time.Duration +} + +func (b *defaultBackoff) Pause() time.Duration { + d := time.Duration(1 + rand.Int63n(int64(b.cur))) + b.cur = time.Duration(float64(b.cur) * b.mul) + if b.cur > b.max { + b.cur = b.max + } + return d +} + +// sleep is the equivalent of gax.Sleep without the need for the dependency. +func sleep(ctx context.Context, d time.Duration) error { + t := time.NewTimer(d) + select { + case <-ctx.Done(): + t.Stop() + return ctx.Err() + case <-t.C: + return nil + } +} + +func newRetryer() *metadataRetryer { + return &metadataRetryer{bo: &defaultBackoff{ + cur: 100 * time.Millisecond, + max: 30 * time.Second, + mul: 2, + }} +} + +type backoff interface { + Pause() time.Duration +} + +type metadataRetryer struct { + bo backoff + attempts int +} + +func (r *metadataRetryer) Retry(status int, err error) (time.Duration, bool) { + if status == http.StatusOK { + return 0, false + } + retryOk := shouldRetry(status, err) + if !retryOk { + return 0, false + } + if r.attempts == maxRetryAttempts { + return 0, false + } + r.attempts++ + return r.bo.Pause(), true +} + +func shouldRetry(status int, err error) bool { + if 500 <= status && status <= 599 { + return true + } + if status == http.StatusTooManyRequests { + return true + } + if err == io.ErrUnexpectedEOF { + return true + } + // Transient network errors should be retried. + if syscallRetryable(err) { + return true + } + if err, ok := err.(interface{ Temporary() bool }); ok { + if err.Temporary() { + return true + } + } + if err, ok := err.(interface{ Unwrap() error }); ok { + return shouldRetry(status, err.Unwrap()) + } + return false +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/retry_linux.go b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/retry_linux.go new file mode 100644 index 000000000..2e53f0123 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/retry_linux.go @@ -0,0 +1,31 @@ +// Copyright 2021 Google LLC +// +// 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. + +//go:build linux +// +build linux + +package metadata + +import ( + "errors" + "syscall" +) + +func init() { + // Initialize syscallRetryable to return true on transient socket-level + // errors. These errors are specific to Linux. + syscallRetryable = func(err error) bool { + return errors.Is(err, syscall.ECONNRESET) || errors.Is(err, syscall.ECONNREFUSED) + } +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/syscheck.go b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/syscheck.go new file mode 100644 index 000000000..d57ae1b27 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/syscheck.go @@ -0,0 +1,28 @@ +// Copyright 2024 Google LLC +// +// 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. + +//go:build !windows && !linux + +package metadata + +// systemInfoSuggestsGCE reports whether the local system (without +// doing network requests) suggests that we're running on GCE. If this +// returns true, testOnGCE tries a bit harder to reach its metadata +// server. +// +// NOTE: systemInfoSuggestsGCE is assigned to a varible for test stubbing purposes. +var systemInfoSuggestsGCE = func() bool { + // We don't currently have checks for other GOOS + return false +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/syscheck_linux.go b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/syscheck_linux.go new file mode 100644 index 000000000..17ba5a3a2 --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/syscheck_linux.go @@ -0,0 +1,30 @@ +// Copyright 2024 Google LLC +// +// 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. + +//go:build linux + +package metadata + +import ( + "os" + "strings" +) + +// NOTE: systemInfoSuggestsGCE is assigned to a varible for test stubbing purposes. +var systemInfoSuggestsGCE = func() bool { + b, _ := os.ReadFile("/sys/class/dmi/id/product_name") + + name := strings.TrimSpace(string(b)) + return name == "Google" || name == "Google Compute Engine" +} diff --git a/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/syscheck_windows.go b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/syscheck_windows.go new file mode 100644 index 000000000..f57a5b14e --- /dev/null +++ b/plugins/traefik/vendor/cloud.google.com/go/compute/metadata/syscheck_windows.go @@ -0,0 +1,39 @@ +// Copyright 2024 Google LLC +// +// 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. + +//go:build windows + +package metadata + +import ( + "strings" + + "golang.org/x/sys/windows/registry" +) + +// NOTE: systemInfoSuggestsGCE is assigned to a varible for test stubbing purposes. +var systemInfoSuggestsGCE = func() bool { + k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\HardwareConfig\Current`, registry.QUERY_VALUE) + if err != nil { + return false + } + defer k.Close() + + s, _, err := k.GetStringValue("SystemProductName") + if err != nil { + return false + } + s = strings.TrimSpace(s) + return strings.HasPrefix(s, "Google") +} diff --git a/plugins/traefik/vendor/dario.cat/mergo/FUNDING.json b/plugins/traefik/vendor/dario.cat/mergo/FUNDING.json new file mode 100644 index 000000000..0585e1fe1 --- /dev/null +++ b/plugins/traefik/vendor/dario.cat/mergo/FUNDING.json @@ -0,0 +1,7 @@ +{ + "drips": { + "ethereum": { + "ownedBy": "0x6160020e7102237aC41bdb156e94401692D76930" + } + } +} diff --git a/plugins/traefik/vendor/dario.cat/mergo/README.md b/plugins/traefik/vendor/dario.cat/mergo/README.md index 0b3c48889..0e4a59afd 100644 --- a/plugins/traefik/vendor/dario.cat/mergo/README.md +++ b/plugins/traefik/vendor/dario.cat/mergo/README.md @@ -85,7 +85,6 @@ Mergo is used by [thousands](https://deps.dev/go/dario.cat%2Fmergo/v1.0.0/depend * [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser) * [go-micro/go-micro](https://github.com/go-micro/go-micro) * [grafana/loki](https://github.com/grafana/loki) -* [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) * [masterminds/sprig](github.com/Masterminds/sprig) * [moby/moby](https://github.com/moby/moby) * [slackhq/nebula](https://github.com/slackhq/nebula) @@ -191,10 +190,6 @@ func main() { } ``` -Note: if test are failing due missing package, please execute: - - go get gopkg.in/yaml.v3 - ### Transformers Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`? diff --git a/plugins/traefik/vendor/dario.cat/mergo/SECURITY.md b/plugins/traefik/vendor/dario.cat/mergo/SECURITY.md index a5de61f77..3788fcc1c 100644 --- a/plugins/traefik/vendor/dario.cat/mergo/SECURITY.md +++ b/plugins/traefik/vendor/dario.cat/mergo/SECURITY.md @@ -4,8 +4,8 @@ | Version | Supported | | ------- | ------------------ | -| 0.3.x | :white_check_mark: | -| < 0.3 | :x: | +| 1.x.x | :white_check_mark: | +| < 1.0 | :x: | ## Security contact information diff --git a/plugins/traefik/vendor/filippo.io/bigmod/LICENSE b/plugins/traefik/vendor/filippo.io/bigmod/LICENSE new file mode 100644 index 000000000..6a66aea5e --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/plugins/traefik/vendor/filippo.io/bigmod/README.md b/plugins/traefik/vendor/filippo.io/bigmod/README.md new file mode 100644 index 000000000..fbacbddfe --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/README.md @@ -0,0 +1,9 @@ +Package bigmod implements constant-time big integer arithmetic modulo large +moduli. Unlike math/big, this package is suitable for implementing +security-sensitive cryptographic operations. It is a re-exported version the +standard library package crypto/internal/fips140/bigmod used to implement +crypto/rsa amongst others. + +v0.1.0 is up to date with Go 1.24. + +The API is NOT stable. diff --git a/plugins/traefik/vendor/filippo.io/bigmod/nat.go b/plugins/traefik/vendor/filippo.io/bigmod/nat.go new file mode 100644 index 000000000..67f721a5e --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/nat.go @@ -0,0 +1,1241 @@ +// Copyright 2021 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 bigmod implements constant-time big integer arithmetic modulo large +// moduli. Unlike math/big, this package is suitable for implementing +// security-sensitive cryptographic operations. It is a re-exported version the +// standard library package crypto/internal/fips140/bigmod used to implement +// crypto/rsa amongst others. +// +// The API is NOT stable. The caller is responsible for ensuring that Nats are +// reduced modulo the Modulus they are used with. +package bigmod + +import ( + "encoding/binary" + "errors" + "math/bits" +) + +const ( + // _W is the size in bits of our limbs. + _W = bits.UintSize + // _S is the size in bytes of our limbs. + _S = _W / 8 +) + +// Note: These functions make many loops over all the words in a Nat. +// These loops used to be in assembly, invisible to -race, -asan, and -msan, +// but now they are in Go and incur significant overhead in those modes. +// To bring the old performance back, we mark all functions that loop +// over Nat words with //go:norace. Because //go:norace does not +// propagate across inlining, we must also mark functions that inline +// //go:norace functions - specifically, those that inline add, addMulVVW, +// assign, cmpGeq, rshift1, and sub. + +// choice represents a constant-time boolean. The value of choice is always +// either 1 or 0. We use an int instead of bool in order to make decisions in +// constant time by turning it into a mask. +type choice uint + +func not(c choice) choice { return 1 ^ c } + +const yes = choice(1) +const no = choice(0) + +// ctMask is all 1s if on is yes, and all 0s otherwise. +func ctMask(on choice) uint { return -uint(on) } + +// ctEq returns 1 if x == y, and 0 otherwise. The execution time of this +// function does not depend on its inputs. +func ctEq(x, y uint) choice { + // If x != y, then either x - y or y - x will generate a carry. + _, c1 := bits.Sub(x, y, 0) + _, c2 := bits.Sub(y, x, 0) + return not(choice(c1 | c2)) +} + +// Nat represents an arbitrary natural number +// +// Each Nat has an announced length, which is the number of limbs it has stored. +// Operations on this number are allowed to leak this length, but will not leak +// any information about the values contained in those limbs. +type Nat struct { + // limbs is little-endian in base 2^W with W = bits.UintSize. + limbs []uint +} + +// preallocTarget is the size in bits of the numbers used to implement the most +// common and most performant RSA key size. It's also enough to cover some of +// the operations of key sizes up to 4096. +const preallocTarget = 2048 +const preallocLimbs = (preallocTarget + _W - 1) / _W + +// NewNat returns a new nat with a size of zero, just like new(Nat), but with +// the preallocated capacity to hold a number of up to 2048 bits. +// NewNat inlines, so the allocation can live on the stack. +func NewNat() *Nat { + limbs := make([]uint, 0, preallocLimbs) + return &Nat{limbs} +} + +// expand expands x to n limbs, leaving its value unchanged. +func (x *Nat) expand(n int) *Nat { + if len(x.limbs) > n { + panic("bigmod: internal error: shrinking nat") + } + if cap(x.limbs) < n { + newLimbs := make([]uint, n) + copy(newLimbs, x.limbs) + x.limbs = newLimbs + return x + } + extraLimbs := x.limbs[len(x.limbs):n] + clear(extraLimbs) + x.limbs = x.limbs[:n] + return x +} + +// reset returns a zero nat of n limbs, reusing x's storage if n <= cap(x.limbs). +func (x *Nat) reset(n int) *Nat { + if cap(x.limbs) < n { + x.limbs = make([]uint, n) + return x + } + // Clear both the returned limbs and the previously used ones. + clear(x.limbs[:max(n, len(x.limbs))]) + x.limbs = x.limbs[:n] + return x +} + +// resetToBytes assigns x = b, where b is a slice of big-endian bytes, resizing +// n to the appropriate size. +// +// The announced length of x is set based on the actual bit size of the input, +// ignoring leading zeroes. +func (x *Nat) resetToBytes(b []byte) *Nat { + x.reset((len(b) + _S - 1) / _S) + if err := x.setBytes(b); err != nil { + panic("bigmod: internal error: bad arithmetic") + } + return x.trim() +} + +// trim reduces the size of x to match its value. +func (x *Nat) trim() *Nat { + // Trim most significant (trailing in little-endian) zero limbs. + // We assume comparison with zero (but not the branch) is constant time. + for i := len(x.limbs) - 1; i >= 0; i-- { + if x.limbs[i] != 0 { + break + } + x.limbs = x.limbs[:i] + } + return x +} + +// set assigns x = y, optionally resizing x to the appropriate size. +func (x *Nat) set(y *Nat) *Nat { + x.reset(len(y.limbs)) + copy(x.limbs, y.limbs) + return x +} + +// Bits returns x as a little-endian slice of uint. The length of the slice +// matches the announced length of x. The result and x share the same underlying +// array. +func (x *Nat) Bits() []uint { + return x.limbs +} + +// Bytes returns x as a zero-extended big-endian byte slice. The size of the +// slice will match the size of m. +// +// x must have the same size as m and it must be less than or equal to m. +func (x *Nat) Bytes(m *Modulus) []byte { + i := m.Size() + bytes := make([]byte, i) + for _, limb := range x.limbs { + for j := 0; j < _S; j++ { + i-- + if i < 0 { + if limb == 0 { + break + } + panic("bigmod: modulus is smaller than nat") + } + bytes[i] = byte(limb) + limb >>= 8 + } + } + return bytes +} + +// SetBytes assigns x = b, where b is a slice of big-endian bytes. +// SetBytes returns an error if b >= m. +// +// The output will be resized to the size of m and overwritten. +// +//go:norace +func (x *Nat) SetBytes(b []byte, m *Modulus) (*Nat, error) { + x.resetFor(m) + if err := x.setBytes(b); err != nil { + return nil, err + } + if x.cmpGeq(m.nat) == yes { + return nil, errors.New("input overflows the modulus") + } + return x, nil +} + +// SetOverflowingBytes assigns x = b, where b is a slice of big-endian bytes. +// SetOverflowingBytes returns an error if b has a longer bit length than m, but +// reduces overflowing values up to 2^⌈log2(m)⌉ - 1. +// +// The output will be resized to the size of m and overwritten. +func (x *Nat) SetOverflowingBytes(b []byte, m *Modulus) (*Nat, error) { + x.resetFor(m) + if err := x.setBytes(b); err != nil { + return nil, err + } + // setBytes would have returned an error if the input overflowed the limb + // size of the modulus, so now we only need to check if the most significant + // limb of x has more bits than the most significant limb of the modulus. + if bitLen(x.limbs[len(x.limbs)-1]) > bitLen(m.nat.limbs[len(m.nat.limbs)-1]) { + return nil, errors.New("input overflows the modulus size") + } + x.maybeSubtractModulus(no, m) + return x, nil +} + +// bigEndianUint returns the contents of buf interpreted as a +// big-endian encoded uint value. +func bigEndianUint(buf []byte) uint { + if _W == 64 { + return uint(binary.BigEndian.Uint64(buf)) + } + return uint(binary.BigEndian.Uint32(buf)) +} + +func (x *Nat) setBytes(b []byte) error { + i, k := len(b), 0 + for k < len(x.limbs) && i >= _S { + x.limbs[k] = bigEndianUint(b[i-_S : i]) + i -= _S + k++ + } + for s := 0; s < _W && k < len(x.limbs) && i > 0; s += 8 { + x.limbs[k] |= uint(b[i-1]) << s + i-- + } + if i > 0 { + return errors.New("input overflows the modulus size") + } + return nil +} + +// SetUint assigns x = y. +// +// The output will be resized to a single limb and overwritten. +func (x *Nat) SetUint(y uint) *Nat { + x.reset(1) + x.limbs[0] = y + return x +} + +// Equal returns 1 if x == y, and 0 otherwise. +// +// Both operands must have the same announced length. +// +//go:norace +func (x *Nat) Equal(y *Nat) uint { + // Eliminate bounds checks in the loop. + size := len(x.limbs) + xLimbs := x.limbs[:size] + yLimbs := y.limbs[:size] + + equal := yes + for i := 0; i < size; i++ { + equal &= ctEq(xLimbs[i], yLimbs[i]) + } + return uint(equal) +} + +// IsZero returns 1 if x == 0, and 0 otherwise. +// +//go:norace +func (x *Nat) IsZero() uint { + // Eliminate bounds checks in the loop. + size := len(x.limbs) + xLimbs := x.limbs[:size] + + zero := yes + for i := 0; i < size; i++ { + zero &= ctEq(xLimbs[i], 0) + } + return uint(zero) +} + +// IsOne returns 1 if x == 1, and 0 otherwise. +// +//go:norace +func (x *Nat) IsOne() uint { + // Eliminate bounds checks in the loop. + size := len(x.limbs) + xLimbs := x.limbs[:size] + + if len(xLimbs) == 0 { + return uint(no) + } + + one := ctEq(xLimbs[0], 1) + for i := 1; i < size; i++ { + one &= ctEq(xLimbs[i], 0) + } + return uint(one) +} + +// IsMinusOne returns 1 if x == -1 mod m, and 0 otherwise. +// +// The length of x must be the same as the modulus. x must already be reduced +// modulo m. +// +//go:norace +func (x *Nat) IsMinusOne(m *Modulus) uint { + minusOne := m.Nat() + minusOne.SubOne(m) + return x.Equal(minusOne) +} + +// IsOdd returns 1 if x is odd, and 0 otherwise. +func (x *Nat) IsOdd() uint { + if len(x.limbs) == 0 { + return uint(no) + } + return uint(x.limbs[0] & 1) +} + +// TrailingZeroBitsVarTime returns the number of trailing zero bits in x. +func (x *Nat) TrailingZeroBitsVarTime() uint { + var t uint + limbs := x.limbs + for _, l := range limbs { + if l == 0 { + t += _W + continue + } + t += uint(bits.TrailingZeros(l)) + break + } + return t +} + +// cmpGeq returns 1 if x >= y, and 0 otherwise. +// +// Both operands must have the same announced length. +// +//go:norace +func (x *Nat) cmpGeq(y *Nat) choice { + // Eliminate bounds checks in the loop. + size := len(x.limbs) + xLimbs := x.limbs[:size] + yLimbs := y.limbs[:size] + + var c uint + for i := 0; i < size; i++ { + _, c = bits.Sub(xLimbs[i], yLimbs[i], c) + } + // If there was a carry, then subtracting y underflowed, so + // x is not greater than or equal to y. + return not(choice(c)) +} + +// assign sets x <- y if on == 1, and does nothing otherwise. +// +// Both operands must have the same announced length. +// +//go:norace +func (x *Nat) assign(on choice, y *Nat) *Nat { + // Eliminate bounds checks in the loop. + size := len(x.limbs) + xLimbs := x.limbs[:size] + yLimbs := y.limbs[:size] + + mask := ctMask(on) + for i := 0; i < size; i++ { + xLimbs[i] ^= mask & (xLimbs[i] ^ yLimbs[i]) + } + return x +} + +// add computes x += y and returns the carry. +// +// Both operands must have the same announced length. +// +//go:norace +func (x *Nat) add(y *Nat) (c uint) { + // Eliminate bounds checks in the loop. + size := len(x.limbs) + xLimbs := x.limbs[:size] + yLimbs := y.limbs[:size] + + for i := 0; i < size; i++ { + xLimbs[i], c = bits.Add(xLimbs[i], yLimbs[i], c) + } + return +} + +// sub computes x -= y. It returns the borrow of the subtraction. +// +// Both operands must have the same announced length. +// +//go:norace +func (x *Nat) sub(y *Nat) (c uint) { + // Eliminate bounds checks in the loop. + size := len(x.limbs) + xLimbs := x.limbs[:size] + yLimbs := y.limbs[:size] + + for i := 0; i < size; i++ { + xLimbs[i], c = bits.Sub(xLimbs[i], yLimbs[i], c) + } + return +} + +// ShiftRightVarTime sets x = x >> n. +// +// The announced length of x is unchanged. +// +//go:norace +func (x *Nat) ShiftRightVarTime(n uint) *Nat { + // Eliminate bounds checks in the loop. + size := len(x.limbs) + xLimbs := x.limbs[:size] + + shift := int(n % _W) + shiftLimbs := int(n / _W) + + var shiftedLimbs []uint + if shiftLimbs < size { + shiftedLimbs = xLimbs[shiftLimbs:] + } + + for i := range xLimbs { + if i >= len(shiftedLimbs) { + xLimbs[i] = 0 + continue + } + + xLimbs[i] = shiftedLimbs[i] >> shift + if i+1 < len(shiftedLimbs) { + xLimbs[i] |= shiftedLimbs[i+1] << (_W - shift) + } + } + + return x +} + +// BitLenVarTime returns the actual size of x in bits. +// +// The actual size of x (but nothing more) leaks through timing side-channels. +// Note that this is ordinarily secret, as opposed to the announced size of x. +func (x *Nat) BitLenVarTime() int { + // Eliminate bounds checks in the loop. + size := len(x.limbs) + xLimbs := x.limbs[:size] + + for i := size - 1; i >= 0; i-- { + if xLimbs[i] != 0 { + return i*_W + bitLen(xLimbs[i]) + } + } + return 0 +} + +// bitLen is a version of bits.Len that only leaks the bit length of n, but not +// its value. bits.Len and bits.LeadingZeros use a lookup table for the +// low-order bits on some architectures. +func bitLen(n uint) int { + len := 0 + // We assume, here and elsewhere, that comparison to zero is constant time + // with respect to different non-zero values. + for n != 0 { + len++ + n >>= 1 + } + return len +} + +// Modulus is used for modular arithmetic, precomputing relevant constants. +// +// A Modulus can leak the exact number of bits needed to store its value +// and is stored without padding. Its actual value is still kept secret. +type Modulus struct { + // The underlying natural number for this modulus. + // + // This will be stored without any padding, and shouldn't alias with any + // other natural number being used. + nat *Nat + + // If m is even, the following fields are not set. + odd bool + m0inv uint // -nat.limbs[0]⁻¹ mod _W + rr *Nat // R*R for montgomeryRepresentation +} + +// rr returns R*R with R = 2^(_W * n) and n = len(m.nat.limbs). +func rr(m *Modulus) *Nat { + rr := NewNat().ExpandFor(m) + n := uint(len(rr.limbs)) + mLen := uint(m.BitLen()) + logR := _W * n + + // We start by computing R = 2^(_W * n) mod m. We can get pretty close, to + // 2^⌊log₂m⌋, by setting the highest bit we can without having to reduce. + rr.limbs[n-1] = 1 << ((mLen - 1) % _W) + // Then we double until we reach 2^(_W * n). + for i := mLen - 1; i < logR; i++ { + rr.Add(rr, m) + } + + // Next we need to get from R to 2^(_W * n) R mod m (aka from one to R in + // the Montgomery domain, meaning we can use Montgomery multiplication now). + // We could do that by doubling _W * n times, or with a square-and-double + // chain log2(_W * n) long. Turns out the fastest thing is to start out with + // doublings, and switch to square-and-double once the exponent is large + // enough to justify the cost of the multiplications. + + // The threshold is selected experimentally as a linear function of n. + threshold := n / 4 + + // We calculate how many of the most-significant bits of the exponent we can + // compute before crossing the threshold, and we do it with doublings. + i := bits.UintSize + for logR>>i <= threshold { + i-- + } + for k := uint(0); k < logR>>i; k++ { + rr.Add(rr, m) + } + + // Then we process the remaining bits of the exponent with a + // square-and-double chain. + for i > 0 { + rr.montgomeryMul(rr, rr, m) + i-- + if logR>>i&1 != 0 { + rr.Add(rr, m) + } + } + + return rr +} + +// minusInverseModW computes -x⁻¹ mod _W with x odd. +// +// This operation is used to precompute a constant involved in Montgomery +// multiplication. +func minusInverseModW(x uint) uint { + // Every iteration of this loop doubles the least-significant bits of + // correct inverse in y. The first three bits are already correct (1⁻¹ = 1, + // 3⁻¹ = 3, 5⁻¹ = 5, and 7⁻¹ = 7 mod 8), so doubling five times is enough + // for 64 bits (and wastes only one iteration for 32 bits). + // + // See https://crypto.stackexchange.com/a/47496. + y := x + for i := 0; i < 5; i++ { + y = y * (2 - x*y) + } + return -y +} + +// NewModulus creates a new Modulus from a slice of big-endian bytes. The +// modulus must be greater than one. +// +// The number of significant bits and whether the modulus is even is leaked +// through timing side-channels. +func NewModulus(b []byte) (*Modulus, error) { + n := NewNat().resetToBytes(b) + return newModulus(n) +} + +// NewModulusProduct creates a new Modulus from the product of two numbers +// represented as big-endian byte slices. The result must be greater than one. +// +//go:norace +func NewModulusProduct(a, b []byte) (*Modulus, error) { + x := NewNat().resetToBytes(a) + y := NewNat().resetToBytes(b) + n := NewNat().reset(len(x.limbs) + len(y.limbs)) + for i := range y.limbs { + n.limbs[i+len(x.limbs)] = addMulVVW(n.limbs[i:i+len(x.limbs)], x.limbs, y.limbs[i]) + } + return newModulus(n.trim()) +} + +func newModulus(n *Nat) (*Modulus, error) { + m := &Modulus{nat: n} + if m.nat.IsZero() == 1 || m.nat.IsOne() == 1 { + return nil, errors.New("modulus must be > 1") + } + if m.nat.IsOdd() == 1 { + m.odd = true + m.m0inv = minusInverseModW(m.nat.limbs[0]) + m.rr = rr(m) + } + return m, nil +} + +// Size returns the size of m in bytes. +func (m *Modulus) Size() int { + return (m.BitLen() + 7) / 8 +} + +// BitLen returns the size of m in bits. +func (m *Modulus) BitLen() int { + return m.nat.BitLenVarTime() +} + +// Nat returns m as a Nat. +func (m *Modulus) Nat() *Nat { + // Make a copy so that the caller can't modify m.nat or alias it with + // another Nat in a modulus operation. + n := NewNat() + n.set(m.nat) + return n +} + +// shiftIn calculates x = x << _W + y mod m. +// +// This assumes that x is already reduced mod m. +// +//go:norace +func (x *Nat) shiftIn(y uint, m *Modulus) *Nat { + d := NewNat().resetFor(m) + + // Eliminate bounds checks in the loop. + size := len(m.nat.limbs) + xLimbs := x.limbs[:size] + dLimbs := d.limbs[:size] + mLimbs := m.nat.limbs[:size] + + // Each iteration of this loop computes x = 2x + b mod m, where b is a bit + // from y. Effectively, it left-shifts x and adds y one bit at a time, + // reducing it every time. + // + // To do the reduction, each iteration computes both 2x + b and 2x + b - m. + // The next iteration (and finally the return line) will use either result + // based on whether 2x + b overflows m. + needSubtraction := no + for i := _W - 1; i >= 0; i-- { + carry := (y >> i) & 1 + var borrow uint + mask := ctMask(needSubtraction) + for i := 0; i < size; i++ { + l := xLimbs[i] ^ (mask & (xLimbs[i] ^ dLimbs[i])) + xLimbs[i], carry = bits.Add(l, l, carry) + dLimbs[i], borrow = bits.Sub(xLimbs[i], mLimbs[i], borrow) + } + // Like in maybeSubtractModulus, we need the subtraction if either it + // didn't underflow (meaning 2x + b > m) or if computing 2x + b + // overflowed (meaning 2x + b > 2^_W*n > m). + needSubtraction = not(choice(borrow)) | choice(carry) + } + return x.assign(needSubtraction, d) +} + +// Mod calculates out = y mod m. +// +// This works regardless how large the value of y is. +// +// The output will be resized to the size of m and overwritten. +// +//go:norace +func (x *Nat) Mod(y *Nat, m *Modulus) *Nat { + out, x := x, y + out.resetFor(m) + // Working our way from the most significant to the least significant limb, + // we can insert each limb at the least significant position, shifting all + // previous limbs left by _W. This way each limb will get shifted by the + // correct number of bits. We can insert at least N - 1 limbs without + // overflowing m. After that, we need to reduce every time we shift. + i := len(x.limbs) - 1 + // For the first N - 1 limbs we can skip the actual shifting and position + // them at the shifted position, which starts at min(N - 2, i). + start := len(m.nat.limbs) - 2 + if i < start { + start = i + } + for j := start; j >= 0; j-- { + out.limbs[j] = x.limbs[i] + i-- + } + // We shift in the remaining limbs, reducing modulo m each time. + for i >= 0 { + out.shiftIn(x.limbs[i], m) + i-- + } + return out +} + +// ExpandFor ensures x has the right size to work with operations modulo m. +// +// The announced size of x must be smaller than or equal to that of m. +func (x *Nat) ExpandFor(m *Modulus) *Nat { + return x.expand(len(m.nat.limbs)) +} + +// resetFor ensures x has the right size to work with operations modulo m. +// +// x is zeroed and may start at any size. +func (x *Nat) resetFor(m *Modulus) *Nat { + return x.reset(len(m.nat.limbs)) +} + +// maybeSubtractModulus computes x -= m if and only if x >= m or if "always" is yes. +// +// It can be used to reduce modulo m a value up to 2m - 1, which is a common +// range for results computed by higher level operations. +// +// always is usually a carry that indicates that the operation that produced x +// overflowed its size, meaning abstractly x > 2^_W*n > m even if x < m. +// +// x and m operands must have the same announced length. +// +//go:norace +func (x *Nat) maybeSubtractModulus(always choice, m *Modulus) { + t := NewNat().set(x) + underflow := t.sub(m.nat) + // We keep the result if x - m didn't underflow (meaning x >= m) + // or if always was set. + keep := not(choice(underflow)) | choice(always) + x.assign(keep, t) +} + +// Sub computes x = x - y mod m. +// +// The length of both operands must be the same as the modulus. Both operands +// must already be reduced modulo m. +// +//go:norace +func (x *Nat) Sub(y *Nat, m *Modulus) *Nat { + underflow := x.sub(y) + // If the subtraction underflowed, add m. + t := NewNat().set(x) + t.add(m.nat) + x.assign(choice(underflow), t) + return x +} + +// SubOne computes x = x - 1 mod m. +// +// The length of x must be the same as the modulus. +func (x *Nat) SubOne(m *Modulus) *Nat { + one := NewNat().ExpandFor(m) + one.limbs[0] = 1 + // Sub asks for x to be reduced modulo m, while SubOne doesn't, but when + // y = 1, it works, and this is an internal use. + return x.Sub(one, m) +} + +// Add computes x = x + y mod m. +// +// The length of both operands must be the same as the modulus. Both operands +// must already be reduced modulo m. +// +//go:norace +func (x *Nat) Add(y *Nat, m *Modulus) *Nat { + overflow := x.add(y) + x.maybeSubtractModulus(choice(overflow), m) + return x +} + +// montgomeryRepresentation calculates x = x * R mod m, with R = 2^(_W * n) and +// n = len(m.nat.limbs). +// +// Faster Montgomery multiplication replaces standard modular multiplication for +// numbers in this representation. +// +// This assumes that x is already reduced mod m. +func (x *Nat) montgomeryRepresentation(m *Modulus) *Nat { + // A Montgomery multiplication (which computes a * b / R) by R * R works out + // to a multiplication by R, which takes the value out of the Montgomery domain. + return x.montgomeryMul(x, m.rr, m) +} + +// montgomeryReduction calculates x = x / R mod m, with R = 2^(_W * n) and +// n = len(m.nat.limbs). +// +// This assumes that x is already reduced mod m. +func (x *Nat) montgomeryReduction(m *Modulus) *Nat { + // By Montgomery multiplying with 1 not in Montgomery representation, we + // convert out back from Montgomery representation, because it works out to + // dividing by R. + one := NewNat().ExpandFor(m) + one.limbs[0] = 1 + return x.montgomeryMul(x, one, m) +} + +// montgomeryMul calculates x = a * b / R mod m, with R = 2^(_W * n) and +// n = len(m.nat.limbs), also known as a Montgomery multiplication. +// +// All inputs should be the same length and already reduced modulo m. +// x will be resized to the size of m and overwritten. +// +//go:norace +func (x *Nat) montgomeryMul(a *Nat, b *Nat, m *Modulus) *Nat { + n := len(m.nat.limbs) + mLimbs := m.nat.limbs[:n] + aLimbs := a.limbs[:n] + bLimbs := b.limbs[:n] + + switch n { + default: + // Attempt to use a stack-allocated backing array. + T := make([]uint, 0, preallocLimbs*2) + if cap(T) < n*2 { + T = make([]uint, 0, n*2) + } + T = T[:n*2] + + // This loop implements Word-by-Word Montgomery Multiplication, as + // described in Algorithm 4 (Fig. 3) of "Efficient Software + // Implementations of Modular Exponentiation" by Shay Gueron + // [https://eprint.iacr.org/2011/239.pdf]. + var c uint + for i := 0; i < n; i++ { + _ = T[n+i] // bounds check elimination hint + + // Step 1 (T = a × b) is computed as a large pen-and-paper column + // multiplication of two numbers with n base-2^_W digits. If we just + // wanted to produce 2n-wide T, we would do + // + // for i := 0; i < n; i++ { + // d := bLimbs[i] + // T[n+i] = addMulVVW(T[i:n+i], aLimbs, d) + // } + // + // where d is a digit of the multiplier, T[i:n+i] is the shifted + // position of the product of that digit, and T[n+i] is the final carry. + // Note that T[i] isn't modified after processing the i-th digit. + // + // Instead of running two loops, one for Step 1 and one for Steps 2–6, + // the result of Step 1 is computed during the next loop. This is + // possible because each iteration only uses T[i] in Step 2 and then + // discards it in Step 6. + d := bLimbs[i] + c1 := addMulVVW(T[i:n+i], aLimbs, d) + + // Step 6 is replaced by shifting the virtual window we operate + // over: T of the algorithm is T[i:] for us. That means that T1 in + // Step 2 (T mod 2^_W) is simply T[i]. k0 in Step 3 is our m0inv. + Y := T[i] * m.m0inv + + // Step 4 and 5 add Y × m to T, which as mentioned above is stored + // at T[i:]. The two carries (from a × d and Y × m) are added up in + // the next word T[n+i], and the carry bit from that addition is + // brought forward to the next iteration. + c2 := addMulVVW(T[i:n+i], mLimbs, Y) + T[n+i], c = bits.Add(c1, c2, c) + } + + // Finally for Step 7 we copy the final T window into x, and subtract m + // if necessary (which as explained in maybeSubtractModulus can be the + // case both if x >= m, or if x overflowed). + // + // The paper suggests in Section 4 that we can do an "Almost Montgomery + // Multiplication" by subtracting only in the overflow case, but the + // cost is very similar since the constant time subtraction tells us if + // x >= m as a side effect, and taking care of the broken invariant is + // highly undesirable (see https://go.dev/issue/13907). + copy(x.reset(n).limbs, T[n:]) + x.maybeSubtractModulus(choice(c), m) + + // The following specialized cases follow the exact same algorithm, but + // optimized for the sizes most used in RSA. addMulVVW is implemented in + // assembly with loop unrolling depending on the architecture and bounds + // checks are removed by the compiler thanks to the constant size. + case 1024 / _W: + const n = 1024 / _W // compiler hint + T := make([]uint, n*2) + var c uint + for i := 0; i < n; i++ { + d := bLimbs[i] + c1 := addMulVVW1024(&T[i], &aLimbs[0], d) + Y := T[i] * m.m0inv + c2 := addMulVVW1024(&T[i], &mLimbs[0], Y) + T[n+i], c = bits.Add(c1, c2, c) + } + copy(x.reset(n).limbs, T[n:]) + x.maybeSubtractModulus(choice(c), m) + + case 1536 / _W: + const n = 1536 / _W // compiler hint + T := make([]uint, n*2) + var c uint + for i := 0; i < n; i++ { + d := bLimbs[i] + c1 := addMulVVW1536(&T[i], &aLimbs[0], d) + Y := T[i] * m.m0inv + c2 := addMulVVW1536(&T[i], &mLimbs[0], Y) + T[n+i], c = bits.Add(c1, c2, c) + } + copy(x.reset(n).limbs, T[n:]) + x.maybeSubtractModulus(choice(c), m) + + case 2048 / _W: + const n = 2048 / _W // compiler hint + T := make([]uint, n*2) + var c uint + for i := 0; i < n; i++ { + d := bLimbs[i] + c1 := addMulVVW2048(&T[i], &aLimbs[0], d) + Y := T[i] * m.m0inv + c2 := addMulVVW2048(&T[i], &mLimbs[0], Y) + T[n+i], c = bits.Add(c1, c2, c) + } + copy(x.reset(n).limbs, T[n:]) + x.maybeSubtractModulus(choice(c), m) + } + + return x +} + +// addMulVVW multiplies the multi-word value x by the single-word value y, +// adding the result to the multi-word value z and returning the final carry. +// It can be thought of as one row of a pen-and-paper column multiplication. +// +//go:norace +func addMulVVW(z, x []uint, y uint) (carry uint) { + _ = x[len(z)-1] // bounds check elimination hint + for i := range z { + hi, lo := bits.Mul(x[i], y) + lo, c := bits.Add(lo, z[i], 0) + // We use bits.Add with zero to get an add-with-carry instruction that + // absorbs the carry from the previous bits.Add. + hi, _ = bits.Add(hi, 0, c) + lo, c = bits.Add(lo, carry, 0) + hi, _ = bits.Add(hi, 0, c) + carry = hi + z[i] = lo + } + return carry +} + +// Mul calculates x = x * y mod m. +// +// The length of both operands must be the same as the modulus. Both operands +// must already be reduced modulo m. +// +//go:norace +func (x *Nat) Mul(y *Nat, m *Modulus) *Nat { + if m.odd { + // A Montgomery multiplication by a value out of the Montgomery domain + // takes the result out of Montgomery representation. + xR := NewNat().set(x).montgomeryRepresentation(m) // xR = x * R mod m + return x.montgomeryMul(xR, y, m) // x = xR * y / R mod m + } + + n := len(m.nat.limbs) + xLimbs := x.limbs[:n] + yLimbs := y.limbs[:n] + + switch n { + default: + // Attempt to use a stack-allocated backing array. + T := make([]uint, 0, preallocLimbs*2) + if cap(T) < n*2 { + T = make([]uint, 0, n*2) + } + T = T[:n*2] + + // T = x * y + for i := 0; i < n; i++ { + T[n+i] = addMulVVW(T[i:n+i], xLimbs, yLimbs[i]) + } + + // x = T mod m + return x.Mod(&Nat{limbs: T}, m) + + // The following specialized cases follow the exact same algorithm, but + // optimized for the sizes most used in RSA. See montgomeryMul for details. + case 1024 / _W: + const n = 1024 / _W // compiler hint + T := make([]uint, n*2) + for i := 0; i < n; i++ { + T[n+i] = addMulVVW1024(&T[i], &xLimbs[0], yLimbs[i]) + } + return x.Mod(&Nat{limbs: T}, m) + case 1536 / _W: + const n = 1536 / _W // compiler hint + T := make([]uint, n*2) + for i := 0; i < n; i++ { + T[n+i] = addMulVVW1536(&T[i], &xLimbs[0], yLimbs[i]) + } + return x.Mod(&Nat{limbs: T}, m) + case 2048 / _W: + const n = 2048 / _W // compiler hint + T := make([]uint, n*2) + for i := 0; i < n; i++ { + T[n+i] = addMulVVW2048(&T[i], &xLimbs[0], yLimbs[i]) + } + return x.Mod(&Nat{limbs: T}, m) + } +} + +// Exp calculates x = y^e mod m. +// +// The exponent e is represented in big-endian order. The output will be resized +// to the size of m and overwritten. y must already be reduced modulo m. +// +// m must be odd, or Exp will panic. +// +//go:norace +func (x *Nat) Exp(y *Nat, e []byte, m *Modulus) *Nat { + out, x := x, y + + if !m.odd { + panic("bigmod: modulus for Exp must be odd") + } + + // We use a 4 bit window. For our RSA workload, 4 bit windows are faster + // than 2 bit windows, but use an extra 12 nats worth of scratch space. + // Using bit sizes that don't divide 8 are more complex to implement, but + // are likely to be more efficient if necessary. + + table := [(1 << 4) - 1]*Nat{ // table[i] = x ^ (i+1) + // newNat calls are unrolled so they are allocated on the stack. + NewNat(), NewNat(), NewNat(), NewNat(), NewNat(), + NewNat(), NewNat(), NewNat(), NewNat(), NewNat(), + NewNat(), NewNat(), NewNat(), NewNat(), NewNat(), + } + table[0].set(x).montgomeryRepresentation(m) + for i := 1; i < len(table); i++ { + table[i].montgomeryMul(table[i-1], table[0], m) + } + + out.resetFor(m) + out.limbs[0] = 1 + out.montgomeryRepresentation(m) + tmp := NewNat().ExpandFor(m) + for _, b := range e { + for _, j := range []int{4, 0} { + // Square four times. Optimization note: this can be implemented + // more efficiently than with generic Montgomery multiplication. + out.montgomeryMul(out, out, m) + out.montgomeryMul(out, out, m) + out.montgomeryMul(out, out, m) + out.montgomeryMul(out, out, m) + + // Select x^k in constant time from the table. + k := uint((b >> j) & 0b1111) + for i := range table { + tmp.assign(ctEq(k, uint(i+1)), table[i]) + } + + // Multiply by x^k, discarding the result if k = 0. + tmp.montgomeryMul(out, tmp, m) + out.assign(not(ctEq(k, 0)), tmp) + } + } + + return out.montgomeryReduction(m) +} + +// ExpShortVarTime calculates out = x^e mod m. +// +// The output will be resized to the size of m and overwritten. x must already +// be reduced modulo m. This leaks the exponent through timing side-channels. +// +// m must be odd, or ExpShortVarTime will panic. +func (x *Nat) ExpShortVarTime(y *Nat, e uint, m *Modulus) *Nat { + out, x := x, y + + if !m.odd { + panic("bigmod: modulus for ExpShortVarTime must be odd") + } + // For short exponents, precomputing a table and using a window like in Exp + // doesn't pay off. Instead, we do a simple conditional square-and-multiply + // chain, skipping the initial run of zeroes. + xR := NewNat().set(x).montgomeryRepresentation(m) + out.set(xR) + for i := bits.UintSize - bits.Len(e) + 1; i < bits.UintSize; i++ { + out.montgomeryMul(out, out, m) + if k := (e >> (bits.UintSize - i - 1)) & 1; k != 0 { + out.montgomeryMul(out, xR, m) + } + } + return out.montgomeryReduction(m) +} + +// InverseVarTime calculates x = a⁻¹ mod m and returns (x, true) if a is +// invertible. Otherwise, InverseVarTime returns (x, false) and x is not +// modified. +// +// a must be reduced modulo m, but doesn't need to have the same size. The +// output will be resized to the size of m and overwritten. +// +//go:norace +func (x *Nat) InverseVarTime(a *Nat, m *Modulus) (*Nat, bool) { + u, A, err := extendedGCD(a, m.nat) + if err != nil { + return x, false + } + if u.IsOne() == 0 { + return x, false + } + return x.set(A), true +} + +// GCDVarTime calculates x = GCD(a, b) where at least one of a or b is odd, and +// both are non-zero. If GCDVarTime returns an error, x is not modified. +// +// The output will be resized to the size of the larger of a and b. +func (x *Nat) GCDVarTime(a, b *Nat) (*Nat, error) { + u, _, err := extendedGCD(a, b) + if err != nil { + return nil, err + } + return x.set(u), nil +} + +// extendedGCD computes u and A such that a = GCD(a, m) and u = A*a - B*m. +// +// u will have the size of the larger of a and m, and A will have the size of m. +// +// It is an error if either a or m is zero, or if they are both even. +func extendedGCD(a, m *Nat) (u, A *Nat, err error) { + // This is the extended binary GCD algorithm described in the Handbook of + // Applied Cryptography, Algorithm 14.61, adapted by BoringSSL to bound + // coefficients and avoid negative numbers. For more details and proof of + // correctness, see https://github.com/mit-plv/fiat-crypto/pull/333/files. + // + // Following the proof linked in the PR above, the changes are: + // + // 1. Negate [B] and [C] so they are positive. The invariant now involves a + // subtraction. + // 2. If step 2 (both [x] and [y] are even) runs, abort immediately. This + // case needs to be handled by the caller. + // 3. Subtract copies of [x] and [y] as needed in step 6 (both [u] and [v] + // are odd) so coefficients stay in bounds. + // 4. Replace the [u >= v] check with [u > v]. This changes the end + // condition to [v = 0] rather than [u = 0]. This saves an extra + // subtraction due to which coefficients were negated. + // 5. Rename x and y to a and n, to capture that one is a modulus. + // 6. Rearrange steps 4 through 6 slightly. Merge the loops in steps 4 and + // 5 into the main loop (step 7's goto), and move step 6 to the start of + // the loop iteration, ensuring each loop iteration halves at least one + // value. + // + // Note this algorithm does not handle either input being zero. + + if a.IsZero() == 1 || m.IsZero() == 1 { + return nil, nil, errors.New("extendedGCD: a or m is zero") + } + if a.IsOdd() == 0 && m.IsOdd() == 0 { + return nil, nil, errors.New("extendedGCD: both a and m are even") + } + + size := max(len(a.limbs), len(m.limbs)) + u = NewNat().set(a).expand(size) + v := NewNat().set(m).expand(size) + + A = NewNat().reset(len(m.limbs)) + A.limbs[0] = 1 + B := NewNat().reset(len(a.limbs)) + C := NewNat().reset(len(m.limbs)) + D := NewNat().reset(len(a.limbs)) + D.limbs[0] = 1 + + // Before and after each loop iteration, the following hold: + // + // u = A*a - B*m + // v = D*m - C*a + // 0 < u <= a + // 0 <= v <= m + // 0 <= A < m + // 0 <= B <= a + // 0 <= C < m + // 0 <= D <= a + // + // After each loop iteration, u and v only get smaller, and at least one of + // them shrinks by at least a factor of two. + for { + // If both u and v are odd, subtract the smaller from the larger. + // If u = v, we need to subtract from v to hit the modified exit condition. + if u.IsOdd() == 1 && v.IsOdd() == 1 { + if v.cmpGeq(u) == 0 { + u.sub(v) + A.Add(C, &Modulus{nat: m}) + B.Add(D, &Modulus{nat: a}) + } else { + v.sub(u) + C.Add(A, &Modulus{nat: m}) + D.Add(B, &Modulus{nat: a}) + } + } + + // Exactly one of u and v is now even. + if u.IsOdd() == v.IsOdd() { + panic("bigmod: internal error: u and v are not in the expected state") + } + + // Halve the even one and adjust the corresponding coefficient. + if u.IsOdd() == 0 { + rshift1(u, 0) + if A.IsOdd() == 1 || B.IsOdd() == 1 { + rshift1(A, A.add(m)) + rshift1(B, B.add(a)) + } else { + rshift1(A, 0) + rshift1(B, 0) + } + } else { // v.IsOdd() == 0 + rshift1(v, 0) + if C.IsOdd() == 1 || D.IsOdd() == 1 { + rshift1(C, C.add(m)) + rshift1(D, D.add(a)) + } else { + rshift1(C, 0) + rshift1(D, 0) + } + } + + if v.IsZero() == 1 { + return u, A, nil + } + } +} + +//go:norace +func rshift1(a *Nat, carry uint) { + size := len(a.limbs) + aLimbs := a.limbs[:size] + + for i := range size { + aLimbs[i] >>= 1 + if i+1 < size { + aLimbs[i] |= aLimbs[i+1] << (_W - 1) + } else { + aLimbs[i] |= carry << (_W - 1) + } + } +} + +// DivShortVarTime calculates x = x / y and returns the remainder. +// +// It panics if y is zero. +// +//go:norace +func (x *Nat) DivShortVarTime(y uint) uint { + if y == 0 { + panic("bigmod: division by zero") + } + + var r uint + for i := len(x.limbs) - 1; i >= 0; i-- { + x.limbs[i], r = bits.Div(r, x.limbs[i], y) + } + return r +} diff --git a/plugins/traefik/vendor/filippo.io/bigmod/nat_386.s b/plugins/traefik/vendor/filippo.io/bigmod/nat_386.s new file mode 100644 index 000000000..b20cd0b2b --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/nat_386.s @@ -0,0 +1,47 @@ +// Copyright 2009 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 !purego + +#include "textflag.h" + +// func addMulVVW1024(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1024(SB), $0-16 + MOVL $32, BX + JMP addMulVVWx<>(SB) + +// func addMulVVW1536(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1536(SB), $0-16 + MOVL $48, BX + JMP addMulVVWx<>(SB) + +// func addMulVVW2048(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW2048(SB), $0-16 + MOVL $64, BX + JMP addMulVVWx<>(SB) + +TEXT addMulVVWx<>(SB), NOFRAME|NOSPLIT, $0 + MOVL z+0(FP), DI + MOVL x+4(FP), SI + MOVL y+8(FP), BP + LEAL (DI)(BX*4), DI + LEAL (SI)(BX*4), SI + NEGL BX // i = -n + MOVL $0, CX // c = 0 + JMP E6 + +L6: MOVL (SI)(BX*4), AX + MULL BP + ADDL CX, AX + ADCL $0, DX + ADDL AX, (DI)(BX*4) + ADCL $0, DX + MOVL DX, CX + ADDL $1, BX // i++ + +E6: CMPL BX, $0 // i < 0 + JL L6 + + MOVL CX, c+12(FP) + RET diff --git a/plugins/traefik/vendor/filippo.io/bigmod/nat_amd64.s b/plugins/traefik/vendor/filippo.io/bigmod/nat_amd64.s new file mode 100644 index 000000000..ab94344e1 --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/nat_amd64.s @@ -0,0 +1,1230 @@ +// Code generated by command: go run nat_amd64_asm.go -out ../nat_amd64.s -pkg bigmod. DO NOT EDIT. + +//go:build !purego + +// func addMulVVW1024(z *uint, x *uint, y uint) (c uint) +// Requires: ADX, BMI2 +TEXT ·addMulVVW1024(SB), $0-32 + CMPB ·supportADX+0(SB), $0x01 + JEQ adx + MOVQ z+0(FP), CX + MOVQ x+8(FP), BX + MOVQ y+16(FP), SI + XORQ DI, DI + + // Iteration 0 + MOVQ (BX), AX + MULQ SI + ADDQ (CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, (CX) + + // Iteration 1 + MOVQ 8(BX), AX + MULQ SI + ADDQ 8(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 8(CX) + + // Iteration 2 + MOVQ 16(BX), AX + MULQ SI + ADDQ 16(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 16(CX) + + // Iteration 3 + MOVQ 24(BX), AX + MULQ SI + ADDQ 24(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 24(CX) + + // Iteration 4 + MOVQ 32(BX), AX + MULQ SI + ADDQ 32(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 32(CX) + + // Iteration 5 + MOVQ 40(BX), AX + MULQ SI + ADDQ 40(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 40(CX) + + // Iteration 6 + MOVQ 48(BX), AX + MULQ SI + ADDQ 48(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 48(CX) + + // Iteration 7 + MOVQ 56(BX), AX + MULQ SI + ADDQ 56(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 56(CX) + + // Iteration 8 + MOVQ 64(BX), AX + MULQ SI + ADDQ 64(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 64(CX) + + // Iteration 9 + MOVQ 72(BX), AX + MULQ SI + ADDQ 72(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 72(CX) + + // Iteration 10 + MOVQ 80(BX), AX + MULQ SI + ADDQ 80(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 80(CX) + + // Iteration 11 + MOVQ 88(BX), AX + MULQ SI + ADDQ 88(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 88(CX) + + // Iteration 12 + MOVQ 96(BX), AX + MULQ SI + ADDQ 96(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 96(CX) + + // Iteration 13 + MOVQ 104(BX), AX + MULQ SI + ADDQ 104(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 104(CX) + + // Iteration 14 + MOVQ 112(BX), AX + MULQ SI + ADDQ 112(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 112(CX) + + // Iteration 15 + MOVQ 120(BX), AX + MULQ SI + ADDQ 120(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 120(CX) + MOVQ DI, c+24(FP) + RET + +adx: + MOVQ z+0(FP), AX + MOVQ x+8(FP), CX + MOVQ y+16(FP), DX + XORQ BX, BX + XORQ SI, SI + + // Iteration 0 + MULXQ (CX), R8, DI + ADCXQ BX, R8 + ADOXQ (AX), R8 + MOVQ R8, (AX) + + // Iteration 1 + MULXQ 8(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 8(AX), R8 + MOVQ R8, 8(AX) + + // Iteration 2 + MULXQ 16(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 16(AX), R8 + MOVQ R8, 16(AX) + + // Iteration 3 + MULXQ 24(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 24(AX), R8 + MOVQ R8, 24(AX) + + // Iteration 4 + MULXQ 32(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 32(AX), R8 + MOVQ R8, 32(AX) + + // Iteration 5 + MULXQ 40(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 40(AX), R8 + MOVQ R8, 40(AX) + + // Iteration 6 + MULXQ 48(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 48(AX), R8 + MOVQ R8, 48(AX) + + // Iteration 7 + MULXQ 56(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 56(AX), R8 + MOVQ R8, 56(AX) + + // Iteration 8 + MULXQ 64(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 64(AX), R8 + MOVQ R8, 64(AX) + + // Iteration 9 + MULXQ 72(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 72(AX), R8 + MOVQ R8, 72(AX) + + // Iteration 10 + MULXQ 80(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 80(AX), R8 + MOVQ R8, 80(AX) + + // Iteration 11 + MULXQ 88(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 88(AX), R8 + MOVQ R8, 88(AX) + + // Iteration 12 + MULXQ 96(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 96(AX), R8 + MOVQ R8, 96(AX) + + // Iteration 13 + MULXQ 104(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 104(AX), R8 + MOVQ R8, 104(AX) + + // Iteration 14 + MULXQ 112(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 112(AX), R8 + MOVQ R8, 112(AX) + + // Iteration 15 + MULXQ 120(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 120(AX), R8 + MOVQ R8, 120(AX) + + // Add back carry flags and return + ADCXQ SI, BX + ADOXQ SI, BX + MOVQ BX, c+24(FP) + RET + +// func addMulVVW1536(z *uint, x *uint, y uint) (c uint) +// Requires: ADX, BMI2 +TEXT ·addMulVVW1536(SB), $0-32 + CMPB ·supportADX+0(SB), $0x01 + JEQ adx + MOVQ z+0(FP), CX + MOVQ x+8(FP), BX + MOVQ y+16(FP), SI + XORQ DI, DI + + // Iteration 0 + MOVQ (BX), AX + MULQ SI + ADDQ (CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, (CX) + + // Iteration 1 + MOVQ 8(BX), AX + MULQ SI + ADDQ 8(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 8(CX) + + // Iteration 2 + MOVQ 16(BX), AX + MULQ SI + ADDQ 16(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 16(CX) + + // Iteration 3 + MOVQ 24(BX), AX + MULQ SI + ADDQ 24(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 24(CX) + + // Iteration 4 + MOVQ 32(BX), AX + MULQ SI + ADDQ 32(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 32(CX) + + // Iteration 5 + MOVQ 40(BX), AX + MULQ SI + ADDQ 40(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 40(CX) + + // Iteration 6 + MOVQ 48(BX), AX + MULQ SI + ADDQ 48(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 48(CX) + + // Iteration 7 + MOVQ 56(BX), AX + MULQ SI + ADDQ 56(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 56(CX) + + // Iteration 8 + MOVQ 64(BX), AX + MULQ SI + ADDQ 64(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 64(CX) + + // Iteration 9 + MOVQ 72(BX), AX + MULQ SI + ADDQ 72(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 72(CX) + + // Iteration 10 + MOVQ 80(BX), AX + MULQ SI + ADDQ 80(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 80(CX) + + // Iteration 11 + MOVQ 88(BX), AX + MULQ SI + ADDQ 88(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 88(CX) + + // Iteration 12 + MOVQ 96(BX), AX + MULQ SI + ADDQ 96(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 96(CX) + + // Iteration 13 + MOVQ 104(BX), AX + MULQ SI + ADDQ 104(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 104(CX) + + // Iteration 14 + MOVQ 112(BX), AX + MULQ SI + ADDQ 112(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 112(CX) + + // Iteration 15 + MOVQ 120(BX), AX + MULQ SI + ADDQ 120(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 120(CX) + + // Iteration 16 + MOVQ 128(BX), AX + MULQ SI + ADDQ 128(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 128(CX) + + // Iteration 17 + MOVQ 136(BX), AX + MULQ SI + ADDQ 136(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 136(CX) + + // Iteration 18 + MOVQ 144(BX), AX + MULQ SI + ADDQ 144(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 144(CX) + + // Iteration 19 + MOVQ 152(BX), AX + MULQ SI + ADDQ 152(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 152(CX) + + // Iteration 20 + MOVQ 160(BX), AX + MULQ SI + ADDQ 160(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 160(CX) + + // Iteration 21 + MOVQ 168(BX), AX + MULQ SI + ADDQ 168(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 168(CX) + + // Iteration 22 + MOVQ 176(BX), AX + MULQ SI + ADDQ 176(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 176(CX) + + // Iteration 23 + MOVQ 184(BX), AX + MULQ SI + ADDQ 184(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 184(CX) + MOVQ DI, c+24(FP) + RET + +adx: + MOVQ z+0(FP), AX + MOVQ x+8(FP), CX + MOVQ y+16(FP), DX + XORQ BX, BX + XORQ SI, SI + + // Iteration 0 + MULXQ (CX), R8, DI + ADCXQ BX, R8 + ADOXQ (AX), R8 + MOVQ R8, (AX) + + // Iteration 1 + MULXQ 8(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 8(AX), R8 + MOVQ R8, 8(AX) + + // Iteration 2 + MULXQ 16(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 16(AX), R8 + MOVQ R8, 16(AX) + + // Iteration 3 + MULXQ 24(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 24(AX), R8 + MOVQ R8, 24(AX) + + // Iteration 4 + MULXQ 32(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 32(AX), R8 + MOVQ R8, 32(AX) + + // Iteration 5 + MULXQ 40(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 40(AX), R8 + MOVQ R8, 40(AX) + + // Iteration 6 + MULXQ 48(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 48(AX), R8 + MOVQ R8, 48(AX) + + // Iteration 7 + MULXQ 56(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 56(AX), R8 + MOVQ R8, 56(AX) + + // Iteration 8 + MULXQ 64(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 64(AX), R8 + MOVQ R8, 64(AX) + + // Iteration 9 + MULXQ 72(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 72(AX), R8 + MOVQ R8, 72(AX) + + // Iteration 10 + MULXQ 80(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 80(AX), R8 + MOVQ R8, 80(AX) + + // Iteration 11 + MULXQ 88(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 88(AX), R8 + MOVQ R8, 88(AX) + + // Iteration 12 + MULXQ 96(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 96(AX), R8 + MOVQ R8, 96(AX) + + // Iteration 13 + MULXQ 104(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 104(AX), R8 + MOVQ R8, 104(AX) + + // Iteration 14 + MULXQ 112(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 112(AX), R8 + MOVQ R8, 112(AX) + + // Iteration 15 + MULXQ 120(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 120(AX), R8 + MOVQ R8, 120(AX) + + // Iteration 16 + MULXQ 128(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 128(AX), R8 + MOVQ R8, 128(AX) + + // Iteration 17 + MULXQ 136(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 136(AX), R8 + MOVQ R8, 136(AX) + + // Iteration 18 + MULXQ 144(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 144(AX), R8 + MOVQ R8, 144(AX) + + // Iteration 19 + MULXQ 152(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 152(AX), R8 + MOVQ R8, 152(AX) + + // Iteration 20 + MULXQ 160(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 160(AX), R8 + MOVQ R8, 160(AX) + + // Iteration 21 + MULXQ 168(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 168(AX), R8 + MOVQ R8, 168(AX) + + // Iteration 22 + MULXQ 176(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 176(AX), R8 + MOVQ R8, 176(AX) + + // Iteration 23 + MULXQ 184(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 184(AX), R8 + MOVQ R8, 184(AX) + + // Add back carry flags and return + ADCXQ SI, BX + ADOXQ SI, BX + MOVQ BX, c+24(FP) + RET + +// func addMulVVW2048(z *uint, x *uint, y uint) (c uint) +// Requires: ADX, BMI2 +TEXT ·addMulVVW2048(SB), $0-32 + CMPB ·supportADX+0(SB), $0x01 + JEQ adx + MOVQ z+0(FP), CX + MOVQ x+8(FP), BX + MOVQ y+16(FP), SI + XORQ DI, DI + + // Iteration 0 + MOVQ (BX), AX + MULQ SI + ADDQ (CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, (CX) + + // Iteration 1 + MOVQ 8(BX), AX + MULQ SI + ADDQ 8(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 8(CX) + + // Iteration 2 + MOVQ 16(BX), AX + MULQ SI + ADDQ 16(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 16(CX) + + // Iteration 3 + MOVQ 24(BX), AX + MULQ SI + ADDQ 24(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 24(CX) + + // Iteration 4 + MOVQ 32(BX), AX + MULQ SI + ADDQ 32(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 32(CX) + + // Iteration 5 + MOVQ 40(BX), AX + MULQ SI + ADDQ 40(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 40(CX) + + // Iteration 6 + MOVQ 48(BX), AX + MULQ SI + ADDQ 48(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 48(CX) + + // Iteration 7 + MOVQ 56(BX), AX + MULQ SI + ADDQ 56(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 56(CX) + + // Iteration 8 + MOVQ 64(BX), AX + MULQ SI + ADDQ 64(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 64(CX) + + // Iteration 9 + MOVQ 72(BX), AX + MULQ SI + ADDQ 72(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 72(CX) + + // Iteration 10 + MOVQ 80(BX), AX + MULQ SI + ADDQ 80(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 80(CX) + + // Iteration 11 + MOVQ 88(BX), AX + MULQ SI + ADDQ 88(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 88(CX) + + // Iteration 12 + MOVQ 96(BX), AX + MULQ SI + ADDQ 96(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 96(CX) + + // Iteration 13 + MOVQ 104(BX), AX + MULQ SI + ADDQ 104(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 104(CX) + + // Iteration 14 + MOVQ 112(BX), AX + MULQ SI + ADDQ 112(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 112(CX) + + // Iteration 15 + MOVQ 120(BX), AX + MULQ SI + ADDQ 120(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 120(CX) + + // Iteration 16 + MOVQ 128(BX), AX + MULQ SI + ADDQ 128(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 128(CX) + + // Iteration 17 + MOVQ 136(BX), AX + MULQ SI + ADDQ 136(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 136(CX) + + // Iteration 18 + MOVQ 144(BX), AX + MULQ SI + ADDQ 144(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 144(CX) + + // Iteration 19 + MOVQ 152(BX), AX + MULQ SI + ADDQ 152(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 152(CX) + + // Iteration 20 + MOVQ 160(BX), AX + MULQ SI + ADDQ 160(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 160(CX) + + // Iteration 21 + MOVQ 168(BX), AX + MULQ SI + ADDQ 168(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 168(CX) + + // Iteration 22 + MOVQ 176(BX), AX + MULQ SI + ADDQ 176(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 176(CX) + + // Iteration 23 + MOVQ 184(BX), AX + MULQ SI + ADDQ 184(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 184(CX) + + // Iteration 24 + MOVQ 192(BX), AX + MULQ SI + ADDQ 192(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 192(CX) + + // Iteration 25 + MOVQ 200(BX), AX + MULQ SI + ADDQ 200(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 200(CX) + + // Iteration 26 + MOVQ 208(BX), AX + MULQ SI + ADDQ 208(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 208(CX) + + // Iteration 27 + MOVQ 216(BX), AX + MULQ SI + ADDQ 216(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 216(CX) + + // Iteration 28 + MOVQ 224(BX), AX + MULQ SI + ADDQ 224(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 224(CX) + + // Iteration 29 + MOVQ 232(BX), AX + MULQ SI + ADDQ 232(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 232(CX) + + // Iteration 30 + MOVQ 240(BX), AX + MULQ SI + ADDQ 240(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 240(CX) + + // Iteration 31 + MOVQ 248(BX), AX + MULQ SI + ADDQ 248(CX), AX + ADCQ $0x00, DX + ADDQ DI, AX + ADCQ $0x00, DX + MOVQ DX, DI + MOVQ AX, 248(CX) + MOVQ DI, c+24(FP) + RET + +adx: + MOVQ z+0(FP), AX + MOVQ x+8(FP), CX + MOVQ y+16(FP), DX + XORQ BX, BX + XORQ SI, SI + + // Iteration 0 + MULXQ (CX), R8, DI + ADCXQ BX, R8 + ADOXQ (AX), R8 + MOVQ R8, (AX) + + // Iteration 1 + MULXQ 8(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 8(AX), R8 + MOVQ R8, 8(AX) + + // Iteration 2 + MULXQ 16(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 16(AX), R8 + MOVQ R8, 16(AX) + + // Iteration 3 + MULXQ 24(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 24(AX), R8 + MOVQ R8, 24(AX) + + // Iteration 4 + MULXQ 32(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 32(AX), R8 + MOVQ R8, 32(AX) + + // Iteration 5 + MULXQ 40(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 40(AX), R8 + MOVQ R8, 40(AX) + + // Iteration 6 + MULXQ 48(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 48(AX), R8 + MOVQ R8, 48(AX) + + // Iteration 7 + MULXQ 56(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 56(AX), R8 + MOVQ R8, 56(AX) + + // Iteration 8 + MULXQ 64(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 64(AX), R8 + MOVQ R8, 64(AX) + + // Iteration 9 + MULXQ 72(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 72(AX), R8 + MOVQ R8, 72(AX) + + // Iteration 10 + MULXQ 80(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 80(AX), R8 + MOVQ R8, 80(AX) + + // Iteration 11 + MULXQ 88(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 88(AX), R8 + MOVQ R8, 88(AX) + + // Iteration 12 + MULXQ 96(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 96(AX), R8 + MOVQ R8, 96(AX) + + // Iteration 13 + MULXQ 104(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 104(AX), R8 + MOVQ R8, 104(AX) + + // Iteration 14 + MULXQ 112(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 112(AX), R8 + MOVQ R8, 112(AX) + + // Iteration 15 + MULXQ 120(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 120(AX), R8 + MOVQ R8, 120(AX) + + // Iteration 16 + MULXQ 128(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 128(AX), R8 + MOVQ R8, 128(AX) + + // Iteration 17 + MULXQ 136(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 136(AX), R8 + MOVQ R8, 136(AX) + + // Iteration 18 + MULXQ 144(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 144(AX), R8 + MOVQ R8, 144(AX) + + // Iteration 19 + MULXQ 152(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 152(AX), R8 + MOVQ R8, 152(AX) + + // Iteration 20 + MULXQ 160(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 160(AX), R8 + MOVQ R8, 160(AX) + + // Iteration 21 + MULXQ 168(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 168(AX), R8 + MOVQ R8, 168(AX) + + // Iteration 22 + MULXQ 176(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 176(AX), R8 + MOVQ R8, 176(AX) + + // Iteration 23 + MULXQ 184(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 184(AX), R8 + MOVQ R8, 184(AX) + + // Iteration 24 + MULXQ 192(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 192(AX), R8 + MOVQ R8, 192(AX) + + // Iteration 25 + MULXQ 200(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 200(AX), R8 + MOVQ R8, 200(AX) + + // Iteration 26 + MULXQ 208(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 208(AX), R8 + MOVQ R8, 208(AX) + + // Iteration 27 + MULXQ 216(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 216(AX), R8 + MOVQ R8, 216(AX) + + // Iteration 28 + MULXQ 224(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 224(AX), R8 + MOVQ R8, 224(AX) + + // Iteration 29 + MULXQ 232(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 232(AX), R8 + MOVQ R8, 232(AX) + + // Iteration 30 + MULXQ 240(CX), R8, DI + ADCXQ BX, R8 + ADOXQ 240(AX), R8 + MOVQ R8, 240(AX) + + // Iteration 31 + MULXQ 248(CX), R8, BX + ADCXQ DI, R8 + ADOXQ 248(AX), R8 + MOVQ R8, 248(AX) + + // Add back carry flags and return + ADCXQ SI, BX + ADOXQ SI, BX + MOVQ BX, c+24(FP) + RET diff --git a/plugins/traefik/vendor/filippo.io/bigmod/nat_arm.s b/plugins/traefik/vendor/filippo.io/bigmod/nat_arm.s new file mode 100644 index 000000000..b4148a238 --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/nat_arm.s @@ -0,0 +1,47 @@ +// Copyright 2009 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 !purego + +#include "textflag.h" + +// func addMulVVW1024(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1024(SB), $0-16 + MOVW $32, R5 + JMP addMulVVWx<>(SB) + +// func addMulVVW1536(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1536(SB), $0-16 + MOVW $48, R5 + JMP addMulVVWx<>(SB) + +// func addMulVVW2048(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW2048(SB), $0-16 + MOVW $64, R5 + JMP addMulVVWx<>(SB) + +TEXT addMulVVWx<>(SB), NOFRAME|NOSPLIT, $0 + MOVW $0, R0 + MOVW z+0(FP), R1 + MOVW x+4(FP), R2 + MOVW y+8(FP), R3 + ADD R5<<2, R1, R5 + MOVW $0, R4 + B E9 + +L9: MOVW.P 4(R2), R6 + MULLU R6, R3, (R7, R6) + ADD.S R4, R6 + ADC R0, R7 + MOVW 0(R1), R4 + ADD.S R4, R6 + ADC R0, R7 + MOVW.P R6, 4(R1) + MOVW R7, R4 + +E9: TEQ R1, R5 + BNE L9 + + MOVW R4, c+12(FP) + RET diff --git a/plugins/traefik/vendor/filippo.io/bigmod/nat_arm64.s b/plugins/traefik/vendor/filippo.io/bigmod/nat_arm64.s new file mode 100644 index 000000000..20c216c78 --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/nat_arm64.s @@ -0,0 +1,69 @@ +// Copyright 2013 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 !purego + +#include "textflag.h" + +// func addMulVVW1024(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1024(SB), $0-32 + MOVD $16, R0 + JMP addMulVVWx<>(SB) + +// func addMulVVW1536(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1536(SB), $0-32 + MOVD $24, R0 + JMP addMulVVWx<>(SB) + +// func addMulVVW2048(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW2048(SB), $0-32 + MOVD $32, R0 + JMP addMulVVWx<>(SB) + +TEXT addMulVVWx<>(SB), NOFRAME|NOSPLIT, $0 + MOVD z+0(FP), R1 + MOVD x+8(FP), R2 + MOVD y+16(FP), R3 + MOVD $0, R4 + +// The main loop of this code operates on a block of 4 words every iteration +// performing [R4:R12:R11:R10:R9] = R4 + R3 * [R8:R7:R6:R5] + [R12:R11:R10:R9] +// where R4 is carried from the previous iteration, R8:R7:R6:R5 hold the next +// 4 words of x, R3 is y and R12:R11:R10:R9 are part of the result z. +loop: + CBZ R0, done + + LDP.P 16(R2), (R5, R6) + LDP.P 16(R2), (R7, R8) + + LDP (R1), (R9, R10) + ADDS R4, R9 + MUL R6, R3, R14 + ADCS R14, R10 + MUL R7, R3, R15 + LDP 16(R1), (R11, R12) + ADCS R15, R11 + MUL R8, R3, R16 + ADCS R16, R12 + UMULH R8, R3, R20 + ADC $0, R20 + + MUL R5, R3, R13 + ADDS R13, R9 + UMULH R5, R3, R17 + ADCS R17, R10 + UMULH R6, R3, R21 + STP.P (R9, R10), 16(R1) + ADCS R21, R11 + UMULH R7, R3, R19 + ADCS R19, R12 + STP.P (R11, R12), 16(R1) + ADC $0, R20, R4 + + SUB $4, R0 + B loop + +done: + MOVD R4, c+24(FP) + RET diff --git a/plugins/traefik/vendor/filippo.io/bigmod/nat_asm.go b/plugins/traefik/vendor/filippo.io/bigmod/nat_asm.go new file mode 100644 index 000000000..1a4a06141 --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/nat_asm.go @@ -0,0 +1,28 @@ +// 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 !purego && (386 || amd64 || arm || arm64 || loong64 || ppc64 || ppc64le || riscv64 || s390x) + +package bigmod + +import "golang.org/x/sys/cpu" + +// amd64 assembly uses ADCX/ADOX/MULX if ADX is available to run two carry +// chains in the flags in parallel across the whole operation, and aggressively +// unrolls loops. arm64 processes four words at a time. +// +// It's unclear why the assembly for all other architectures, as well as for +// amd64 without ADX, perform better than the compiler output. +// TODO(filippo): file cmd/compile performance issue. + +var supportADX = cpu.X86.HasADX && cpu.X86.HasBMI2 + +//go:noescape +func addMulVVW1024(z, x *uint, y uint) (c uint) + +//go:noescape +func addMulVVW1536(z, x *uint, y uint) (c uint) + +//go:noescape +func addMulVVW2048(z, x *uint, y uint) (c uint) diff --git a/plugins/traefik/vendor/filippo.io/bigmod/nat_loong64.s b/plugins/traefik/vendor/filippo.io/bigmod/nat_loong64.s new file mode 100644 index 000000000..ef5464370 --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/nat_loong64.s @@ -0,0 +1,93 @@ +// Copyright 2024 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. + +// derived from crypto/internal/fips140/bigmod/nat_riscv64.s + +//go:build !purego + +#include "textflag.h" + +// func addMulVVW1024(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1024(SB),$0-32 + MOVV $16, R8 + JMP addMulVVWx<>(SB) + +// func addMulVVW1536(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1536(SB),$0-32 + MOVV $24, R8 + JMP addMulVVWx<>(SB) + +// func addMulVVW2048(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW2048(SB),$0-32 + MOVV $32, R8 + JMP addMulVVWx<>(SB) + +TEXT addMulVVWx<>(SB),NOFRAME|NOSPLIT,$0 + MOVV z+0(FP), R4 + MOVV x+8(FP), R6 + MOVV y+16(FP), R5 + MOVV $0, R7 + + BEQ R8, R0, done +loop: + MOVV 0*8(R4), R9 // z[0] + MOVV 1*8(R4), R10 // z[1] + MOVV 2*8(R4), R11 // z[2] + MOVV 3*8(R4), R12 // z[3] + + MOVV 0*8(R6), R13 // x[0] + MOVV 1*8(R6), R14 // x[1] + MOVV 2*8(R6), R15 // x[2] + MOVV 3*8(R6), R16 // x[3] + + MULHVU R13, R5, R17 // z_hi[0] = x[0] * y + MULV R13, R5, R13 // z_lo[0] = x[0] * y + ADDV R13, R9, R18 // z_lo[0] = x[0] * y + z[0] + SGTU R13, R18, R19 + ADDV R17, R19, R17 // z_hi[0] = x[0] * y + z[0] + ADDV R18, R7, R9 // z_lo[0] = x[0] * y + z[0] + c + SGTU R18, R9, R19 + ADDV R17, R19, R7 // next c + + MULHVU R14, R5, R24 // z_hi[1] = x[1] * y + MULV R14, R5, R14 // z_lo[1] = x[1] * y + ADDV R14, R10, R18 // z_lo[1] = x[1] * y + z[1] + SGTU R14, R18, R19 + ADDV R24, R19, R24 // z_hi[1] = x[1] * y + z[1] + ADDV R18, R7, R10 // z_lo[1] = x[1] * y + z[1] + c + SGTU R18, R10, R19 + ADDV R24, R19, R7 // next c + + MULHVU R15, R5, R25 // z_hi[2] = x[2] * y + MULV R15, R5, R15 // z_lo[2] = x[2] * y + ADDV R15, R11, R18 // z_lo[2] = x[2] * y + z[2] + SGTU R15, R18, R19 + ADDV R25, R19, R25 // z_hi[2] = x[2] * y + z[2] + ADDV R18, R7, R11 // z_lo[2] = x[2] * y + z[2] + c + SGTU R18, R11, R19 + ADDV R25, R19, R7 // next c + + MULHVU R16, R5, R26 // z_hi[3] = x[3] * y + MULV R16, R5, R16 // z_lo[3] = x[3] * y + ADDV R16, R12, R18 // z_lo[3] = x[3] * y + z[3] + SGTU R16, R18, R19 + ADDV R26, R19, R26 // z_hi[3] = x[3] * y + z[3] + ADDV R18, R7, R12 // z_lo[3] = x[3] * y + z[3] + c + SGTU R18, R12, R19 + ADDV R26, R19, R7 // next c + + MOVV R9, 0*8(R4) // z[0] + MOVV R10, 1*8(R4) // z[1] + MOVV R11, 2*8(R4) // z[2] + MOVV R12, 3*8(R4) // z[3] + + ADDV $32, R4 + ADDV $32, R6 + + SUBV $4, R8 + BNE R8, R0, loop + +done: + MOVV R7, c+24(FP) + RET diff --git a/plugins/traefik/vendor/filippo.io/bigmod/nat_noasm.go b/plugins/traefik/vendor/filippo.io/bigmod/nat_noasm.go new file mode 100644 index 000000000..dbec229f5 --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/nat_noasm.go @@ -0,0 +1,21 @@ +// 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 purego || !(386 || amd64 || arm || arm64 || loong64 || ppc64 || ppc64le || riscv64 || s390x || wasm) + +package bigmod + +import "unsafe" + +func addMulVVW1024(z, x *uint, y uint) (c uint) { + return addMulVVW(unsafe.Slice(z, 1024/_W), unsafe.Slice(x, 1024/_W), y) +} + +func addMulVVW1536(z, x *uint, y uint) (c uint) { + return addMulVVW(unsafe.Slice(z, 1536/_W), unsafe.Slice(x, 1536/_W), y) +} + +func addMulVVW2048(z, x *uint, y uint) (c uint) { + return addMulVVW(unsafe.Slice(z, 2048/_W), unsafe.Slice(x, 2048/_W), y) +} diff --git a/plugins/traefik/vendor/filippo.io/bigmod/nat_ppc64x.s b/plugins/traefik/vendor/filippo.io/bigmod/nat_ppc64x.s new file mode 100644 index 000000000..94260ca29 --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/nat_ppc64x.s @@ -0,0 +1,82 @@ +// Copyright 2013 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 !purego && (ppc64 || ppc64le) + +#include "textflag.h" + +// func addMulVVW1024(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1024(SB), $0-32 + MOVD $4, R6 // R6 = z_len/4 + JMP addMulVVWx<>(SB) + +// func addMulVVW1536(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1536(SB), $0-32 + MOVD $6, R6 // R6 = z_len/4 + JMP addMulVVWx<>(SB) + +// func addMulVVW2048(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW2048(SB), $0-32 + MOVD $8, R6 // R6 = z_len/4 + JMP addMulVVWx<>(SB) + +// This local function expects to be called only by +// callers above. R6 contains the z length/4 +// since 4 values are processed for each +// loop iteration, and is guaranteed to be > 0. +// If other callers are added this function might +// need to change. +TEXT addMulVVWx<>(SB), NOSPLIT, $0 + MOVD z+0(FP), R3 + MOVD x+8(FP), R4 + MOVD y+16(FP), R5 + + MOVD $0, R9 // R9 = c = 0 + MOVD R6, CTR // Initialize loop counter + PCALIGN $16 + +loop: + MOVD 0(R4), R14 // x[i] + MOVD 8(R4), R16 // x[i+1] + MOVD 16(R4), R18 // x[i+2] + MOVD 24(R4), R20 // x[i+3] + MOVD 0(R3), R15 // z[i] + MOVD 8(R3), R17 // z[i+1] + MOVD 16(R3), R19 // z[i+2] + MOVD 24(R3), R21 // z[i+3] + MULLD R5, R14, R10 // low x[i]*y + MULHDU R5, R14, R11 // high x[i]*y + ADDC R15, R10 + ADDZE R11 + ADDC R9, R10 + ADDZE R11, R9 + MULLD R5, R16, R14 // low x[i+1]*y + MULHDU R5, R16, R15 // high x[i+1]*y + ADDC R17, R14 + ADDZE R15 + ADDC R9, R14 + ADDZE R15, R9 + MULLD R5, R18, R16 // low x[i+2]*y + MULHDU R5, R18, R17 // high x[i+2]*y + ADDC R19, R16 + ADDZE R17 + ADDC R9, R16 + ADDZE R17, R9 + MULLD R5, R20, R18 // low x[i+3]*y + MULHDU R5, R20, R19 // high x[i+3]*y + ADDC R21, R18 + ADDZE R19 + ADDC R9, R18 + ADDZE R19, R9 + MOVD R10, 0(R3) // z[i] + MOVD R14, 8(R3) // z[i+1] + MOVD R16, 16(R3) // z[i+2] + MOVD R18, 24(R3) // z[i+3] + ADD $32, R3 + ADD $32, R4 + BDNZ loop + +done: + MOVD R9, c+24(FP) + RET diff --git a/plugins/traefik/vendor/filippo.io/bigmod/nat_riscv64.s b/plugins/traefik/vendor/filippo.io/bigmod/nat_riscv64.s new file mode 100644 index 000000000..f10ac7048 --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/nat_riscv64.s @@ -0,0 +1,91 @@ +// 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 !purego + +#include "textflag.h" + +// func addMulVVW1024(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1024(SB),$0-32 + MOV $16, X30 + JMP addMulVVWx<>(SB) + +// func addMulVVW1536(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1536(SB),$0-32 + MOV $24, X30 + JMP addMulVVWx<>(SB) + +// func addMulVVW2048(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW2048(SB),$0-32 + MOV $32, X30 + JMP addMulVVWx<>(SB) + +TEXT addMulVVWx<>(SB),NOFRAME|NOSPLIT,$0 + MOV z+0(FP), X5 + MOV x+8(FP), X7 + MOV y+16(FP), X6 + MOV $0, X29 + + BEQZ X30, done +loop: + MOV 0*8(X5), X10 // z[0] + MOV 1*8(X5), X13 // z[1] + MOV 2*8(X5), X16 // z[2] + MOV 3*8(X5), X19 // z[3] + + MOV 0*8(X7), X8 // x[0] + MOV 1*8(X7), X11 // x[1] + MOV 2*8(X7), X14 // x[2] + MOV 3*8(X7), X17 // x[3] + + MULHU X8, X6, X9 // z_hi[0] = x[0] * y + MUL X8, X6, X8 // z_lo[0] = x[0] * y + ADD X8, X10, X21 // z_lo[0] = x[0] * y + z[0] + SLTU X8, X21, X22 + ADD X9, X22, X9 // z_hi[0] = x[0] * y + z[0] + ADD X21, X29, X10 // z_lo[0] = x[0] * y + z[0] + c + SLTU X21, X10, X22 + ADD X9, X22, X29 // next c + + MULHU X11, X6, X12 // z_hi[1] = x[1] * y + MUL X11, X6, X11 // z_lo[1] = x[1] * y + ADD X11, X13, X21 // z_lo[1] = x[1] * y + z[1] + SLTU X11, X21, X22 + ADD X12, X22, X12 // z_hi[1] = x[1] * y + z[1] + ADD X21, X29, X13 // z_lo[1] = x[1] * y + z[1] + c + SLTU X21, X13, X22 + ADD X12, X22, X29 // next c + + MULHU X14, X6, X15 // z_hi[2] = x[2] * y + MUL X14, X6, X14 // z_lo[2] = x[2] * y + ADD X14, X16, X21 // z_lo[2] = x[2] * y + z[2] + SLTU X14, X21, X22 + ADD X15, X22, X15 // z_hi[2] = x[2] * y + z[2] + ADD X21, X29, X16 // z_lo[2] = x[2] * y + z[2] + c + SLTU X21, X16, X22 + ADD X15, X22, X29 // next c + + MULHU X17, X6, X18 // z_hi[3] = x[3] * y + MUL X17, X6, X17 // z_lo[3] = x[3] * y + ADD X17, X19, X21 // z_lo[3] = x[3] * y + z[3] + SLTU X17, X21, X22 + ADD X18, X22, X18 // z_hi[3] = x[3] * y + z[3] + ADD X21, X29, X19 // z_lo[3] = x[3] * y + z[3] + c + SLTU X21, X19, X22 + ADD X18, X22, X29 // next c + + MOV X10, 0*8(X5) // z[0] + MOV X13, 1*8(X5) // z[1] + MOV X16, 2*8(X5) // z[2] + MOV X19, 3*8(X5) // z[3] + + ADDI $32, X5 + ADDI $32, X7 + + ADDI $-4, X30 + BNEZ X30, loop + +done: + MOV X29, c+24(FP) + RET diff --git a/plugins/traefik/vendor/filippo.io/bigmod/nat_s390x.s b/plugins/traefik/vendor/filippo.io/bigmod/nat_s390x.s new file mode 100644 index 000000000..9b87c7a1d --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/nat_s390x.s @@ -0,0 +1,85 @@ +// Copyright 2016 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 !purego + +#include "textflag.h" + +// func addMulVVW1024(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1024(SB), $0-32 + MOVD $16, R5 + JMP addMulVVWx<>(SB) + +// func addMulVVW1536(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW1536(SB), $0-32 + MOVD $24, R5 + JMP addMulVVWx<>(SB) + +// func addMulVVW2048(z, x *uint, y uint) (c uint) +TEXT ·addMulVVW2048(SB), $0-32 + MOVD $32, R5 + JMP addMulVVWx<>(SB) + +TEXT addMulVVWx<>(SB), NOFRAME|NOSPLIT, $0 + MOVD z+0(FP), R2 + MOVD x+8(FP), R8 + MOVD y+16(FP), R9 + + MOVD $0, R1 // i*8 = 0 + MOVD $0, R7 // i = 0 + MOVD $0, R0 // make sure it's zero + MOVD $0, R4 // c = 0 + + MOVD R5, R12 + AND $-2, R12 + CMPBGE R5, $2, A6 + BR E6 + +A6: + MOVD (R8)(R1*1), R6 + MULHDU R9, R6 + MOVD (R2)(R1*1), R10 + ADDC R10, R11 // add to low order bits + ADDE R0, R6 + ADDC R4, R11 + ADDE R0, R6 + MOVD R6, R4 + MOVD R11, (R2)(R1*1) + + MOVD (8)(R8)(R1*1), R6 + MULHDU R9, R6 + MOVD (8)(R2)(R1*1), R10 + ADDC R10, R11 // add to low order bits + ADDE R0, R6 + ADDC R4, R11 + ADDE R0, R6 + MOVD R6, R4 + MOVD R11, (8)(R2)(R1*1) + + ADD $16, R1 // i*8 + 8 + ADD $2, R7 // i++ + + CMPBLT R7, R12, A6 + BR E6 + +L6: + // TODO: drop unused single-step loop. + MOVD (R8)(R1*1), R6 + MULHDU R9, R6 + MOVD (R2)(R1*1), R10 + ADDC R10, R11 // add to low order bits + ADDE R0, R6 + ADDC R4, R11 + ADDE R0, R6 + MOVD R6, R4 + MOVD R11, (R2)(R1*1) + + ADD $8, R1 // i*8 + 8 + ADD $1, R7 // i++ + +E6: + CMPBLT R7, R5, L6 // i < n + + MOVD R4, c+24(FP) + RET diff --git a/plugins/traefik/vendor/filippo.io/bigmod/nat_wasm.go b/plugins/traefik/vendor/filippo.io/bigmod/nat_wasm.go new file mode 100644 index 000000000..b4aaff74c --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/bigmod/nat_wasm.go @@ -0,0 +1,61 @@ +// Copyright 2024 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 !purego + +package bigmod + +import "unsafe" + +// The generic implementation relies on 64x64->128 bit multiplication and +// 64-bit add-with-carry, which are compiler intrinsics on many architectures. +// Wasm doesn't support those. Here we implement it with 32x32->64 bit +// operations, which is more efficient on Wasm. + +func idx(x *uint, i uintptr) *uint { + return (*uint)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + i*8)) +} + +func addMulVVWWasm(z, x *uint, y uint, n uintptr) (carry uint) { + const mask32 = 1<<32 - 1 + y0 := y & mask32 + y1 := y >> 32 + for i := range n { + xi := *idx(x, i) + x0 := xi & mask32 + x1 := xi >> 32 + zi := *idx(z, i) + z0 := zi & mask32 + z1 := zi >> 32 + c0 := carry & mask32 + c1 := carry >> 32 + + w00 := x0*y0 + z0 + c0 + l00 := w00 & mask32 + h00 := w00 >> 32 + + w01 := x0*y1 + z1 + h00 + l01 := w01 & mask32 + h01 := w01 >> 32 + + w10 := x1*y0 + c1 + l01 + h10 := w10 >> 32 + + carry = x1*y1 + h10 + h01 + *idx(z, i) = w10<<32 + l00 + } + return carry +} + +func addMulVVW1024(z, x *uint, y uint) (c uint) { + return addMulVVWWasm(z, x, y, 1024/_W) +} + +func addMulVVW1536(z, x *uint, y uint) (c uint) { + return addMulVVWWasm(z, x, y, 1536/_W) +} + +func addMulVVW2048(z, x *uint, y uint) (c uint) { + return addMulVVWWasm(z, x, y, 2048/_W) +} diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/README.md b/plugins/traefik/vendor/filippo.io/edwards25519/README.md index 24e2457d8..dcdd8d85f 100644 --- a/plugins/traefik/vendor/filippo.io/edwards25519/README.md +++ b/plugins/traefik/vendor/filippo.io/edwards25519/README.md @@ -7,8 +7,10 @@ import "filippo.io/edwards25519" This library implements the edwards25519 elliptic curve, exposing the necessary APIs to build a wide array of higher-level primitives. Read the docs at [pkg.go.dev/filippo.io/edwards25519](https://pkg.go.dev/filippo.io/edwards25519). -The code is originally derived from Adam Langley's internal implementation in the Go standard library, and includes George Tankersley's [performance improvements](https://golang.org/cl/71950). It was then further developed by Henry de Valence for use in ristretto255, and was finally [merged back into the Go standard library](https://golang.org/cl/276272) as of Go 1.17. It now tracks the upstream codebase and extends it with additional functionality. +The package tracks the upstream standard library package `crypto/internal/fips140/edwards25519` and extends it with additional functionality. -Most users don't need this package, and should instead use `crypto/ed25519` for signatures, `golang.org/x/crypto/curve25519` for Diffie-Hellman, or `github.com/gtank/ristretto255` for prime order group logic. However, for anyone currently using a fork of `crypto/internal/edwards25519`/`crypto/ed25519/internal/edwards25519` or `github.com/agl/edwards25519`, this package should be a safer, faster, and more powerful alternative. +The code is originally derived from Adam Langley's internal implementation in the Go standard library, and includes George Tankersley's [performance improvements](https://golang.org/cl/71950). It was then further developed by Henry de Valence for use in ristretto255, and was finally [merged back into the Go standard library](https://golang.org/cl/276272) as of Go 1.17. + +Most users don't need this package, and should instead use `crypto/ed25519` for signatures, `crypto/ecdh` for Diffie-Hellman, or `github.com/gtank/ristretto255` for prime order group logic. However, for anyone currently using a fork of the internal `edwards25519` package or of `github.com/agl/edwards25519`, this package should be a safer, faster, and more powerful alternative. Since this package is meant to curb proliferation of edwards25519 implementations in the Go ecosystem, it welcomes requests for new APIs or reviewable performance improvements. diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/doc.go b/plugins/traefik/vendor/filippo.io/edwards25519/doc.go index ab6aaebc0..dd2deb644 100644 --- a/plugins/traefik/vendor/filippo.io/edwards25519/doc.go +++ b/plugins/traefik/vendor/filippo.io/edwards25519/doc.go @@ -10,11 +10,11 @@ // the curve used by the Ed25519 signature scheme. // // Most users don't need this package, and should instead use crypto/ed25519 for -// signatures, golang.org/x/crypto/curve25519 for Diffie-Hellman, or -// github.com/gtank/ristretto255 for prime order group logic. +// signatures, crypto/ecdh for Diffie-Hellman, or github.com/gtank/ristretto255 +// for prime order group logic. // // However, developers who do need to interact with low-level edwards25519 // operations can use this package, which is an extended version of -// crypto/internal/edwards25519 from the standard library repackaged as +// crypto/internal/fips140/edwards25519 from the standard library repackaged as // an importable module. package edwards25519 diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/extra.go b/plugins/traefik/vendor/filippo.io/edwards25519/extra.go index d152d68ff..ee9b5ca5b 100644 --- a/plugins/traefik/vendor/filippo.io/edwards25519/extra.go +++ b/plugins/traefik/vendor/filippo.io/edwards25519/extra.go @@ -9,6 +9,7 @@ package edwards25519 import ( "errors" + "slices" "filippo.io/edwards25519/field" ) @@ -100,13 +101,15 @@ func (v *Point) bytesMontgomery(buf *[32]byte) []byte { // // u = (1 + y) / (1 - y) // - // where y = Y / Z. + // where y = Y / Z and therefore + // + // u = (Z + Y) / (Z - Y) - var y, recip, u field.Element + var n, r, u field.Element - y.Multiply(&v.y, y.Invert(&v.z)) // y = Y / Z - recip.Invert(recip.Subtract(feOne, &y)) // r = 1/(1 - y) - u.Multiply(u.Add(feOne, &y), &recip) // u = (1 + y)*r + n.Add(&v.z, &v.y) // n = Z + Y + r.Invert(r.Subtract(&v.z, &v.y)) // r = 1 / (Z - Y) + u.Multiply(&n, &r) // u = n * r return copyFieldElement(buf, &u) } @@ -124,7 +127,7 @@ func (v *Point) MultByCofactor(p *Point) *Point { return v.fromP1xP1(&result) } -// Given k > 0, set s = s**(2*i). +// Given k > 0, set s = s**(2*k). func (s *Scalar) pow2k(k int) { for i := 0; i < k; i++ { s.Multiply(s, s) @@ -250,12 +253,14 @@ func (v *Point) MultiScalarMult(scalars []*Scalar, points []*Point) *Point { // between each point in the multiscalar equation. // Build lookup tables for each point - tables := make([]projLookupTable, len(points)) + tables := make([]projLookupTable, 0, 2) // avoid allocation for small sizes + tables = slices.Grow(tables, len(points))[:len(points)] for i := range tables { tables[i].FromP3(points[i]) } // Compute signed radix-16 digits for each scalar - digits := make([][64]int8, len(scalars)) + digits := make([][64]int8, 0, 2) // avoid allocation for small sizes + digits = slices.Grow(digits, len(scalars))[:len(scalars)] for i := range digits { digits[i] = scalars[i].signedRadix16() } @@ -265,6 +270,7 @@ func (v *Point) MultiScalarMult(scalars []*Scalar, points []*Point) *Point { tmp1 := &projP1xP1{} tmp2 := &projP2{} // Lookup-and-add the appropriate multiple of each input point + v.Set(NewIdentityPoint()) for j := range tables { tables[j].SelectInto(multiple, digits[j][63]) tmp1.Add(v, multiple) // tmp1 = v + x_(j,63)*Q in P1xP1 coords @@ -347,3 +353,49 @@ func (v *Point) VarTimeMultiScalarMult(scalars []*Scalar, points []*Point) *Poin v.fromP2(tmp2) return v } + +// Select sets v to a if cond == 1 and to b if cond == 0. +func (v *Point) Select(a, b *Point, cond int) *Point { + checkInitialized(a, b) + v.x.Select(&a.x, &b.x, cond) + v.y.Select(&a.y, &b.y, cond) + v.z.Select(&a.z, &b.z, cond) + v.t.Select(&a.t, &b.t, cond) + return v +} + +// Double sets v = p + p, and returns v. +func (v *Point) Double(p *Point) *Point { + checkInitialized(p) + + pp := new(projP2).FromP3(p) + p1 := new(projP1xP1).Double(pp) + return v.fromP1xP1(p1) +} + +func (v *Point) addCached(p *Point, qCached *projCached) *Point { + result := new(projP1xP1).Add(p, qCached) + return v.fromP1xP1(result) +} + +// ScalarMultSlow sets v = x * q, and returns v. It doesn't precompute a large +// table, so it is considerably slower, but requires less memory. +// +// The scalar multiplication is done in constant time. +func (v *Point) ScalarMultSlow(x *Scalar, q *Point) *Point { + checkInitialized(q) + + s := x.Bytes() + qCached := new(projCached).FromP3(q) + v.Set(NewIdentityPoint()) + t := new(Point) + + for i := 255; i >= 0; i-- { + v.Double(v) + t.addCached(v, qCached) + cond := (s[i/8] >> (i % 8)) & 1 + v.Select(t, v, int(cond)) + } + + return v +} diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe.go b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe.go index 5518ef2b9..4d52cc10d 100644 --- a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe.go +++ b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe.go @@ -90,11 +90,7 @@ func (v *Element) Add(a, b *Element) *Element { v.l2 = a.l2 + b.l2 v.l3 = a.l3 + b.l3 v.l4 = a.l4 + b.l4 - // Using the generic implementation here is actually faster than the - // assembly. Probably because the body of this function is so simple that - // the compiler can figure out better optimizations by inlining the carry - // propagation. - return v.carryPropagateGeneric() + return v.carryPropagate() } // Subtract sets v = a - b, and returns v. @@ -232,18 +228,22 @@ func (v *Element) bytes(out *[32]byte) []byte { t := *v t.reduce() - var buf [8]byte - for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} { - bitsOffset := i * 51 - binary.LittleEndian.PutUint64(buf[:], l<= len(out) { - break - } - out[off] |= bb - } - } + // Pack five 51-bit limbs into four 64-bit words: + // + // 255 204 153 102 51 0 + // ├──l4──┼──l3──┼──l2──┼──l1──┼──l0──┤ + // ├───u3───┼───u2───┼───u1───┼───u0───┤ + // 256 192 128 64 0 + + u0 := t.l1<<51 | t.l0 + u1 := t.l2<<(102-64) | t.l1>>(64-51) + u2 := t.l3<<(153-128) | t.l2>>(128-102) + u3 := t.l4<<(204-192) | t.l3>>(192-153) + + binary.LittleEndian.PutUint64(out[0*8:], u0) + binary.LittleEndian.PutUint64(out[1*8:], u1) + binary.LittleEndian.PutUint64(out[2*8:], u2) + binary.LittleEndian.PutUint64(out[3*8:], u3) return out[:] } diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_amd64.go b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_amd64.go index edcf163c4..00bf8f447 100644 --- a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_amd64.go +++ b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_amd64.go @@ -1,7 +1,6 @@ // Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT. -//go:build amd64 && gc && !purego -// +build amd64,gc,!purego +//go:build !purego package field diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_amd64.s b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_amd64.s index 293f013c9..5e06e242e 100644 --- a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_amd64.s +++ b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_amd64.s @@ -1,7 +1,6 @@ // Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT. -//go:build amd64 && gc && !purego -// +build amd64,gc,!purego +//go:build !purego #include "textflag.h" @@ -17,32 +16,36 @@ TEXT ·feMul(SB), NOSPLIT, $0-24 MOVQ DX, SI // r0 += 19×a1×b4 - MOVQ 8(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, DI - ADCQ DX, SI + MOVQ 8(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + MULQ 32(BX) + ADDQ AX, DI + ADCQ DX, SI // r0 += 19×a2×b3 - MOVQ 16(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(BX) - ADDQ AX, DI - ADCQ DX, SI + MOVQ 16(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + MULQ 24(BX) + ADDQ AX, DI + ADCQ DX, SI // r0 += 19×a3×b2 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 16(BX) - ADDQ AX, DI - ADCQ DX, SI + MOVQ 24(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + MULQ 16(BX) + ADDQ AX, DI + ADCQ DX, SI // r0 += 19×a4×b1 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 8(BX) - ADDQ AX, DI - ADCQ DX, SI + MOVQ 32(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + MULQ 8(BX) + ADDQ AX, DI + ADCQ DX, SI // r1 = a0×b1 MOVQ (CX), AX @@ -57,25 +60,28 @@ TEXT ·feMul(SB), NOSPLIT, $0-24 ADCQ DX, R8 // r1 += 19×a2×b4 - MOVQ 16(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, R9 - ADCQ DX, R8 + MOVQ 16(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + MULQ 32(BX) + ADDQ AX, R9 + ADCQ DX, R8 // r1 += 19×a3×b3 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(BX) - ADDQ AX, R9 - ADCQ DX, R8 + MOVQ 24(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + MULQ 24(BX) + ADDQ AX, R9 + ADCQ DX, R8 // r1 += 19×a4×b2 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 16(BX) - ADDQ AX, R9 - ADCQ DX, R8 + MOVQ 32(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + MULQ 16(BX) + ADDQ AX, R9 + ADCQ DX, R8 // r2 = a0×b2 MOVQ (CX), AX @@ -96,18 +102,20 @@ TEXT ·feMul(SB), NOSPLIT, $0-24 ADCQ DX, R10 // r2 += 19×a3×b4 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, R11 - ADCQ DX, R10 + MOVQ 24(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + MULQ 32(BX) + ADDQ AX, R11 + ADCQ DX, R10 // r2 += 19×a4×b3 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(BX) - ADDQ AX, R11 - ADCQ DX, R10 + MOVQ 32(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + MULQ 24(BX) + ADDQ AX, R11 + ADCQ DX, R10 // r3 = a0×b3 MOVQ (CX), AX @@ -134,11 +142,12 @@ TEXT ·feMul(SB), NOSPLIT, $0-24 ADCQ DX, R12 // r3 += 19×a4×b4 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, R13 - ADCQ DX, R12 + MOVQ 32(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + MULQ 32(BX) + ADDQ AX, R13 + ADCQ DX, R12 // r4 = a0×b4 MOVQ (CX), AX @@ -232,18 +241,22 @@ TEXT ·feSquare(SB), NOSPLIT, $0-16 MOVQ DX, BX // r0 += 38×l1×l4 - MOVQ 8(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 32(CX) - ADDQ AX, SI - ADCQ DX, BX + MOVQ 8(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + SHLQ $0x01, AX + MULQ 32(CX) + ADDQ AX, SI + ADCQ DX, BX // r0 += 38×l2×l3 - MOVQ 16(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 24(CX) - ADDQ AX, SI - ADCQ DX, BX + MOVQ 16(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + SHLQ $0x01, AX + MULQ 24(CX) + ADDQ AX, SI + ADCQ DX, BX // r1 = 2×l0×l1 MOVQ (CX), AX @@ -253,18 +266,21 @@ TEXT ·feSquare(SB), NOSPLIT, $0-16 MOVQ DX, DI // r1 += 38×l2×l4 - MOVQ 16(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 32(CX) - ADDQ AX, R8 - ADCQ DX, DI + MOVQ 16(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + SHLQ $0x01, AX + MULQ 32(CX) + ADDQ AX, R8 + ADCQ DX, DI // r1 += 19×l3×l3 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(CX) - ADDQ AX, R8 - ADCQ DX, DI + MOVQ 24(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + MULQ 24(CX) + ADDQ AX, R8 + ADCQ DX, DI // r2 = 2×l0×l2 MOVQ (CX), AX @@ -280,11 +296,13 @@ TEXT ·feSquare(SB), NOSPLIT, $0-16 ADCQ DX, R9 // r2 += 38×l3×l4 - MOVQ 24(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 32(CX) - ADDQ AX, R10 - ADCQ DX, R9 + MOVQ 24(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + SHLQ $0x01, AX + MULQ 32(CX) + ADDQ AX, R10 + ADCQ DX, R9 // r3 = 2×l0×l3 MOVQ (CX), AX @@ -294,18 +312,19 @@ TEXT ·feSquare(SB), NOSPLIT, $0-16 MOVQ DX, R11 // r3 += 2×l1×l2 - MOVQ 8(CX), AX - IMUL3Q $0x02, AX, AX - MULQ 16(CX) - ADDQ AX, R12 - ADCQ DX, R11 + MOVQ 8(CX), AX + SHLQ $0x01, AX + MULQ 16(CX) + ADDQ AX, R12 + ADCQ DX, R11 // r3 += 19×l4×l4 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(CX) - ADDQ AX, R12 - ADCQ DX, R11 + MOVQ 32(CX), DX + LEAQ (DX)(DX*8), AX + LEAQ (DX)(AX*2), AX + MULQ 32(CX) + ADDQ AX, R12 + ADCQ DX, R11 // r4 = 2×l0×l4 MOVQ (CX), AX @@ -315,11 +334,11 @@ TEXT ·feSquare(SB), NOSPLIT, $0-16 MOVQ DX, R13 // r4 += 2×l1×l3 - MOVQ 8(CX), AX - IMUL3Q $0x02, AX, AX - MULQ 24(CX) - ADDQ AX, R14 - ADCQ DX, R13 + MOVQ 8(CX), AX + SHLQ $0x01, AX + MULQ 24(CX) + ADDQ AX, R14 + ADCQ DX, R13 // r4 += l2×l2 MOVQ 16(CX), AX diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go index ddb6c9b8f..4b81f25d1 100644 --- a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go +++ b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go @@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !amd64 || !gc || purego -// +build !amd64 !gc purego +//go:build !amd64 || purego package field diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_arm64.go b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_arm64.go deleted file mode 100644 index af459ef51..000000000 --- a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_arm64.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2020 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 arm64 && gc && !purego -// +build arm64,gc,!purego - -package field - -//go:noescape -func carryPropagate(v *Element) - -func (v *Element) carryPropagate() *Element { - carryPropagate(v) - return v -} diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_arm64.s b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_arm64.s deleted file mode 100644 index 3126a4341..000000000 --- a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_arm64.s +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2020 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 arm64 && gc && !purego - -#include "textflag.h" - -// carryPropagate works exactly like carryPropagateGeneric and uses the -// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but -// avoids loading R0-R4 twice and uses LDP and STP. -// -// See https://golang.org/issues/43145 for the main compiler issue. -// -// func carryPropagate(v *Element) -TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8 - MOVD v+0(FP), R20 - - LDP 0(R20), (R0, R1) - LDP 16(R20), (R2, R3) - MOVD 32(R20), R4 - - AND $0x7ffffffffffff, R0, R10 - AND $0x7ffffffffffff, R1, R11 - AND $0x7ffffffffffff, R2, R12 - AND $0x7ffffffffffff, R3, R13 - AND $0x7ffffffffffff, R4, R14 - - ADD R0>>51, R11, R11 - ADD R1>>51, R12, R12 - ADD R2>>51, R13, R13 - ADD R3>>51, R14, R14 - // R4>>51 * 19 + R10 -> R10 - LSR $51, R4, R21 - MOVD $19, R22 - MADD R22, R10, R21, R10 - - STP (R10, R11), 0(R20) - STP (R12, R13), 16(R20) - MOVD R14, 32(R20) - - RET diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go deleted file mode 100644 index 234a5b2e5..000000000 --- a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2021 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 !arm64 || !gc || purego -// +build !arm64 !gc purego - -package field - -func (v *Element) carryPropagate() *Element { - return v.carryPropagateGeneric() -} diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_generic.go b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_generic.go index 86f5fd955..ef1f15a5d 100644 --- a/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_generic.go +++ b/plugins/traefik/vendor/filippo.io/edwards25519/field/fe_generic.go @@ -12,20 +12,42 @@ type uint128 struct { lo, hi uint64 } -// mul64 returns a * b. -func mul64(a, b uint64) uint128 { +// mul returns a * b. +func mul(a, b uint64) uint128 { hi, lo := bits.Mul64(a, b) return uint128{lo, hi} } -// addMul64 returns v + a * b. -func addMul64(v uint128, a, b uint64) uint128 { +// addMul returns v + a * b. +func addMul(v uint128, a, b uint64) uint128 { hi, lo := bits.Mul64(a, b) lo, c := bits.Add64(lo, v.lo, 0) hi, _ = bits.Add64(hi, v.hi, c) return uint128{lo, hi} } +// mul19 returns v * 19. +func mul19(v uint64) uint64 { + // Using this approach seems to yield better optimizations than *19. + return v + (v+v<<3)<<1 +} + +// addMul19 returns v + 19 * a * b, where a and b are at most 52 bits. +func addMul19(v uint128, a, b uint64) uint128 { + hi, lo := bits.Mul64(mul19(a), b) + lo, c := bits.Add64(lo, v.lo, 0) + hi, _ = bits.Add64(hi, v.hi, c) + return uint128{lo, hi} +} + +// addMul38 returns v + 38 * a * b, where a and b are at most 52 bits. +func addMul38(v uint128, a, b uint64) uint128 { + hi, lo := bits.Mul64(mul19(a), b*2) + lo, c := bits.Add64(lo, v.lo, 0) + hi, _ = bits.Add64(hi, v.hi, c) + return uint128{lo, hi} +} + // shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits. func shiftRightBy51(a uint128) uint64 { return (a.hi << (64 - 51)) | (a.lo >> 51) @@ -76,45 +98,40 @@ func feMulGeneric(v, a, b *Element) { // // Finally we add up the columns into wide, overlapping limbs. - a1_19 := a1 * 19 - a2_19 := a2 * 19 - a3_19 := a3 * 19 - a4_19 := a4 * 19 - // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1) - r0 := mul64(a0, b0) - r0 = addMul64(r0, a1_19, b4) - r0 = addMul64(r0, a2_19, b3) - r0 = addMul64(r0, a3_19, b2) - r0 = addMul64(r0, a4_19, b1) + r0 := mul(a0, b0) + r0 = addMul19(r0, a1, b4) + r0 = addMul19(r0, a2, b3) + r0 = addMul19(r0, a3, b2) + r0 = addMul19(r0, a4, b1) // r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2) - r1 := mul64(a0, b1) - r1 = addMul64(r1, a1, b0) - r1 = addMul64(r1, a2_19, b4) - r1 = addMul64(r1, a3_19, b3) - r1 = addMul64(r1, a4_19, b2) + r1 := mul(a0, b1) + r1 = addMul(r1, a1, b0) + r1 = addMul19(r1, a2, b4) + r1 = addMul19(r1, a3, b3) + r1 = addMul19(r1, a4, b2) // r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3) - r2 := mul64(a0, b2) - r2 = addMul64(r2, a1, b1) - r2 = addMul64(r2, a2, b0) - r2 = addMul64(r2, a3_19, b4) - r2 = addMul64(r2, a4_19, b3) + r2 := mul(a0, b2) + r2 = addMul(r2, a1, b1) + r2 = addMul(r2, a2, b0) + r2 = addMul19(r2, a3, b4) + r2 = addMul19(r2, a4, b3) // r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4 - r3 := mul64(a0, b3) - r3 = addMul64(r3, a1, b2) - r3 = addMul64(r3, a2, b1) - r3 = addMul64(r3, a3, b0) - r3 = addMul64(r3, a4_19, b4) + r3 := mul(a0, b3) + r3 = addMul(r3, a1, b2) + r3 = addMul(r3, a2, b1) + r3 = addMul(r3, a3, b0) + r3 = addMul19(r3, a4, b4) // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0 - r4 := mul64(a0, b4) - r4 = addMul64(r4, a1, b3) - r4 = addMul64(r4, a2, b2) - r4 = addMul64(r4, a3, b1) - r4 = addMul64(r4, a4, b0) + r4 := mul(a0, b4) + r4 = addMul(r4, a1, b3) + r4 = addMul(r4, a2, b2) + r4 = addMul(r4, a3, b1) + r4 = addMul(r4, a4, b0) // After the multiplication, we need to reduce (carry) the five coefficients // to obtain a result with limbs that are at most slightly larger than 2⁵¹, @@ -149,7 +166,7 @@ func feMulGeneric(v, a, b *Element) { c3 := shiftRightBy51(r3) c4 := shiftRightBy51(r4) - rr0 := r0.lo&maskLow51Bits + c4*19 + rr0 := r0.lo&maskLow51Bits + mul19(c4) rr1 := r1.lo&maskLow51Bits + c0 rr2 := r2.lo&maskLow51Bits + c1 rr3 := r3.lo&maskLow51Bits + c2 @@ -158,8 +175,12 @@ func feMulGeneric(v, a, b *Element) { // Now all coefficients fit into 64-bit registers but are still too large to // be passed around as an Element. We therefore do one last carry chain, // where the carries will be small enough to fit in the wiggle room above 2⁵¹. - *v = Element{rr0, rr1, rr2, rr3, rr4} - v.carryPropagate() + + v.l0 = rr0&maskLow51Bits + mul19(rr4>>51) + v.l1 = rr1&maskLow51Bits + rr0>>51 + v.l2 = rr2&maskLow51Bits + rr1>>51 + v.l3 = rr3&maskLow51Bits + rr2>>51 + v.l4 = rr4&maskLow51Bits + rr3>>51 } func feSquareGeneric(v, a *Element) { @@ -190,44 +211,31 @@ func feSquareGeneric(v, a *Element) { // l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4 = // -------------------------------------- // r4 r3 r2 r1 r0 - // - // With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with - // only three Mul64 and four Add64, instead of five and eight. - - l0_2 := l0 * 2 - l1_2 := l1 * 2 - - l1_38 := l1 * 38 - l2_38 := l2 * 38 - l3_38 := l3 * 38 - - l3_19 := l3 * 19 - l4_19 := l4 * 19 // r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3) - r0 := mul64(l0, l0) - r0 = addMul64(r0, l1_38, l4) - r0 = addMul64(r0, l2_38, l3) + r0 := mul(l0, l0) + r0 = addMul38(r0, l1, l4) + r0 = addMul38(r0, l2, l3) // r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3 - r1 := mul64(l0_2, l1) - r1 = addMul64(r1, l2_38, l4) - r1 = addMul64(r1, l3_19, l3) + r1 := mul(l0*2, l1) + r1 = addMul38(r1, l2, l4) + r1 = addMul19(r1, l3, l3) // r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4 - r2 := mul64(l0_2, l2) - r2 = addMul64(r2, l1, l1) - r2 = addMul64(r2, l3_38, l4) + r2 := mul(l0*2, l2) + r2 = addMul(r2, l1, l1) + r2 = addMul38(r2, l3, l4) // r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4 - r3 := mul64(l0_2, l3) - r3 = addMul64(r3, l1_2, l2) - r3 = addMul64(r3, l4_19, l4) + r3 := mul(l0*2, l3) + r3 = addMul(r3, l1*2, l2) + r3 = addMul19(r3, l4, l4) // r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2 - r4 := mul64(l0_2, l4) - r4 = addMul64(r4, l1_2, l3) - r4 = addMul64(r4, l2, l2) + r4 := mul(l0*2, l4) + r4 = addMul(r4, l1*2, l3) + r4 = addMul(r4, l2, l2) c0 := shiftRightBy51(r0) c1 := shiftRightBy51(r1) @@ -235,32 +243,30 @@ func feSquareGeneric(v, a *Element) { c3 := shiftRightBy51(r3) c4 := shiftRightBy51(r4) - rr0 := r0.lo&maskLow51Bits + c4*19 + rr0 := r0.lo&maskLow51Bits + mul19(c4) rr1 := r1.lo&maskLow51Bits + c0 rr2 := r2.lo&maskLow51Bits + c1 rr3 := r3.lo&maskLow51Bits + c2 rr4 := r4.lo&maskLow51Bits + c3 - *v = Element{rr0, rr1, rr2, rr3, rr4} - v.carryPropagate() + v.l0 = rr0&maskLow51Bits + mul19(rr4>>51) + v.l1 = rr1&maskLow51Bits + rr0>>51 + v.l2 = rr2&maskLow51Bits + rr1>>51 + v.l3 = rr3&maskLow51Bits + rr2>>51 + v.l4 = rr4&maskLow51Bits + rr3>>51 } -// carryPropagateGeneric brings the limbs below 52 bits by applying the reduction +// carryPropagate brings the limbs below 52 bits by applying the reduction // identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry. -func (v *Element) carryPropagateGeneric() *Element { - c0 := v.l0 >> 51 - c1 := v.l1 >> 51 - c2 := v.l2 >> 51 - c3 := v.l3 >> 51 - c4 := v.l4 >> 51 - - // c4 is at most 64 - 51 = 13 bits, so c4*19 is at most 18 bits, and +func (v *Element) carryPropagate() *Element { + // (l4>>51) is at most 64 - 51 = 13 bits, so (l4>>51)*19 is at most 18 bits, and // the final l0 will be at most 52 bits. Similarly for the rest. - v.l0 = v.l0&maskLow51Bits + c4*19 - v.l1 = v.l1&maskLow51Bits + c0 - v.l2 = v.l2&maskLow51Bits + c1 - v.l3 = v.l3&maskLow51Bits + c2 - v.l4 = v.l4&maskLow51Bits + c3 + l0 := v.l0 + v.l0 = v.l0&maskLow51Bits + mul19(v.l4>>51) + v.l4 = v.l4&maskLow51Bits + v.l3>>51 + v.l3 = v.l3&maskLow51Bits + v.l2>>51 + v.l2 = v.l2&maskLow51Bits + v.l1>>51 + v.l1 = v.l1&maskLow51Bits + l0>>51 return v } diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/pull.sh b/plugins/traefik/vendor/filippo.io/edwards25519/pull.sh new file mode 100644 index 000000000..f6217c96e --- /dev/null +++ b/plugins/traefik/vendor/filippo.io/edwards25519/pull.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +TAG="$1" +TMPDIR="$(mktemp -d)" + +cleanup() { + rm -rf "$TMPDIR" +} +trap cleanup EXIT + +command -v git >/dev/null +command -v git-filter-repo >/dev/null + +if [ -d "$HOME/go/.git" ]; then + REFERENCE=(--reference "$HOME/go" --dissociate) +else + REFERENCE=() +fi + +git -c advice.detachedHead=false clone --no-checkout "${REFERENCE[@]}" \ + -b "$TAG" https://go.googlesource.com/go.git "$TMPDIR" + +# Simplify the history graph by removing the dev.boringcrypto branches, whose +# merges end up empty after grafting anyway. This also fixes a weird quirk +# (maybe a git-filter-repo bug?) where only one file from an old path, +# src/crypto/ed25519/internal/edwards25519/const.go, would still exist in the +# filtered repo. +git -C "$TMPDIR" replace --graft f771edd7f9 99f1bf54eb +git -C "$TMPDIR" replace --graft 109c13b64f c2f96e686f +git -C "$TMPDIR" replace --graft aa4da4f189 912f075047 + +git -C "$TMPDIR" filter-repo --force \ + --paths-from-file /dev/stdin \ + --prune-empty always \ + --prune-degenerate always \ + --tag-callback 'tag.skip()' <<'EOF' +src/crypto/internal/fips140/edwards25519 +src/crypto/internal/edwards25519 +src/crypto/ed25519/internal/edwards25519 +EOF + +git fetch "$TMPDIR" +git update-ref "refs/heads/upstream/$TAG" FETCH_HEAD + +echo +echo "Fetched upstream history up to $TAG. Merge with:" +echo -e "\tgit merge --no-ff --no-commit --allow-unrelated-histories upstream/$TAG" diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/scalar.go b/plugins/traefik/vendor/filippo.io/edwards25519/scalar.go index 3fd165387..f08b26245 100644 --- a/plugins/traefik/vendor/filippo.io/edwards25519/scalar.go +++ b/plugins/traefik/vendor/filippo.io/edwards25519/scalar.go @@ -7,6 +7,7 @@ package edwards25519 import ( "encoding/binary" "errors" + "math/bits" ) // A Scalar is an integer modulo @@ -179,15 +180,23 @@ func isReduced(s []byte) bool { return false } - for i := len(s) - 1; i >= 0; i-- { - switch { - case s[i] > scalarMinusOneBytes[i]: - return false - case s[i] < scalarMinusOneBytes[i]: - return true - } - } - return true + s0 := binary.LittleEndian.Uint64(s[:8]) + s1 := binary.LittleEndian.Uint64(s[8:16]) + s2 := binary.LittleEndian.Uint64(s[16:24]) + s3 := binary.LittleEndian.Uint64(s[24:]) + + l0 := binary.LittleEndian.Uint64(scalarMinusOneBytes[:8]) + l1 := binary.LittleEndian.Uint64(scalarMinusOneBytes[8:16]) + l2 := binary.LittleEndian.Uint64(scalarMinusOneBytes[16:24]) + l3 := binary.LittleEndian.Uint64(scalarMinusOneBytes[24:]) + + // Do a constant time subtraction chain scalarMinusOneBytes - s. If there is + // a borrow at the end, then s > scalarMinusOneBytes. + _, b := bits.Sub64(l0, s0, 0) + _, b = bits.Sub64(l1, s1, b) + _, b = bits.Sub64(l2, s2, b) + _, b = bits.Sub64(l3, s3, b) + return b == 0 } // SetBytesWithClamping applies the buffer pruning described in RFC 8032, diff --git a/plugins/traefik/vendor/filippo.io/edwards25519/tables.go b/plugins/traefik/vendor/filippo.io/edwards25519/tables.go index 83234bbc0..4a2b54eba 100644 --- a/plugins/traefik/vendor/filippo.io/edwards25519/tables.go +++ b/plugins/traefik/vendor/filippo.io/edwards25519/tables.go @@ -4,9 +4,7 @@ package edwards25519 -import ( - "crypto/subtle" -) +import "crypto/subtle" // A dynamic lookup table for variable-base, constant-time scalar muls. type projLookupTable struct { diff --git a/plugins/traefik/vendor/github.com/KimMachineGun/automemlimit/memlimit/cgroups.go b/plugins/traefik/vendor/github.com/KimMachineGun/automemlimit/memlimit/cgroups.go index 73a57c3eb..2f0a84043 100644 --- a/plugins/traefik/vendor/github.com/KimMachineGun/automemlimit/memlimit/cgroups.go +++ b/plugins/traefik/vendor/github.com/KimMachineGun/automemlimit/memlimit/cgroups.go @@ -103,8 +103,8 @@ func getMemoryLimitV2(chs []cgroupHierarchy, mis []mountInfo) (uint64, error) { return 0, err } - // retrieve the memory limit from the memory.max file - return readMemoryLimitV2FromPath(filepath.Join(cgroupPath, "memory.max")) + // retrieve the memory limit from the memory.max recursively. + return walkCgroupV2Hierarchy(cgroupPath, mountPoint) } // readMemoryLimitV2FromPath reads the memory limit for cgroup v2 from the given path. @@ -131,6 +131,39 @@ func readMemoryLimitV2FromPath(path string) (uint64, error) { return limit, nil } +// walkCgroupV2Hierarchy walks up the cgroup v2 hierarchy to find the most restrictive memory limit. +func walkCgroupV2Hierarchy(cgroupPath, mountPoint string) (uint64, error) { + var ( + found = false + minLimit uint64 = math.MaxUint64 + currentPath = cgroupPath + ) + for { + limit, err := readMemoryLimitV2FromPath(filepath.Join(currentPath, "memory.max")) + if err != nil && !errors.Is(err, ErrNoLimit) { + return 0, err + } else if err == nil { + found = true + minLimit = min(minLimit, limit) + } + + if currentPath == mountPoint { + break + } + + parent := filepath.Dir(currentPath) + if parent == currentPath { + break + } + currentPath = parent + } + if !found { + return 0, ErrNoLimit + } + + return minLimit, nil +} + // getMemoryLimitV1 retrieves the memory limit from the cgroup v1 controller. func getMemoryLimitV1(chs []cgroupHierarchy, mis []mountInfo) (uint64, error) { // find the cgroup v1 path for the memory controller. @@ -157,7 +190,7 @@ func getMemoryLimitV1(chs []cgroupHierarchy, mis []mountInfo) (uint64, error) { return 0, err } - // retrieve the memory limit from the memory.stats and memory.limit_in_bytes files. + // retrieve the memory limit from the memory.stat and memory.limit_in_bytes files. return readMemoryLimitV1FromPath(cgroupPath) } @@ -173,7 +206,7 @@ func getCgroupV1NoLimit() uint64 { func readMemoryLimitV1FromPath(cgroupPath string) (uint64, error) { // read hierarchical_memory_limit and memory.limit_in_bytes files. // but if hierarchical_memory_limit is not available, then use the max value as a fallback. - hml, err := readHierarchicalMemoryLimit(filepath.Join(cgroupPath, "memory.stats")) + hml, err := readHierarchicalMemoryLimit(filepath.Join(cgroupPath, "memory.stat")) if err != nil && !errors.Is(err, os.ErrNotExist) { return 0, fmt.Errorf("failed to read hierarchical_memory_limit: %w", err) } else if hml == 0 { @@ -202,8 +235,8 @@ func readMemoryLimitV1FromPath(cgroupPath string) (uint64, error) { return limit, nil } -// readHierarchicalMemoryLimit extracts hierarchical_memory_limit from memory.stats. -// this function expects the path to be memory.stats file. +// readHierarchicalMemoryLimit extracts hierarchical_memory_limit from memory.stat. +// this function expects the path to be memory.stat file. func readHierarchicalMemoryLimit(path string) (uint64, error) { file, err := os.Open(path) if err != nil { @@ -217,12 +250,12 @@ func readHierarchicalMemoryLimit(path string) (uint64, error) { fields := strings.Split(line, " ") if len(fields) < 2 { - return 0, fmt.Errorf("failed to parse memory.stats %q: not enough fields", line) + return 0, fmt.Errorf("failed to parse memory.stat %q: not enough fields", line) } if fields[0] == "hierarchical_memory_limit" { if len(fields) > 2 { - return 0, fmt.Errorf("failed to parse memory.stats %q: too many fields for hierarchical_memory_limit", line) + return 0, fmt.Errorf("failed to parse memory.stat %q: too many fields for hierarchical_memory_limit", line) } return strconv.ParseUint(fields[1], 10, 64) } @@ -276,11 +309,9 @@ func parseMountInfoLine(line string) (mountInfo, error) { fields1 = append(fields1, "") } - fields2 := strings.Split(fieldss[1], " ") + fields2 := strings.SplitN(fieldss[1], " ", 3) if len(fields2) < 3 { return mountInfo{}, fmt.Errorf("not enough fields after separator: %v", fields2) - } else if len(fields2) > 3 { - return mountInfo{}, fmt.Errorf("too many fields after separator: %v", fields2) } return mountInfo{ diff --git a/plugins/traefik/vendor/github.com/KimMachineGun/automemlimit/memlimit/memlimit.go b/plugins/traefik/vendor/github.com/KimMachineGun/automemlimit/memlimit/memlimit.go index cbd53ce3a..b23980a51 100644 --- a/plugins/traefik/vendor/github.com/KimMachineGun/automemlimit/memlimit/memlimit.go +++ b/plugins/traefik/vendor/github.com/KimMachineGun/automemlimit/memlimit/memlimit.go @@ -169,7 +169,7 @@ func SetGoMemLimitWithOpts(opts ...Option) (_ int64, _err error) { // set the memory limit and start refresh limit, err := updateGoMemLimit(uint64(snapshot), provider, cfg.logger) - go refresh(provider, cfg.logger, cfg.refresh) + refresh(provider, cfg.logger, cfg.refresh) if err != nil { if errors.Is(err, ErrNoLimit) { cfg.logger.Info("memory is not limited, skipping") @@ -200,7 +200,7 @@ func updateGoMemLimit(currLimit uint64, provider Provider, logger *slog.Logger) return newLimit, nil } -// refresh periodically fetches the memory limit from the provider and reapplies it if it has changed. +// refresh spawns a goroutine that runs every refresh duration and updates the GOMEMLIMIT if it has changed. // See more details in the documentation of WithRefreshInterval. func refresh(provider Provider, logger *slog.Logger, refresh time.Duration) { if refresh == 0 { @@ -210,22 +210,24 @@ func refresh(provider Provider, logger *slog.Logger, refresh time.Duration) { provider = noErrNoLimitProvider(provider) t := time.NewTicker(refresh) - for range t.C { - err := func() (_err error) { - snapshot := debug.SetMemoryLimit(-1) - defer rollbackOnPanic(logger, snapshot, &_err) - - _, err := updateGoMemLimit(uint64(snapshot), provider, logger) + go func() { + for range t.C { + err := func() (_err error) { + snapshot := debug.SetMemoryLimit(-1) + defer rollbackOnPanic(logger, snapshot, &_err) + + _, err := updateGoMemLimit(uint64(snapshot), provider, logger) + if err != nil { + return err + } + + return nil + }() if err != nil { - return err + logger.Error("failed to refresh GOMEMLIMIT", slog.Any("error", err)) } - - return nil - }() - if err != nil { - logger.Error("failed to refresh GOMEMLIMIT", slog.Any("error", err)) } - } + }() } // rollbackOnPanic rollbacks to the snapshot on panic. diff --git a/plugins/traefik/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md b/plugins/traefik/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md index f95a504fe..fabe5e43d 100644 --- a/plugins/traefik/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md +++ b/plugins/traefik/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md @@ -1,5 +1,31 @@ # Changelog +## 3.4.0 (2025-06-27) + +### Added + +- #268: Added property to Constraints to include prereleases for Check and Validate + +### Changed + +- #263: Updated Go testing for 1.24, 1.23, and 1.22 +- #269: Updated the error message handling for message case and wrapping errors +- #266: Restore the ability to have leading 0's when parsing with NewVersion. + Opt-out of this by setting CoerceNewVersion to false. + +### Fixed + +- #257: Fixed the CodeQL link (thanks @dmitris) +- #262: Restored detailed errors when failed to parse with NewVersion. Opt-out + of this by setting DetailedNewVersionErrors to false for faster performance. +- #267: Handle pre-releases for an "and" group if one constraint includes them + +## 3.3.1 (2024-11-19) + +### Fixed + +- #253: Fix for allowing some version that were invalid + ## 3.3.0 (2024-08-27) ### Added @@ -137,7 +163,7 @@ functions. These are described in the added and changed sections below. - #78: Fix unchecked error in example code (thanks @ravron) - #70: Fix the handling of pre-releases and the 0.0.0 release edge case - #97: Fixed copyright file for proper display on GitHub -- #107: Fix handling prerelease when sorting alphanum and num +- #107: Fix handling prerelease when sorting alphanum and num - #109: Fixed where Validate sometimes returns wrong message on error ## 1.4.2 (2018-04-10) diff --git a/plugins/traefik/vendor/github.com/Masterminds/semver/v3/README.md b/plugins/traefik/vendor/github.com/Masterminds/semver/v3/README.md index ed5693608..2f56c676a 100644 --- a/plugins/traefik/vendor/github.com/Masterminds/semver/v3/README.md +++ b/plugins/traefik/vendor/github.com/Masterminds/semver/v3/README.md @@ -50,6 +50,18 @@ other versions, convert the version back into a string, and get the original string. Getting the original string is useful if the semantic version was coerced into a valid form. +There are package level variables that affect how `NewVersion` handles parsing. + +- `CoerceNewVersion` is `true` by default. When set to `true` it coerces non-compliant + versions into SemVer. For example, allowing a leading 0 in a major, minor, or patch + part. This enables the use of CalVer in versions even when not compliant with SemVer. + When set to `false` less coercion work is done. +- `DetailedNewVersionErrors` provides more detailed errors. It only has an affect when + `CoerceNewVersion` is set to `false`. When `DetailedNewVersionErrors` is set to `true` + it can provide some more insight into why a version is invalid. Setting + `DetailedNewVersionErrors` to `false` is faster on performance but provides less + detailed error messages if a version fails to parse. + ## Sorting Semantic Versions A set of versions can be sorted using the `sort` package from the standard library. @@ -160,6 +172,10 @@ means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case sensitivity doesn't apply here. This is due to ASCII sort ordering which is what the spec specifies. +The `Constraints` instance returned from `semver.NewConstraint()` has a property +`IncludePrerelease` that, when set to true, will return prerelease versions when calls +to `Check()` and `Validate()` are made. + ### Hyphen Range Comparisons There are multiple methods to handle ranges and the first is hyphens ranges. @@ -250,7 +266,7 @@ or [create a pull request](https://github.com/Masterminds/semver/pulls). Security is an important consideration for this project. The project currently uses the following tools to help discover security issues: -* [CodeQL](https://github.com/Masterminds/semver) +* [CodeQL](https://codeql.github.com) * [gosec](https://github.com/securego/gosec) * Daily Fuzz testing diff --git a/plugins/traefik/vendor/github.com/Masterminds/semver/v3/constraints.go b/plugins/traefik/vendor/github.com/Masterminds/semver/v3/constraints.go index 8461c7ed9..8b7a10f83 100644 --- a/plugins/traefik/vendor/github.com/Masterminds/semver/v3/constraints.go +++ b/plugins/traefik/vendor/github.com/Masterminds/semver/v3/constraints.go @@ -12,6 +12,13 @@ import ( // checked against. type Constraints struct { constraints [][]*constraint + containsPre []bool + + // IncludePrerelease specifies if pre-releases should be included in + // the results. Note, if a constraint range has a prerelease than + // prereleases will be included for that AND group even if this is + // set to false. + IncludePrerelease bool } // NewConstraint returns a Constraints instance that a Version instance can @@ -22,11 +29,10 @@ func NewConstraint(c string) (*Constraints, error) { c = rewriteRange(c) ors := strings.Split(c, "||") - or := make([][]*constraint, len(ors)) + lenors := len(ors) + or := make([][]*constraint, lenors) + hasPre := make([]bool, lenors) for k, v := range ors { - - // TODO: Find a way to validate and fetch all the constraints in a simpler form - // Validate the segment if !validConstraintRegex.MatchString(v) { return nil, fmt.Errorf("improper constraint: %s", v) @@ -43,12 +49,22 @@ func NewConstraint(c string) (*Constraints, error) { return nil, err } + // If one of the constraints has a prerelease record this. + // This information is used when checking all in an "and" + // group to ensure they all check for prereleases. + if pc.con.pre != "" { + hasPre[k] = true + } + result[i] = pc } or[k] = result } - o := &Constraints{constraints: or} + o := &Constraints{ + constraints: or, + containsPre: hasPre, + } return o, nil } @@ -57,10 +73,10 @@ func (cs Constraints) Check(v *Version) bool { // TODO(mattfarina): For v4 of this library consolidate the Check and Validate // functions as the underlying functions make that possible now. // loop over the ORs and check the inner ANDs - for _, o := range cs.constraints { + for i, o := range cs.constraints { joy := true for _, c := range o { - if check, _ := c.check(v); !check { + if check, _ := c.check(v, (cs.IncludePrerelease || cs.containsPre[i])); !check { joy = false break } @@ -83,12 +99,12 @@ func (cs Constraints) Validate(v *Version) (bool, []error) { // Capture the prerelease message only once. When it happens the first time // this var is marked var prerelesase bool - for _, o := range cs.constraints { + for i, o := range cs.constraints { joy := true for _, c := range o { // Before running the check handle the case there the version is // a prerelease and the check is not searching for prereleases. - if c.con.pre == "" && v.pre != "" { + if !(cs.IncludePrerelease || cs.containsPre[i]) && v.pre != "" { if !prerelesase { em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) e = append(e, em) @@ -98,7 +114,7 @@ func (cs Constraints) Validate(v *Version) (bool, []error) { } else { - if _, err := c.check(v); err != nil { + if _, err := c.check(v, (cs.IncludePrerelease || cs.containsPre[i])); err != nil { e = append(e, err) joy = false } @@ -227,8 +243,8 @@ type constraint struct { } // Check if a version meets the constraint -func (c *constraint) check(v *Version) (bool, error) { - return constraintOps[c.origfunc](v, c) +func (c *constraint) check(v *Version, includePre bool) (bool, error) { + return constraintOps[c.origfunc](v, c, includePre) } // String prints an individual constraint into a string @@ -236,7 +252,7 @@ func (c *constraint) string() string { return c.origfunc + c.orig } -type cfunc func(v *Version, c *constraint) (bool, error) +type cfunc func(v *Version, c *constraint, includePre bool) (bool, error) func parseConstraint(c string) (*constraint, error) { if len(c) > 0 { @@ -272,7 +288,7 @@ func parseConstraint(c string) (*constraint, error) { // The constraintRegex should catch any regex parsing errors. So, // we should never get here. - return nil, errors.New("constraint Parser Error") + return nil, errors.New("constraint parser error") } cs.con = con @@ -290,7 +306,7 @@ func parseConstraint(c string) (*constraint, error) { // The constraintRegex should catch any regex parsing errors. So, // we should never get here. - return nil, errors.New("constraint Parser Error") + return nil, errors.New("constraint parser error") } cs := &constraint{ @@ -305,16 +321,14 @@ func parseConstraint(c string) (*constraint, error) { } // Constraint functions -func constraintNotEqual(v *Version, c *constraint) (bool, error) { - if c.dirty { - - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } +func constraintNotEqual(v *Version, c *constraint, includePre bool) (bool, error) { + // The existence of prereleases is checked at the group level and passed in. + // Exit early if the version has a prerelease but those are to be ignored. + if v.Prerelease() != "" && !includePre { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + if c.dirty { if c.con.Major() != v.Major() { return true, nil } @@ -345,12 +359,11 @@ func constraintNotEqual(v *Version, c *constraint) (bool, error) { return true, nil } -func constraintGreaterThan(v *Version, c *constraint) (bool, error) { +func constraintGreaterThan(v *Version, c *constraint, includePre bool) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { + // The existence of prereleases is checked at the group level and passed in. + // Exit early if the version has a prerelease but those are to be ignored. + if v.Prerelease() != "" && !includePre { return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) } @@ -391,11 +404,10 @@ func constraintGreaterThan(v *Version, c *constraint) (bool, error) { return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) } -func constraintLessThan(v *Version, c *constraint) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { +func constraintLessThan(v *Version, c *constraint, includePre bool) (bool, error) { + // The existence of prereleases is checked at the group level and passed in. + // Exit early if the version has a prerelease but those are to be ignored. + if v.Prerelease() != "" && !includePre { return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) } @@ -406,12 +418,11 @@ func constraintLessThan(v *Version, c *constraint) (bool, error) { return false, fmt.Errorf("%s is greater than or equal to %s", v, c.orig) } -func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) { +func constraintGreaterThanEqual(v *Version, c *constraint, includePre bool) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { + // The existence of prereleases is checked at the group level and passed in. + // Exit early if the version has a prerelease but those are to be ignored. + if v.Prerelease() != "" && !includePre { return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) } @@ -422,11 +433,10 @@ func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) { return false, fmt.Errorf("%s is less than %s", v, c.orig) } -func constraintLessThanEqual(v *Version, c *constraint) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { +func constraintLessThanEqual(v *Version, c *constraint, includePre bool) (bool, error) { + // The existence of prereleases is checked at the group level and passed in. + // Exit early if the version has a prerelease but those are to be ignored. + if v.Prerelease() != "" && !includePre { return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) } @@ -455,11 +465,10 @@ func constraintLessThanEqual(v *Version, c *constraint) (bool, error) { // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0 // ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0 // ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0 -func constraintTilde(v *Version, c *constraint) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { +func constraintTilde(v *Version, c *constraint, includePre bool) (bool, error) { + // The existence of prereleases is checked at the group level and passed in. + // Exit early if the version has a prerelease but those are to be ignored. + if v.Prerelease() != "" && !includePre { return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) } @@ -487,16 +496,15 @@ func constraintTilde(v *Version, c *constraint) (bool, error) { // When there is a .x (dirty) status it automatically opts in to ~. Otherwise // it's a straight = -func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { +func constraintTildeOrEqual(v *Version, c *constraint, includePre bool) (bool, error) { + // The existence of prereleases is checked at the group level and passed in. + // Exit early if the version has a prerelease but those are to be ignored. + if v.Prerelease() != "" && !includePre { return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) } if c.dirty { - return constraintTilde(v, c) + return constraintTilde(v, c, includePre) } eq := v.Equal(c.con) @@ -516,11 +524,10 @@ func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) { // ^0.0.3 --> >=0.0.3 <0.0.4 // ^0.0 --> >=0.0.0 <0.1.0 // ^0 --> >=0.0.0 <1.0.0 -func constraintCaret(v *Version, c *constraint) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { +func constraintCaret(v *Version, c *constraint, includePre bool) (bool, error) { + // The existence of prereleases is checked at the group level and passed in. + // Exit early if the version has a prerelease but those are to be ignored. + if v.Prerelease() != "" && !includePre { return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) } diff --git a/plugins/traefik/vendor/github.com/Masterminds/semver/v3/version.go b/plugins/traefik/vendor/github.com/Masterminds/semver/v3/version.go index ff499fb66..7a3ba7388 100644 --- a/plugins/traefik/vendor/github.com/Masterminds/semver/v3/version.go +++ b/plugins/traefik/vendor/github.com/Masterminds/semver/v3/version.go @@ -14,32 +14,52 @@ import ( // The compiled version of the regex created at init() is cached here so it // only needs to be created once. var versionRegex *regexp.Regexp +var looseVersionRegex *regexp.Regexp + +// CoerceNewVersion sets if leading 0's are allowd in the version part. Leading 0's are +// not allowed in a valid semantic version. When set to true, NewVersion will coerce +// leading 0's into a valid version. +var CoerceNewVersion = true + +// DetailedNewVersionErrors specifies if detailed errors are returned from the NewVersion +// function. This is used when CoerceNewVersion is set to false. If set to false +// ErrInvalidSemVer is returned for an invalid version. This does not apply to +// StrictNewVersion. Setting this function to false returns errors more quickly. +var DetailedNewVersionErrors = true var ( // ErrInvalidSemVer is returned a version is found to be invalid when // being parsed. - ErrInvalidSemVer = errors.New("Invalid Semantic Version") + ErrInvalidSemVer = errors.New("invalid semantic version") // ErrEmptyString is returned when an empty string is passed in for parsing. - ErrEmptyString = errors.New("Version string empty") + ErrEmptyString = errors.New("version string empty") // ErrInvalidCharacters is returned when invalid characters are found as // part of a version - ErrInvalidCharacters = errors.New("Invalid characters in version") + ErrInvalidCharacters = errors.New("invalid characters in version") // ErrSegmentStartsZero is returned when a version segment starts with 0. // This is invalid in SemVer. - ErrSegmentStartsZero = errors.New("Version segment starts with 0") + ErrSegmentStartsZero = errors.New("version segment starts with 0") // ErrInvalidMetadata is returned when the metadata is an invalid format - ErrInvalidMetadata = errors.New("Invalid Metadata string") + ErrInvalidMetadata = errors.New("invalid metadata string") // ErrInvalidPrerelease is returned when the pre-release is an invalid format - ErrInvalidPrerelease = errors.New("Invalid Prerelease string") + ErrInvalidPrerelease = errors.New("invalid prerelease string") ) // semVerRegex is the regular expression used to parse a semantic version. -const semVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` + +// This is not the official regex from the semver spec. It has been modified to allow for loose handling +// where versions like 2.1 are detected. +const semVerRegex string = `v?(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:\.(0|[1-9]\d*))?` + + `(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?` + + `(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?` + +// looseSemVerRegex is a regular expression that lets invalid semver expressions through +// with enough detail that certain errors can be checked for. +const looseSemVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` + `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` @@ -53,6 +73,7 @@ type Version struct { func init() { versionRegex = regexp.MustCompile("^" + semVerRegex + "$") + looseVersionRegex = regexp.MustCompile("^" + looseSemVerRegex + "$") } const ( @@ -140,7 +161,80 @@ func StrictNewVersion(v string) (*Version, error) { // attempts to convert it to SemVer. If you want to validate it was a strict // semantic version at parse time see StrictNewVersion(). func NewVersion(v string) (*Version, error) { + if CoerceNewVersion { + return coerceNewVersion(v) + } m := versionRegex.FindStringSubmatch(v) + if m == nil { + + // Disabling detailed errors is first so that it is in the fast path. + if !DetailedNewVersionErrors { + return nil, ErrInvalidSemVer + } + + // Check for specific errors with the semver string and return a more detailed + // error. + m = looseVersionRegex.FindStringSubmatch(v) + if m == nil { + return nil, ErrInvalidSemVer + } + err := validateVersion(m) + if err != nil { + return nil, err + } + return nil, ErrInvalidSemVer + } + + sv := &Version{ + metadata: m[5], + pre: m[4], + original: v, + } + + var err error + sv.major, err = strconv.ParseUint(m[1], 10, 64) + if err != nil { + return nil, fmt.Errorf("error parsing version segment: %w", err) + } + + if m[2] != "" { + sv.minor, err = strconv.ParseUint(m[2], 10, 64) + if err != nil { + return nil, fmt.Errorf("error parsing version segment: %w", err) + } + } else { + sv.minor = 0 + } + + if m[3] != "" { + sv.patch, err = strconv.ParseUint(m[3], 10, 64) + if err != nil { + return nil, fmt.Errorf("error parsing version segment: %w", err) + } + } else { + sv.patch = 0 + } + + // Perform some basic due diligence on the extra parts to ensure they are + // valid. + + if sv.pre != "" { + if err = validatePrerelease(sv.pre); err != nil { + return nil, err + } + } + + if sv.metadata != "" { + if err = validateMetadata(sv.metadata); err != nil { + return nil, err + } + } + + return sv, nil +} + +func coerceNewVersion(v string) (*Version, error) { + m := looseVersionRegex.FindStringSubmatch(v) if m == nil { return nil, ErrInvalidSemVer } @@ -154,13 +248,13 @@ func NewVersion(v string) (*Version, error) { var err error sv.major, err = strconv.ParseUint(m[1], 10, 64) if err != nil { - return nil, fmt.Errorf("Error parsing version segment: %s", err) + return nil, fmt.Errorf("error parsing version segment: %w", err) } if m[2] != "" { sv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], "."), 10, 64) if err != nil { - return nil, fmt.Errorf("Error parsing version segment: %s", err) + return nil, fmt.Errorf("error parsing version segment: %w", err) } } else { sv.minor = 0 @@ -169,7 +263,7 @@ func NewVersion(v string) (*Version, error) { if m[3] != "" { sv.patch, err = strconv.ParseUint(strings.TrimPrefix(m[3], "."), 10, 64) if err != nil { - return nil, fmt.Errorf("Error parsing version segment: %s", err) + return nil, fmt.Errorf("error parsing version segment: %w", err) } } else { sv.patch = 0 @@ -612,7 +706,9 @@ func containsOnly(s string, comp string) bool { func validatePrerelease(p string) error { eparts := strings.Split(p, ".") for _, p := range eparts { - if containsOnly(p, num) { + if p == "" { + return ErrInvalidPrerelease + } else if containsOnly(p, num) { if len(p) > 1 && p[0] == '0' { return ErrSegmentStartsZero } @@ -631,9 +727,62 @@ func validatePrerelease(p string) error { func validateMetadata(m string) error { eparts := strings.Split(m, ".") for _, p := range eparts { - if !containsOnly(p, allowed) { + if p == "" { return ErrInvalidMetadata + } else if !containsOnly(p, allowed) { + return ErrInvalidMetadata + } + } + return nil +} + +// validateVersion checks for common validation issues but may not catch all errors +func validateVersion(m []string) error { + var err error + var v string + if m[1] != "" { + if len(m[1]) > 1 && m[1][0] == '0' { + return ErrSegmentStartsZero + } + _, err = strconv.ParseUint(m[1], 10, 64) + if err != nil { + return fmt.Errorf("error parsing version segment: %w", err) } } + + if m[2] != "" { + v = strings.TrimPrefix(m[2], ".") + if len(v) > 1 && v[0] == '0' { + return ErrSegmentStartsZero + } + _, err = strconv.ParseUint(v, 10, 64) + if err != nil { + return fmt.Errorf("error parsing version segment: %w", err) + } + } + + if m[3] != "" { + v = strings.TrimPrefix(m[3], ".") + if len(v) > 1 && v[0] == '0' { + return ErrSegmentStartsZero + } + _, err = strconv.ParseUint(v, 10, 64) + if err != nil { + return fmt.Errorf("error parsing version segment: %w", err) + } + } + + if m[5] != "" { + if err = validatePrerelease(m[5]); err != nil { + return err + } + } + + if m[8] != "" { + if err = validateMetadata(m[8]); err != nil { + return err + } + } + return nil } diff --git a/plugins/traefik/vendor/github.com/Microsoft/go-winio/tools.go b/plugins/traefik/vendor/github.com/Microsoft/go-winio/tools.go deleted file mode 100644 index 2aa045843..000000000 --- a/plugins/traefik/vendor/github.com/Microsoft/go-winio/tools.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build tools - -package winio - -import _ "golang.org/x/tools/cmd/stringer" diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/antlrdoc.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/antlrdoc.go index 3bb4fd7c4..48bd362bf 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/antlrdoc.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/antlrdoc.go @@ -17,9 +17,9 @@ ANTLR4 that it is compatible with (I.E. uses the /v4 path). However, this was found to be problematic, as it meant that with the runtime embedded so far underneath the root of the repo, the `go get` and related commands could not properly resolve the location of the go runtime source code. This meant that the reference to the runtime in your `go.mod` file would refer to the correct source code, but would not -list the release tag such as @4.12.0 - this was confusing, to say the least. +list the release tag such as @4.13.1 - this was confusing, to say the least. -As of 4.12.1, the runtime is now available as a go module in its own repo, and can be imported as `github.com/antlr4-go/antlr` +As of 4.13.0, the runtime is now available as a go module in its own repo, and can be imported as `github.com/antlr4-go/antlr` (the go get command should also be used with this path). See the main documentation for the ANTLR4 project for more information, which is available at [ANTLR docs]. The documentation for using the Go runtime is available at [Go runtime docs]. @@ -49,7 +49,7 @@ Here is a general/recommended template for an ANTLR based recognizer in Go: . ├── parser │ ├── mygrammar.g4 - │ ├── antlr-4.12.1-complete.jar + │ ├── antlr-4.13.1-complete.jar │ ├── generate.go │ └── generate.sh ├── parsing - generated code goes here @@ -71,7 +71,7 @@ And the generate.sh file will look similar to this: #!/bin/sh - alias antlr4='java -Xmx500M -cp "./antlr4-4.12.1-complete.jar:$CLASSPATH" org.antlr.v4.Tool' + alias antlr4='java -Xmx500M -cp "./antlr4-4.13.1-complete.jar:$CLASSPATH" org.antlr.v4.Tool' antlr4 -Dlanguage=Go -no-visitor -package parsing *.g4 depending on whether you want visitors or listeners or any other ANTLR options. Not that another option here diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/atn.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/atn.go index cdeefed24..e749ebd0c 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/atn.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/atn.go @@ -4,8 +4,6 @@ package antlr -import "sync" - // ATNInvalidAltNumber is used to represent an ALT number that has yet to be calculated or // which is invalid for a particular struct such as [*antlr.BaseRuleContext] var ATNInvalidAltNumber int @@ -56,9 +54,9 @@ type ATN struct { // states []ATNState - mu sync.Mutex - stateMu sync.RWMutex - edgeMu sync.RWMutex + mu Mutex + stateMu RWMutex + edgeMu RWMutex } // NewATN returns a new ATN struct representing the given grammarType and is used diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/atn_config.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/atn_config.go index a83f25d34..267308bb3 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/atn_config.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/atn_config.go @@ -73,9 +73,6 @@ func NewATNConfig1(c *ATNConfig, state ATNState, context *PredictionContext) *AT // NewATNConfig creates a new ATNConfig instance given an existing config, a state, a context and a semantic context, other 'constructors' // are just wrappers around this one. func NewATNConfig(c *ATNConfig, state ATNState, context *PredictionContext, semanticContext SemanticContext) *ATNConfig { - if semanticContext == nil { - panic("semanticContext cannot be nil") // TODO: Remove this - probably put here for some bug that is now fixed - } b := &ATNConfig{} b.InitATNConfig(c, state, c.GetAlt(), context, semanticContext) b.cType = parserConfig diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/input_stream.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/input_stream.go index b737fe85f..ab4e96be5 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/input_stream.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/input_stream.go @@ -148,7 +148,7 @@ func (is *InputStream) GetTextFromInterval(i Interval) string { } func (*InputStream) GetSourceName() string { - return "" + return "Obtained from string" } // String returns the entire input stream as a string diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/jcollect.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/jcollect.go index ceccd96d2..6d668f798 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/jcollect.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/jcollect.go @@ -8,7 +8,6 @@ import ( "container/list" "runtime/debug" "sort" - "sync" ) // Collectable is an interface that a struct should implement if it is to be @@ -587,12 +586,12 @@ type VisitRecord struct { type VisitList struct { cache *list.List - lock sync.RWMutex + lock RWMutex } var visitListPool = VisitList{ cache: list.New(), - lock: sync.RWMutex{}, + lock: RWMutex{}, } // NewVisitRecord returns a new VisitRecord instance from the pool if available. diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/lexer.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/lexer.go index 3c7896a91..e5594b216 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/lexer.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/lexer.go @@ -207,7 +207,7 @@ func (b *BaseLexer) NextToken() Token { for { b.thetype = TokenInvalidType - ttype := b.safeMatch() + ttype := b.safeMatch() // Defaults to LexerSkip if b.input.LA(1) == TokenEOF { b.hitEOF = true diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/ll1_analyzer.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/ll1_analyzer.go index 4955ac876..dfdff000b 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/ll1_analyzer.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/ll1_analyzer.go @@ -40,6 +40,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet { for alt := 0; alt < count; alt++ { look[alt] = NewIntervalSet() + // TODO: This is one of the reasons that ATNConfigs are allocated and freed all the time - fix this tomorrow jim! lookBusy := NewJStore[*ATNConfig, Comparator[*ATNConfig]](aConfEqInst, ClosureBusyCollection, "LL1Analyzer.getDecisionLookahead for lookBusy") la.look1(s.GetTransitions()[alt].getTarget(), nil, BasePredictionContextEMPTY, look[alt], lookBusy, NewBitSet(), false, false) diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/mutex.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/mutex.go new file mode 100644 index 000000000..2b0cda474 --- /dev/null +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/mutex.go @@ -0,0 +1,41 @@ +//go:build !antlr.nomutex +// +build !antlr.nomutex + +package antlr + +import "sync" + +// Mutex is a simple mutex implementation which just delegates to sync.Mutex, it +// is used to provide a mutex implementation for the antlr package, which users +// can turn off with the build tag -tags antlr.nomutex +type Mutex struct { + mu sync.Mutex +} + +func (m *Mutex) Lock() { + m.mu.Lock() +} + +func (m *Mutex) Unlock() { + m.mu.Unlock() +} + +type RWMutex struct { + mu sync.RWMutex +} + +func (m *RWMutex) Lock() { + m.mu.Lock() +} + +func (m *RWMutex) Unlock() { + m.mu.Unlock() +} + +func (m *RWMutex) RLock() { + m.mu.RLock() +} + +func (m *RWMutex) RUnlock() { + m.mu.RUnlock() +} diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/mutex_nomutex.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/mutex_nomutex.go new file mode 100644 index 000000000..35ce4353e --- /dev/null +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/mutex_nomutex.go @@ -0,0 +1,32 @@ +//go:build antlr.nomutex +// +build antlr.nomutex + +package antlr + +type Mutex struct{} + +func (m *Mutex) Lock() { + // No-op +} + +func (m *Mutex) Unlock() { + // No-op +} + +type RWMutex struct{} + +func (m *RWMutex) Lock() { + // No-op +} + +func (m *RWMutex) Unlock() { + // No-op +} + +func (m *RWMutex) RLock() { + // No-op +} + +func (m *RWMutex) RUnlock() { + // No-op +} diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/parser_atn_simulator.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/parser_atn_simulator.go index ae2869692..724fa17a1 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/parser_atn_simulator.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/parser_atn_simulator.go @@ -10,8 +10,6 @@ import ( "strings" ) -var () - // ClosureBusy is a store of ATNConfigs and is a tiny abstraction layer over // a standard JStore so that we can use Lazy instantiation of the JStore, mostly // to avoid polluting the stats module with a ton of JStore instances with nothing in them. @@ -883,7 +881,7 @@ func (p *ParserATNSimulator) getPredicatePredictions(ambigAlts *BitSet, altToPre // the ERROR state was reached, outerContext as the initial parser context from the paper // or the parser stack at the instant before prediction commences. // -// Teh func returns the value to return from [AdaptivePredict], or +// The func returns the value to return from [AdaptivePredict], or // [ATNInvalidAltNumber] if a suitable alternative was not // identified and [AdaptivePredict] should report an error instead. func (p *ParserATNSimulator) getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(configs *ATNConfigSet, outerContext ParserRuleContext) int { diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/prediction_context.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/prediction_context.go index c1b80cc1f..a1d5186b8 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/prediction_context.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/prediction_context.go @@ -6,7 +6,6 @@ package antlr import ( "fmt" - "golang.org/x/exp/slices" "strconv" ) @@ -101,7 +100,7 @@ func NewArrayPredictionContext(parents []*PredictionContext, returnStates []int) hash = murmurUpdate(hash, returnState) } hash = murmurFinish(hash, len(parents)<<1) - + nec := &PredictionContext{} nec.cachedHash = hash nec.pcType = PredictionContextArray @@ -115,6 +114,9 @@ func (p *PredictionContext) Hash() int { } func (p *PredictionContext) Equals(other Collectable[*PredictionContext]) bool { + if p == other { + return true + } switch p.pcType { case PredictionContextEmpty: otherP := other.(*PredictionContext) @@ -138,13 +140,11 @@ func (p *PredictionContext) ArrayEquals(o Collectable[*PredictionContext]) bool if p.cachedHash != other.Hash() { return false // can't be same if hash is different } - + // Must compare the actual array elements and not just the array address // - return slices.Equal(p.returnStates, other.returnStates) && - slices.EqualFunc(p.parents, other.parents, func(x, y *PredictionContext) bool { - return x.Equals(y) - }) + return intSlicesEqual(p.returnStates, other.returnStates) && + pcSliceEqual(p.parents, other.parents) } func (p *PredictionContext) SingletonEquals(other Collectable[*PredictionContext]) bool { @@ -152,23 +152,23 @@ func (p *PredictionContext) SingletonEquals(other Collectable[*PredictionContext return false } otherP := other.(*PredictionContext) - if otherP == nil { + if otherP == nil || otherP.pcType != PredictionContextSingleton { return false } - + if p.cachedHash != otherP.Hash() { return false // Can't be same if hash is different } - + if p.returnState != otherP.getReturnState(0) { return false } - + // Both parents must be nil if one is if p.parentCtx == nil { return otherP.parentCtx == nil } - + return p.parentCtx.Equals(otherP.parentCtx) } @@ -225,27 +225,27 @@ func (p *PredictionContext) String() string { return "$" case PredictionContextSingleton: var up string - + if p.parentCtx == nil { up = "" } else { up = p.parentCtx.String() } - + if len(up) == 0 { if p.returnState == BasePredictionContextEmptyReturnState { return "$" } - + return strconv.Itoa(p.returnState) } - + return strconv.Itoa(p.returnState) + " " + up case PredictionContextArray: if p.isEmpty() { return "[]" } - + s := "[" for i := 0; i < len(p.returnStates); i++ { if i > 0 { @@ -263,7 +263,7 @@ func (p *PredictionContext) String() string { } } return s + "]" - + default: return "unknown" } @@ -309,18 +309,18 @@ func predictionContextFromRuleContext(a *ATN, outerContext RuleContext) *Predict parent := predictionContextFromRuleContext(a, outerContext.GetParent().(RuleContext)) state := a.states[outerContext.GetInvokingState()] transition := state.GetTransitions()[0] - + return SingletonBasePredictionContextCreate(parent, transition.(*RuleTransition).followState.GetStateNumber()) } func merge(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMap) *PredictionContext { - + // Share same graph if both same // if a == b || a.Equals(b) { return a } - + if a.pcType == PredictionContextSingleton && b.pcType == PredictionContextSingleton { return mergeSingletons(a, b, rootIsWildcard, mergeCache) } @@ -334,7 +334,7 @@ func merge(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMap) *Pr return b } } - + // Convert either Singleton or Empty to arrays, so that we can merge them // ara := convertToArray(a) @@ -395,7 +395,7 @@ func mergeSingletons(a, b *PredictionContext, rootIsWildcard bool, mergeCache *J return previous } } - + rootMerge := mergeRoot(a, b, rootIsWildcard) if rootMerge != nil { if mergeCache != nil { @@ -564,7 +564,7 @@ func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMa i := 0 // walks a j := 0 // walks b k := 0 // walks target M array - + mergedReturnStates := make([]int, len(a.returnStates)+len(b.returnStates)) mergedParents := make([]*PredictionContext, len(a.returnStates)+len(b.returnStates)) // walk and merge to yield mergedParents, mergedReturnStates @@ -626,9 +626,9 @@ func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMa mergedParents = mergedParents[0:k] mergedReturnStates = mergedReturnStates[0:k] } - + M := NewArrayPredictionContext(mergedParents, mergedReturnStates) - + // if we created same array as a or b, return that instead // TODO: JI track whether this is possible above during merge sort for speed and possibly avoid an allocation if M.Equals(a) { @@ -650,7 +650,7 @@ func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMa return b } combineCommonParents(&mergedParents) - + if mergeCache != nil { mergeCache.Put(a, b, M) } @@ -666,7 +666,7 @@ func mergeArrays(a, b *PredictionContext, rootIsWildcard bool, mergeCache *JPCMa //goland:noinspection GoUnusedFunction func combineCommonParents(parents *[]*PredictionContext) { uniqueParents := NewJStore[*PredictionContext, Comparator[*PredictionContext]](pContextEqInst, PredictionContextCollection, "combineCommonParents for PredictionContext") - + for p := 0; p < len(*parents); p++ { parent := (*parents)[p] _, _ = uniqueParents.Put(parent) @@ -685,7 +685,7 @@ func getCachedBasePredictionContext(context *PredictionContext, contextCache *Pr if present { return existing } - + existing, present = contextCache.Get(context) if present { visited.Put(context, existing) @@ -722,6 +722,6 @@ func getCachedBasePredictionContext(context *PredictionContext, contextCache *Pr contextCache.add(updated) visited.Put(updated, updated) visited.Put(context, updated) - + return updated } diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/recognizer.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/recognizer.go index 2e0b504fb..dcb8548cd 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/recognizer.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/recognizer.go @@ -56,7 +56,7 @@ var tokenTypeMapCache = make(map[string]int) var ruleIndexMapCache = make(map[string]int) func (b *BaseRecognizer) checkVersion(toolVersion string) { - runtimeVersion := "4.12.0" + runtimeVersion := "4.13.1" if runtimeVersion != toolVersion { fmt.Println("ANTLR runtime and generated code versions disagree: " + runtimeVersion + "!=" + toolVersion) } diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/statistics.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/statistics.go index 70c0673a0..8cb5f3ed6 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/statistics.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/statistics.go @@ -9,7 +9,6 @@ import ( "path/filepath" "sort" "strconv" - "sync" ) // This file allows the user to collect statistics about the runtime of the ANTLR runtime. It is not enabled by default @@ -30,7 +29,7 @@ type goRunStats struct { // within this package. // jStats []*JStatRec - jStatsLock sync.RWMutex + jStatsLock RWMutex topN int topNByMax []*JStatRec topNByUsed []*JStatRec diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/token.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/token.go index 9670efb82..f5bc34229 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/token.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/token.go @@ -104,6 +104,25 @@ func (b *BaseToken) GetSource() *TokenSourceCharStreamPair { return b.source } +func (b *BaseToken) GetText() string { + if b.text != "" { + return b.text + } + input := b.GetInputStream() + if input == nil { + return "" + } + n := input.Size() + if b.GetStart() < n && b.GetStop() < n { + return input.GetTextFromInterval(NewInterval(b.GetStart(), b.GetStop())) + } + return "" +} + +func (b *BaseToken) SetText(text string) { + b.text = text +} + func (b *BaseToken) GetTokenIndex() int { return b.tokenIndex } @@ -120,6 +139,28 @@ func (b *BaseToken) GetInputStream() CharStream { return b.source.charStream } +func (b *BaseToken) String() string { + txt := b.GetText() + if txt != "" { + txt = strings.Replace(txt, "\n", "\\n", -1) + txt = strings.Replace(txt, "\r", "\\r", -1) + txt = strings.Replace(txt, "\t", "\\t", -1) + } else { + txt = "" + } + + var ch string + if b.GetChannel() > 0 { + ch = ",channel=" + strconv.Itoa(b.GetChannel()) + } else { + ch = "" + } + + return "[@" + strconv.Itoa(b.GetTokenIndex()) + "," + strconv.Itoa(b.GetStart()) + ":" + strconv.Itoa(b.GetStop()) + "='" + + txt + "',<" + strconv.Itoa(b.GetTokenType()) + ">" + + ch + "," + strconv.Itoa(b.GetLine()) + ":" + strconv.Itoa(b.GetColumn()) + "]" +} + type CommonToken struct { BaseToken } @@ -170,44 +211,3 @@ func (c *CommonToken) clone() *CommonToken { t.text = c.GetText() return t } - -func (c *CommonToken) GetText() string { - if c.text != "" { - return c.text - } - input := c.GetInputStream() - if input == nil { - return "" - } - n := input.Size() - if c.start < n && c.stop < n { - return input.GetTextFromInterval(NewInterval(c.start, c.stop)) - } - return "" -} - -func (c *CommonToken) SetText(text string) { - c.text = text -} - -func (c *CommonToken) String() string { - txt := c.GetText() - if txt != "" { - txt = strings.Replace(txt, "\n", "\\n", -1) - txt = strings.Replace(txt, "\r", "\\r", -1) - txt = strings.Replace(txt, "\t", "\\t", -1) - } else { - txt = "" - } - - var ch string - if c.channel > 0 { - ch = ",channel=" + strconv.Itoa(c.channel) - } else { - ch = "" - } - - return "[@" + strconv.Itoa(c.tokenIndex) + "," + strconv.Itoa(c.start) + ":" + strconv.Itoa(c.stop) + "='" + - txt + "',<" + strconv.Itoa(c.tokenType) + ">" + - ch + "," + strconv.Itoa(c.line) + ":" + strconv.Itoa(c.column) + "]" -} diff --git a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/utils.go b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/utils.go index 733d7df9d..36a37f247 100644 --- a/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/utils.go +++ b/plugins/traefik/vendor/github.com/antlr4-go/antlr/v4/utils.go @@ -326,3 +326,56 @@ func isDirectory(dir string) (bool, error) { } return fileInfo.IsDir(), err } + +// intSlicesEqual returns true if the two slices of ints are equal, and is a little +// faster than slices.Equal. +func intSlicesEqual(s1, s2 []int) bool { + if s1 == nil && s2 == nil { + return true + } + if s1 == nil || s2 == nil { + return false + } + if len(s1) == 0 && len(s2) == 0 { + return true + } + + if len(s1) == 0 || len(s2) == 0 || len(s1) != len(s2) { + return false + } + // If the slices are using the same memory, then they are the same slice + if &s1[0] == &s2[0] { + return true + } + for i, v := range s1 { + if v != s2[i] { + return false + } + } + return true +} + +func pcSliceEqual(s1, s2 []*PredictionContext) bool { + if s1 == nil && s2 == nil { + return true + } + if s1 == nil || s2 == nil { + return false + } + if len(s1) == 0 && len(s2) == 0 { + return true + } + if len(s1) == 0 || len(s2) == 0 || len(s1) != len(s2) { + return false + } + // If the slices are using the same memory, then they are the same slice + if &s1[0] == &s2[0] { + return true + } + for i, v := range s1 { + if !v.Equals(s2[i]) { + return false + } + } + return true +} diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/.golangci.yml b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/.golangci.yml index aecff563e..e800788f5 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/.golangci.yml +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/.golangci.yml @@ -1,27 +1,19 @@ -linters-settings: - errcheck: - exclude-functions: - - fmt.* - - (go.uber.org/zap/zapcore.ObjectEncoder).AddObject - - (go.uber.org/zap/zapcore.ObjectEncoder).AddArray - gci: - sections: - - standard # Standard section: captures all standard packages. - - default # Default section: contains all imports that could not be matched to another section type. - - prefix(github.com/caddyserver/caddy/v2/cmd) # ensure that this is always at the top and always has a line break. - - prefix(github.com/caddyserver/caddy) # Custom section: groups all imports with the specified Prefix. - # Skip generated files. - # Default: true - skip-generated: true - # Enable custom order of sections. - # If `true`, make the section order the same as the order of `sections`. - # Default: false - custom-order: true - exhaustive: - ignore-enum-types: reflect.Kind|svc.Cmd - +version: "2" +run: + issues-exit-code: 1 + tests: false + build-tags: + - nobadger + - nomysql + - nopgx +output: + formats: + text: + path: stdout + print-linter-name: true + print-issued-lines: true linters: - disable-all: true + default: none enable: - asasalint - asciicheck @@ -35,148 +27,97 @@ linters: - errcheck - errname - exhaustive - - gci - - gofmt - - goimports - - gofumpt - gosec - - gosimple - govet - - ineffassign - importas + - ineffassign - misspell + - modernize - prealloc - promlinter - sloglint - sqlclosecheck - staticcheck - - tenv - testableexamples - testifylint - tparallel - - typecheck - unconvert - unused - wastedassign - whitespace - zerologlint - # these are implicitly disabled: - # - containedctx - # - contextcheck - # - cyclop - # - depguard - # - errchkjson - # - errorlint - # - exhaustruct - # - execinquery - # - exhaustruct - # - forbidigo - # - forcetypeassert - # - funlen - # - ginkgolinter - # - gocheckcompilerdirectives - # - gochecknoglobals - # - gochecknoinits - # - gochecksumtype - # - gocognit - # - goconst - # - gocritic - # - gocyclo - # - godot - # - godox - # - goerr113 - # - goheader - # - gomnd - # - gomoddirectives - # - gomodguard - # - goprintffuncname - # - gosmopolitan - # - grouper - # - inamedparam - # - interfacebloat - # - ireturn - # - lll - # - loggercheck - # - maintidx - # - makezero - # - mirror - # - musttag - # - nakedret - # - nestif - # - nilerr - # - nilnil - # - nlreturn - # - noctx - # - nolintlint - # - nonamedreturns - # - nosprintfhostport - # - paralleltest - # - perfsprint - # - predeclared - # - protogetter - # - reassign - # - revive - # - rowserrcheck - # - stylecheck - # - tagalign - # - tagliatelle - # - testpackage - # - thelper - # - unparam - # - usestdlibvars - # - varnamelen - # - wrapcheck - # - wsl - -run: - # default concurrency is a available CPU number. - # concurrency: 4 # explicitly omit this value to fully utilize available resources. - timeout: 5m - issues-exit-code: 1 - tests: false - -# output configuration options -output: - formats: - - format: 'colored-line-number' - print-issued-lines: true - print-linter-name: true - -issues: - exclude-rules: - - text: 'G115' # TODO: Either we should fix the issues or nuke the linter if it's bad - linters: - - gosec - # we aren't calling unknown URL - - text: 'G107' # G107: Url provided to HTTP request as taint input - linters: - - gosec - # as a web server that's expected to handle any template, this is totally in the hands of the user. - - text: 'G203' # G203: Use of unescaped data in HTML templates - linters: - - gosec - # we're shelling out to known commands, not relying on user-defined input. - - text: 'G204' # G204: Audit use of command execution - linters: - - gosec - # the choice of weakrand is deliberate, hence the named import "weakrand" - - path: modules/caddyhttp/reverseproxy/selectionpolicies.go - text: 'G404' # G404: Insecure random number source (rand) - linters: - - gosec - - path: modules/caddyhttp/reverseproxy/streaming.go - text: 'G404' # G404: Insecure random number source (rand) - linters: - - gosec - - path: modules/logging/filters.go - linters: - - dupl - - path: modules/caddyhttp/matchers.go - linters: - - dupl - - path: modules/caddyhttp/vars.go - linters: - - dupl - - path: _test\.go - linters: - - errcheck + settings: + staticcheck: + checks: ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022", "-QF1006", "-QF1008"] # default, and exclude 1 more undesired check + errcheck: + exclude-functions: + - fmt.* + - (go.uber.org/zap/zapcore.ObjectEncoder).AddObject + - (go.uber.org/zap/zapcore.ObjectEncoder).AddArray + exhaustive: + ignore-enum-types: reflect.Kind|svc.Cmd + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - linters: + - gosec + text: G115 # TODO: Either we should fix the issues or nuke the linter if it's bad + - linters: + - gosec + text: G107 # we aren't calling unknown URL + - linters: + - gosec + text: G203 # as a web server that's expected to handle any template, this is totally in the hands of the user. + - linters: + - gosec + text: G204 # we're shelling out to known commands, not relying on user-defined input. + - linters: + - gosec + # the choice of weakrand is deliberate, hence the named import "weakrand" + path: modules/caddyhttp/reverseproxy/selectionpolicies.go + text: G404 + - linters: + - gosec + path: modules/caddyhttp/reverseproxy/streaming.go + text: G404 + - linters: + - dupl + path: modules/logging/filters.go + - linters: + - dupl + path: modules/caddyhttp/matchers.go + - linters: + - dupl + path: modules/caddyhttp/vars.go + - linters: + - errcheck + path: _test\.go + paths: + - third_party$ + - builtin$ + - examples$ +formatters: + enable: + - gci + - gofmt + - gofumpt + - goimports + settings: + gci: + sections: + - standard # Standard section: captures all standard packages. + - default # Default section: contains all imports that could not be matched to another section type. + - prefix(github.com/caddyserver/caddy/v2/cmd) # ensure that this is always at the top and always has a line break. + - prefix(github.com/caddyserver/caddy) # Custom section: groups all imports with the specified Prefix. + custom-order: true + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/.goreleaser.yml b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/.goreleaser.yml index c7ed4b365..3c87131bd 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/.goreleaser.yml +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/.goreleaser.yml @@ -13,7 +13,7 @@ before: - cp cmd/caddy/main.go caddy-build/main.go - /bin/sh -c 'cd ./caddy-build && go mod init caddy' # prepare syso files for windows embedding - - /bin/sh -c 'for a in amd64 arm arm64; do XCADDY_SKIP_BUILD=1 GOOS=windows GOARCH=$a xcaddy build {{.Env.TAG}}; done' + - /bin/sh -c 'for a in amd64 arm64; do XCADDY_SKIP_BUILD=1 GOOS=windows GOARCH=$a xcaddy build {{.Env.TAG}}; done' - /bin/sh -c 'mv /tmp/buildenv_*/*.syso caddy-build' # GoReleaser doesn't seem to offer {{.Tag}} at this stage, so we have to embed it into the env # so we run: TAG=$(git describe --abbrev=0) goreleaser release --rm-dist --skip-publish --skip-validate @@ -67,6 +67,8 @@ builds: goarch: s390x - goos: windows goarch: riscv64 + - goos: windows + goarch: arm - goos: freebsd goarch: ppc64le - goos: freebsd diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/.pre-commit-config.yaml b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/.pre-commit-config.yaml new file mode 100644 index 000000000..a38a13da3 --- /dev/null +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/.pre-commit-config.yaml @@ -0,0 +1,20 @@ +repos: +- repo: https://github.com/gitleaks/gitleaks + rev: v8.16.3 + hooks: + - id: gitleaks +- repo: https://github.com/golangci/golangci-lint + rev: v1.52.2 + hooks: + - id: golangci-lint-config-verify + - id: golangci-lint + - id: golangci-lint-fmt +- repo: https://github.com/jumanjihouse/pre-commit-hooks + rev: 3.0.0 + hooks: + - id: shellcheck +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: end-of-file-fixer + - id: trailing-whitespace diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/AGENTS.md b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/AGENTS.md new file mode 100644 index 000000000..8b1b5eb8b --- /dev/null +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/AGENTS.md @@ -0,0 +1,217 @@ +# Caddy Project Guidelines + +## Mission + +**Every site on HTTPS.** Caddy is a security-first, modular, extensible server platform. + +## Code Style + +### Go Idioms + +Follow [Go Code Review Comments](https://go.dev/wiki/CodeReviewComments): + +- **Error flow**: Early return, indent error handling—not else blocks + ```go + if err != nil { + return err + } + // normal code + ``` +- **Naming**: initialisms (`URL`, `HTTP`, `ID`—not `Url`, `Http`, `Id`) +- **Receiver names**: 1–2 letters reflecting type (`c` for `Client`, `h` for `Handler`) +- **Error strings**: Lowercase, no trailing punctuation (`"something failed"` not `"Something failed."`) +- **Doc comments**: Full sentences starting with the name being documented + ```go + // Handler serves HTTP requests for the file server. + type Handler struct { ... } + ``` +- **Empty slices**: `var t []string` (nil slice), not `t := []string{}` (non-nil zero-length) +- **Don't panic**: Use error returns for normal error handling + +### Caddy Patterns + +**Module registration**: +```go +func init() { + caddy.RegisterModule(MyModule{}) +} + +func (MyModule) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + ID: "namespace.category.name", + New: func() caddy.Module { return new(MyModule) }, + } +} +``` + +**Module lifecycle**: `New()` → JSON unmarshal → `Provision()` → `Validate()` → use → `Cleanup()` + +**Interface guards** — compile-time verification that modules implement required interfaces: +```go +var ( + _ caddy.Provisioner = (*MyModule)(nil) + _ caddy.Validator = (*MyModule)(nil) + _ caddyfile.Unmarshaler = (*MyModule)(nil) +) +``` + +**Structured logging** — use the module-scoped logger from context: +```go +func (m *MyModule) Provision(ctx caddy.Context) error { + m.logger = ctx.Logger() + m.logger.Debug("provisioning", zap.String("field", m.Field)) + return nil +} +``` + +**Caddyfile support** — implement `UnmarshalCaddyfile(*caddyfile.Dispenser)` using the `Dispenser` API: +```go +// UnmarshalCaddyfile sets up the module from Caddyfile tokens. Syntax: +// +// directive [arg1] [arg2] { +// subdir value +// } +func (m *MyModule) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { + d.Next() // consume directive name + for d.NextArg() { + // handle inline arguments + } + for nesting := d.Nesting(); d.NextBlock(nesting); { + switch d.Val() { + case "subdir": + if !d.NextArg() { + return d.ArgErr() + } + m.Field = d.Val() + default: + return d.Errf("unrecognized subdirective: %s", d.Val()) + } + } + return nil +} +``` + +**Admin API**: Implement `caddy.AdminRouter` for custom endpoints. + +**Context**: Use `caddy.Context` for accessing other apps/modules and logging—don't store contexts in structs. + +## Architecture + +Caddy is built around a **module system** where everything is a module registered via `caddy.RegisterModule()`: + +- **Apps** (`caddy.App`): Top-level modules like `http`, `tls`, `pki` that Caddy loads and runs +- **Modules** (`caddy.Module`): Extensible components with namespaced IDs (e.g., `http.handlers.file_server`) +- **Configuration**: Native JSON with adapters (Caddyfile → JSON via `caddyconfig/httpcaddyfile`) + +| Directory | Purpose | +|-----------|---------| +| `modules/` | All standard modules (HTTP, TLS, PKI, etc.) | +| `modules/standard/imports.go` | Standard module registry | +| `caddyconfig/httpcaddyfile/` | Caddyfile → JSON adapter for HTTP | +| `caddytest/` | Test utilities and integration tests | +| `cmd/caddy/` | CLI entry point with module imports | + +### Critical Packages + +`caddyhttp` and `caddytls` require **extra scrutiny** in code review—these are security-critical. + +## Quality Gates + + +**All required before PR is merge-ready:** + +| Gate | Command | Notes | +|------|---------|-------| +| Tests pass | `go test -race -short ./...` | Race detection enabled | +| Lint clean | `golangci-lint run --timeout 10m` | No warnings in changed files | +| Builds | `go build ./...` | Must compile | +| Benchmarks | `go test -bench=. -benchmem` | Required for optimizations | + +CI runs tests on **Linux, macOS, and Windows**—ensure cross-platform compatibility. + +### Build & Test + +```bash +# Build +cd cmd/caddy && go build + +# Tests with race detection (matches CI) +go test -race -short ./... + +# Integration tests +go test ./caddytest/integration/... + +# Lint (matches CI) +golangci-lint run --timeout 10m +``` + +## Testing Conventions + +**Table-driven tests** (preferred pattern): +```go +func TestFeature(t *testing.T) { + for i, tc := range []struct { + input string + expected string + wantErr bool + }{ + {input: "valid", expected: "result", wantErr: false}, + {input: "invalid", expected: "", wantErr: true}, + } { + actual, err := Function(tc.input) + if tc.wantErr && err == nil { + t.Errorf("Test %d: expected error but got none", i) + } + if !tc.wantErr && err != nil { + t.Errorf("Test %d: unexpected error: %v", i, err) + } + if actual != tc.expected { + t.Errorf("Test %d: expected %q, got %q", i, tc.expected, actual) + } + } +} +``` + +**Integration tests** use `caddytest.Tester`: +```go +func TestHTTPFeature(t *testing.T) { + tester := caddytest.NewTester(t) + tester.InitServer(` + { + admin localhost:2999 + http_port 9080 + } + localhost:9080 { + respond "hello" + }`, "caddyfile") + + tester.AssertGetResponse("http://localhost:9080/", 200, "hello") +} +``` + +Use non-standard ports (9080, 9443, 2999) to avoid conflicts with running servers. + +## AI Contribution Policy + +Per [CONTRIBUTING.md](.github/CONTRIBUTING.md), AI-assisted code **MUST** be: + +1. **Disclosed** — Tell reviewers when code was AI-generated or AI-assisted, mentioning which agent/model is used +2. **Fully comprehended** — You must be able to explain every line +3. **Tested** — Automated tests when feasible, thorough manual tests otherwise +4. **Licensed** — Verify AI output doesn't include plagiarized or incompatibly-licensed code +5. **Contributor License Agreement (CLA)** — The CLA must be signed by the human user + +**Do NOT submit code you cannot fully explain.** Contributors are responsible for their submissions. + +## Dependencies + +- **Avoid new dependencies** — Justify any additions; tiny deps can be inlined +- **No exported dependency types** — Caddy must not export types defined by external packages +- Use Go modules; check with `go mod tidy` + +## Further Reading + +- [CONTRIBUTING.md](.github/CONTRIBUTING.md) — Full PR process and expectations +- [Extending Caddy](https://caddyserver.com/docs/extending-caddy) — Module development guide +- [JSON Config](https://caddyserver.com/docs/json/) — Native configuration reference +- [Caddyfile](https://caddyserver.com/docs/caddyfile/concepts) — Caddyfile syntax guide diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/README.md b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/README.md index 4bebaafdb..508352c56 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/README.md +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/README.md @@ -12,23 +12,52 @@

Every site on HTTPS

Caddy is an extensible server platform that uses TLS by default.

+

+ Releases · + Documentation · + Get Help +

+   + +   -
+   @caddyserver on Twitter +   Caddy Forum
Caddy on Sourcegraph +   Cloudsmith

- Releases · - Documentation · - Get Help + Powered by +
+ + + + + CertMagic + +

+ +
+
+ Special thanks to: +
+ + Warp sponsorship + + +### [Warp, built for coding with multiple AI agents](https://go.warp.dev/caddy) +[Available for MacOS, Linux, & Windows](https://go.warp.dev/caddy)
+
+
### Menu @@ -43,18 +72,6 @@ - [Getting help](#getting-help) - [About](#about) -

- Powered by -
- - - - - CertMagic - - -

- ## [Features](https://caddyserver.com/features) @@ -88,7 +105,7 @@ See [our online documentation](https://caddyserver.com/docs/install) for other i Requirements: -- [Go 1.24.0 or newer](https://golang.org/dl/) +- [Go 1.25.0 or newer](https://golang.org/dl/) ### For development @@ -116,11 +133,18 @@ username ALL=(ALL:ALL) NOPASSWD: /usr/sbin/setcap replacing `username` with your actual username. Please be careful and only do this if you know what you are doing! We are only qualified to document how to use Caddy, not Go tooling or your computer, and we are providing these instructions for convenience only; please learn how to use your own computer at your own risk and make any needful adjustments. +Then you can run the tests in all modules or a specific one: + +```bash +$ go test ./... +$ go test ./modules/caddyhttp/tracing/ +``` + ### With version information and/or plugins Using [our builder tool, `xcaddy`](https://github.com/caddyserver/xcaddy)... -``` +```bash $ xcaddy build ``` @@ -196,6 +220,6 @@ Matthew Holt began developing Caddy in 2014 while studying computer science at B - _Project on X: [@caddyserver](https://x.com/caddyserver)_ - _Author on X: [@mholt6](https://x.com/mholt6)_ -Caddy is a project of [ZeroSSL](https://zerossl.com), a Stack Holdings company. +Caddy is a project of [ZeroSSL](https://zerossl.com), an HID Global company. Debian package repository hosting is graciously provided by [Cloudsmith](https://cloudsmith.com). Cloudsmith is the only fully hosted, cloud-native, universal package management solution, that enables your organization to create, store and share packages in any format, to any place, with total confidence. diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/admin.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/admin.go index 244c7d719..97af846ef 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/admin.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/admin.go @@ -45,8 +45,16 @@ import ( "github.com/prometheus/client_golang/prometheus" "go.uber.org/zap" "go.uber.org/zap/zapcore" + + "github.com/caddyserver/caddy/v2/internal" ) +// testCertMagicStorageOverride is a package-level test hook. Tests may set +// this variable to provide a temporary certmagic.Storage so that cert +// management in tests does not hit the real default storage on disk. +// This must NOT be set in production code. +var testCertMagicStorageOverride certmagic.Storage + func init() { // The hard-coded default `DefaultAdminListen` can be overridden // by setting the `CADDY_ADMIN` environment variable. @@ -112,10 +120,6 @@ type AdminConfig struct { // // EXPERIMENTAL: This feature is subject to change. Remote *RemoteAdmin `json:"remote,omitempty"` - - // Holds onto the routers so that we can later provision them - // if they require provisioning. - routers []AdminRouter } // ConfigSettings configures the management of configuration. @@ -204,8 +208,8 @@ type AdminAccess struct { // AdminPermissions specifies what kinds of requests are allowed // to be made to the admin endpoint. type AdminPermissions struct { - // The API paths allowed. Paths are simple prefix matches. - // Any subpath of the specified paths will be allowed. + // The API paths allowed. A request path must either equal an + // allowed path or be a subpath with a path-segment boundary. Paths []string `json:"paths,omitempty"` // The HTTP methods allowed for the given paths. @@ -214,7 +218,7 @@ type AdminPermissions struct { // newAdminHandler reads admin's config and returns an http.Handler suitable // for use in an admin endpoint server, which will be listening on listenAddr. -func (admin *AdminConfig) newAdminHandler(addr NetworkAddress, remote bool, _ Context) adminHandler { +func (admin *AdminConfig) newAdminHandler(addr NetworkAddress, remote bool, ctx Context) (adminHandler, error) { muxWrap := adminHandler{mux: http.NewServeMux()} // secure the local or remote endpoint respectively @@ -271,34 +275,21 @@ func (admin *AdminConfig) newAdminHandler(addr NetworkAddress, remote bool, _ Co // register third-party module endpoints for _, m := range GetModules("admin.api") { router := m.New().(AdminRouter) - for _, route := range router.Routes() { - addRoute(route.Pattern, handlerLabel, route.Handler) - } - admin.routers = append(admin.routers, router) - } - return muxWrap -} - -// provisionAdminRouters provisions all the router modules -// in the admin.api namespace that need provisioning. -func (admin *AdminConfig) provisionAdminRouters(ctx Context) error { - for _, router := range admin.routers { - provisioner, ok := router.(Provisioner) - if !ok { - continue + // provision the router before registering its routes, so + // handlers have access to all provisioned state + if provisioner, ok := router.(Provisioner); ok { + if err := provisioner.Provision(ctx); err != nil { + return adminHandler{}, fmt.Errorf("provisioning admin router module %s: %v", m.ID, err) + } } - err := provisioner.Provision(ctx) - if err != nil { - return err + for _, route := range router.Routes() { + addRoute(route.Pattern, handlerLabel, route.Handler) } } - // We no longer need the routers once provisioned, allow for GC - admin.routers = nil - - return nil + return muxWrap, nil } // allowedOrigins returns a list of origins that are allowed. @@ -422,7 +413,10 @@ func replaceLocalAdminServer(cfg *Config, ctx Context) error { return err } - handler := cfg.Admin.newAdminHandler(addr, false, ctx) + handler, err := cfg.Admin.newAdminHandler(addr, false, ctx) + if err != nil { + return err + } ln, err := addr.Listen(context.TODO(), 0, net.ListenConfig{}) if err != nil { @@ -543,7 +537,10 @@ func replaceRemoteAdminServer(ctx Context, cfg *Config) error { // make the HTTP handler but disable Host/Origin enforcement // because we are using TLS authentication instead - handler := cfg.Admin.newAdminHandler(addr, true, ctx) + handler, err := cfg.Admin.newAdminHandler(addr, true, ctx) + if err != nil { + return err + } // create client certificate pool for TLS mutual auth, and extract public keys // so that we can enforce access controls at the application layer @@ -619,8 +616,19 @@ func (ident *IdentityConfig) certmagicConfig(logger *zap.Logger, makeCache bool) // certmagic config, although it'll be mostly useless for remote management ident = new(IdentityConfig) } + // Choose storage: prefer the package-level test override when present, + // otherwise use the configured DefaultStorage. Tests may set an override + // to divert storage into a temporary location. Otherwise, in production + // we use the DefaultStorage since we don't want to act as part of a + // cluster; this storage is for the server's local identity only. + var storage certmagic.Storage + if testCertMagicStorageOverride != nil { + storage = testCertMagicStorageOverride + } else { + storage = DefaultStorage + } template := certmagic.Config{ - Storage: DefaultStorage, // do not act as part of a cluster (this is for the server's local identity) + Storage: storage, Logger: logger, Issuers: ident.issuers, } @@ -685,7 +693,7 @@ func (remote RemoteAdmin) enforceAccessControls(r *http.Request) error { // verify path pathFound := accessPerm.Paths == nil for _, allowedPath := range accessPerm.Paths { - if strings.HasPrefix(r.URL.Path, allowedPath) { + if adminPathAllowed(r.URL.Path, allowedPath) { pathFound = true break } @@ -714,14 +722,31 @@ func (remote RemoteAdmin) enforceAccessControls(r *http.Request) error { } } +func adminPathAllowed(reqPath, allowedPath string) bool { + if allowedPath == "" || allowedPath == "/" { + return strings.HasPrefix(reqPath, allowedPath) + } + if reqPath == allowedPath { + return true + } + if strings.HasSuffix(allowedPath, "/") { + return strings.HasPrefix(reqPath, allowedPath) + } + return strings.HasPrefix(reqPath, allowedPath+"/") +} + func stopAdminServer(srv *http.Server) error { if srv == nil { return fmt.Errorf("no admin server") } - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + timeout := 10 * time.Second + ctx, cancel := context.WithTimeoutCause(context.Background(), timeout, fmt.Errorf("stopping admin server: %ds timeout", int(timeout.Seconds()))) defer cancel() err := srv.Shutdown(ctx) if err != nil { + if cause := context.Cause(ctx); cause != nil && errors.Is(err, context.DeadlineExceeded) { + err = cause + } return fmt.Errorf("shutting down admin server: %v", err) } Log().Named("admin").Info("stopped previous server", zap.String("address", srv.Addr)) @@ -765,7 +790,7 @@ func (h adminHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { zap.String("uri", r.RequestURI), zap.String("remote_ip", ip), zap.String("remote_port", port), - zap.Reflect("headers", r.Header), + zap.Object("headers", internal.LoggableHTTPHeader{Header: r.Header}), ) if r.TLS != nil { log = log.With( @@ -793,11 +818,37 @@ func (h adminHandler) serveHTTP(w http.ResponseWriter, r *http.Request) { } } + // common mitigations in browser contexts if strings.Contains(r.Header.Get("Upgrade"), "websocket") { // I've never been able demonstrate a vulnerability myself, but apparently // WebSocket connections originating from browsers aren't subject to CORS // restrictions, so we'll just be on the safe side - h.handleError(w, r, fmt.Errorf("websocket connections aren't allowed")) + h.handleError(w, r, APIError{ + HTTPStatus: http.StatusBadRequest, + Err: errors.New("websocket connections aren't allowed"), + Message: "WebSocket connections aren't allowed.", + }) + return + } + if strings.Contains(r.Header.Get("Sec-Fetch-Mode"), "no-cors") { + // turns out web pages can just disable the same-origin policy (!???!?) + // but at least browsers let us know that's the case, holy heck + h.handleError(w, r, APIError{ + HTTPStatus: http.StatusBadRequest, + Err: errors.New("client attempted to make request by disabling same-origin policy using no-cors mode"), + Message: "Disabling same-origin restrictions is not allowed.", + }) + return + } + if r.Header.Get("Origin") == "null" { + // bug in Firefox in certain cross-origin situations (yikes?) + // (not strictly a security vuln on its own, but it's red flaggy, + // since it seems to manifest in cross-origin contexts) + h.handleError(w, r, APIError{ + HTTPStatus: http.StatusBadRequest, + Err: errors.New("invalid origin 'null'"), + Message: "Buggy browser is sending null Origin header.", + }) return } @@ -810,7 +861,9 @@ func (h adminHandler) serveHTTP(w http.ResponseWriter, r *http.Request) { } } - if h.enforceOrigin { + _, hasOriginHeader := r.Header["Origin"] + _, hasSecHeader := r.Header["Sec-Fetch-Mode"] + if h.enforceOrigin || hasOriginHeader || hasSecHeader { // cross-site mitigation origin, err := h.checkOrigin(r) if err != nil { @@ -932,7 +985,7 @@ func (h adminHandler) originAllowed(origin *url.URL) bool { return false } -// etagHasher returns a the hasher we used on the config to both +// etagHasher returns the hasher we used on the config to both // produce and verify ETags. func etagHasher() hash.Hash { return xxhash.New() } @@ -998,6 +1051,9 @@ func handleConfig(w http.ResponseWriter, r *http.Request) error { buf.Reset() defer bufPool.Put(buf) + const maxConfigSize = 100 * 1024 * 1024 // 100 MB + r.Body = http.MaxBytesReader(w, r.Body, maxConfigSize) + _, err := io.Copy(buf, r.Body) if err != nil { return APIError{ @@ -1015,6 +1071,13 @@ func handleConfig(w http.ResponseWriter, r *http.Request) error { return err } + // If this request changed the config, clear the last + // config info we have stored, if it is different from + // the original source. + ClearLastConfigIfDifferent( + r.Header.Get("Caddy-Config-Source-File"), + r.Header.Get("Caddy-Config-Source-Adapter")) + default: return APIError{ HTTPStatus: http.StatusMethodNotAllowed, @@ -1073,6 +1136,20 @@ func handleStop(w http.ResponseWriter, r *http.Request) error { return nil } +func parseCanonicalArrayIndex(idx string) (int, error) { + if idx == "" { + return 0, fmt.Errorf("empty index") + } + i, err := strconv.Atoi(idx) + if err != nil { + return 0, err + } + if strconv.Itoa(i) != idx { + return 0, fmt.Errorf("non-canonical array index") + } + return i, nil +} + // unsyncedConfigAccess traverses into the current config and performs // the operation at path according to method, using body and out as // needed. This is a low-level, unsynchronized function; most callers @@ -1089,7 +1166,10 @@ func unsyncedConfigAccess(method, path string, body []byte, out io.Writer) error if len(body) > 0 { err = json.Unmarshal(body, &val) if err != nil { - return fmt.Errorf("decoding request body: %v", err) + if jsonErr, ok := err.(*json.SyntaxError); ok { + return fmt.Errorf("decoding request body: %w, at offset %d", jsonErr, jsonErr.Offset) + } + return fmt.Errorf("decoding request body: %w", err) } } @@ -1131,11 +1211,12 @@ traverseLoop: var idx int if method != http.MethodPost { idxStr := parts[len(parts)-1] - idx, err = strconv.Atoi(idxStr) + idx, err = parseCanonicalArrayIndex(idxStr) if err != nil { return fmt.Errorf("[%s] invalid array index '%s': %v", path, idxStr, err) } + if idx < 0 || (method != http.MethodPut && idx >= len(arr)) || idx > len(arr) { return fmt.Errorf("[%s] array index out of bounds: %s", path, idxStr) } @@ -1235,7 +1316,7 @@ traverseLoop: } case []any: - partInt, err := strconv.Atoi(part) + partInt, err := parseCanonicalArrayIndex(part) if err != nil { return fmt.Errorf("[/%s] invalid array index '%s': %v", strings.Join(parts[:i+1], "/"), part, err) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddy.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddy.go index d6a2ae0b3..8799594a9 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddy.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddy.go @@ -81,11 +81,14 @@ type Config struct { // associated value. AppsRaw ModuleMap `json:"apps,omitempty" caddy:"namespace="` - apps map[string]App + apps map[string]App + + // failedApps is a map of apps that failed to provision with their underlying error. + failedApps map[string]error storage certmagic.Storage eventEmitter eventEmitter - cancelFunc context.CancelFunc + cancelFunc context.CancelCauseFunc // fileSystems is a dict of fileSystems that will later be loaded from and added to. fileSystems FileSystems @@ -124,10 +127,9 @@ func Load(cfgJSON []byte, forceReload bool) error { zap.Error(notifyErr), zap.String("reload_err", err.Error())) } - return } - if err := notify.Ready(); err != nil { - Log().Error("unable to notify to service manager of ready state", zap.Error(err)) + if notifyErr := notify.Ready(); notifyErr != nil { + Log().Error("unable to notify to service manager of ready state", zap.Error(notifyErr)) } }() @@ -144,8 +146,8 @@ func Load(cfgJSON []byte, forceReload bool) error { // the new value (if applicable; i.e. "DELETE" doesn't have an input). // If the resulting config is the same as the previous, no reload will // occur unless forceReload is true. If the config is unchanged and not -// forcefully reloaded, then errConfigUnchanged This function is safe for -// concurrent use. +// forcefully reloaded, then errConfigUnchanged is returned. This function +// is safe for concurrent use. // The ifMatchHeader can optionally be given a string of the format: // // " " @@ -224,8 +226,18 @@ func changeConfig(method, path string, input []byte, ifMatchHeader string, force idx := make(map[string]string) err = indexConfigObjects(rawCfg[rawConfigKey], "/"+rawConfigKey, idx) if err != nil { + if len(rawCfgJSON) > 0 { + var oldCfg any + err2 := json.Unmarshal(rawCfgJSON, &oldCfg) + if err2 != nil { + err = fmt.Errorf("%v; additionally, restoring old config: %v", err, err2) + } + rawCfg[rawConfigKey] = oldCfg + } else { + rawCfg[rawConfigKey] = nil + } return APIError{ - HTTPStatus: http.StatusInternalServerError, + HTTPStatus: http.StatusBadRequest, Err: fmt.Errorf("indexing config: %v", err), } } @@ -245,6 +257,8 @@ func changeConfig(method, path string, input []byte, ifMatchHeader string, force err = fmt.Errorf("%v; additionally, restoring old config: %v", err, err2) } rawCfg[rawConfigKey] = oldCfg + } else { + rawCfg[rawConfigKey] = nil } return fmt.Errorf("loading new config: %v", err) @@ -278,14 +292,19 @@ func indexConfigObjects(ptr any, configPath string, index map[string]string) err case map[string]any: for k, v := range val { if k == idKey { + var idStr string switch idVal := v.(type) { case string: - index[idVal] = configPath + idStr = idVal case float64: // all JSON numbers decode as float64 - index[fmt.Sprintf("%v", idVal)] = configPath + idStr = fmt.Sprintf("%v", idVal) default: return fmt.Errorf("%s: %s field must be a string or number", configPath, idKey) } + if existingPath, ok := index[idStr]; ok { + return fmt.Errorf("duplicate ID '%s' found at %s and %s", idStr, existingPath, configPath) + } + index[idStr] = configPath continue } // traverse this object property recursively @@ -408,13 +427,18 @@ func run(newCfg *Config, start bool) (Context, error) { return ctx, nil } - // Provision any admin routers which may need to access - // some of the other apps at runtime - err = ctx.cfg.Admin.provisionAdminRouters(ctx) - if err != nil { - globalMetrics.configSuccess.Set(0) - return ctx, err - } + defer func() { + // if newCfg fails to start completely, clean up the already provisioned modules + // partially copied from provisionContext + if err != nil { + globalMetrics.configSuccess.Set(0) + ctx.cfg.cancelFunc(fmt.Errorf("configuration start error: %w", err)) + + if currentCtx.cfg != nil { + certmagic.Default.Storage = currentCtx.cfg.storage + } + } + }() // Start err = func() error { @@ -438,7 +462,6 @@ func run(newCfg *Config, start bool) (Context, error) { return nil }() if err != nil { - globalMetrics.configSuccess.Set(0) return ctx, err } globalMetrics.configSuccess.Set(1) @@ -449,7 +472,8 @@ func run(newCfg *Config, start bool) (Context, error) { // now that the user's config is running, finish setting up anything else, // such as remote admin endpoint, config loader, etc. - return ctx, finishSettingUp(ctx, ctx.cfg) + err = finishSettingUp(ctx, ctx.cfg) + return ctx, err } // provisionContext creates a new context from the given configuration and provisions @@ -477,7 +501,7 @@ func provisionContext(newCfg *Config, replaceAdminServer bool) (Context, error) // cleanup occurs when we return if there // was an error; if no error, it will get // cleaned up on next config cycle - ctx, cancel := NewContext(Context{Context: context.Background(), cfg: newCfg}) + ctx, cancelCause := NewContextWithCause(Context{Context: context.Background(), cfg: newCfg}) defer func() { if err != nil { globalMetrics.configSuccess.Set(0) @@ -486,7 +510,7 @@ func provisionContext(newCfg *Config, replaceAdminServer bool) (Context, error) // since the associated config won't be used; // this will cause all modules that were newly // provisioned to clean themselves up - cancel() + cancelCause(fmt.Errorf("configuration error: %w", err)) // also undo any other state changes we made if currentCtx.cfg != nil { @@ -494,7 +518,7 @@ func provisionContext(newCfg *Config, replaceAdminServer bool) (Context, error) } } }() - newCfg.cancelFunc = cancel // clean up later + newCfg.cancelFunc = cancelCause // clean up later // set up logging before anything bad happens if newCfg.Logging == nil { @@ -505,19 +529,12 @@ func provisionContext(newCfg *Config, replaceAdminServer bool) (Context, error) return ctx, err } - // start the admin endpoint (and stop any prior one) - if replaceAdminServer { - err = replaceLocalAdminServer(newCfg, ctx) - if err != nil { - return ctx, fmt.Errorf("starting caddy administration endpoint: %v", err) - } - } - // create the new filesystem map newCfg.fileSystems = &filesystems.FileSystemMap{} // prepare the new config for use newCfg.apps = make(map[string]App) + newCfg.failedApps = make(map[string]error) // set up global storage and make it CertMagic's default storage, too err = func() error { @@ -544,6 +561,14 @@ func provisionContext(newCfg *Config, replaceAdminServer bool) (Context, error) return ctx, err } + // start the admin endpoint (and stop any prior one) + if replaceAdminServer { + err = replaceLocalAdminServer(newCfg, ctx) + if err != nil { + return ctx, fmt.Errorf("starting caddy administration endpoint: %v", err) + } + } + // Load and Provision each app and their submodules err = func() error { for appName := range newCfg.AppsRaw { @@ -713,7 +738,7 @@ func unsyncedStop(ctx Context) { } // clean up all modules - ctx.cfg.cancelFunc() + ctx.cfg.cancelFunc(fmt.Errorf("stopping apps")) } // Validate loads, provisions, and validates @@ -721,7 +746,7 @@ func unsyncedStop(ctx Context) { func Validate(cfg *Config) error { _, err := run(cfg, false) if err == nil { - cfg.cancelFunc() // call Cleanup on all modules + cfg.cancelFunc(fmt.Errorf("validation complete")) // call Cleanup on all modules } return err } @@ -734,7 +759,7 @@ func Validate(cfg *Config) error { // code is emitted. func exitProcess(ctx context.Context, logger *zap.Logger) { // let the rest of the program know we're quitting; only do it once - if !atomic.CompareAndSwapInt32(exiting, 0, 1) { + if !exiting.CompareAndSwap(false, true) { return } @@ -813,11 +838,11 @@ func exitProcess(ctx context.Context, logger *zap.Logger) { }() } -var exiting = new(int32) // accessed atomically +var exiting atomic.Bool // Exiting returns true if the process is exiting. // EXPERIMENTAL API: subject to change or removal. -func Exiting() bool { return atomic.LoadInt32(exiting) == 1 } +func Exiting() bool { return exiting.Load() } // OnExit registers a callback to invoke during process exit. // This registration is PROCESS-GLOBAL, meaning that each @@ -929,6 +954,34 @@ func InstanceID() (uuid.UUID, error) { // for example. var CustomVersion string +// CustomBinaryName is an optional string that overrides the root +// command name from the default of "caddy". This is useful for +// downstream projects that embed Caddy but use a different binary +// name. Shell completions and help text will use this name instead +// of "caddy". +// +// Set this variable during `go build` with `-ldflags`: +// +// -ldflags '-X github.com/caddyserver/caddy/v2.CustomBinaryName=my_custom_caddy' +// +// for example. +var CustomBinaryName string + +// CustomLongDescription is an optional string that overrides the +// long description of the root Cobra command. This is useful for +// downstream projects that embed Caddy but want different help +// output. +// +// Set this variable in an init() function of a package that is +// imported by your main: +// +// func init() { +// caddy.CustomLongDescription = "My custom server based on Caddy..." +// } +// +// for example. +var CustomLongDescription string + // Version returns the Caddy version in a simple/short form, and // a full version string. The short form will not have spaces and // is intended for User-Agent strings and similar, but may be @@ -959,11 +1012,11 @@ func Version() (simple, full string) { if CustomVersion != "" { full = CustomVersion simple = CustomVersion - return + return simple, full } full = "unknown" simple = "unknown" - return + return simple, full } // find the Caddy module in the dependency list for _, dep := range bi.Deps { @@ -1043,7 +1096,7 @@ func Version() (simple, full string) { } } - return + return simple, full } // Event represents something that has happened or is happening. @@ -1076,7 +1129,7 @@ type Event struct { } // NewEvent creates a new event, but does not emit the event. To emit an -// event, call Emit() on the current instance of the caddyevents app insteaad. +// event, call Emit() on the current instance of the caddyevents app instead. // // EXPERIMENTAL: Subject to change. func NewEvent(ctx Context, name string, data map[string]any) (Event, error) { @@ -1104,9 +1157,15 @@ func (e Event) Origin() Module { return e.origin } // Returns the module t // CloudEvents spec. func (e Event) CloudEvent() CloudEvent { dataJSON, _ := json.Marshal(e.Data) + var source string + if e.Origin() == nil { + source = "caddy" + } else { + source = string(e.Origin().CaddyModule().ID) + } return CloudEvent{ ID: e.id.String(), - Source: e.origin.CaddyModule().String(), + Source: source, SpecVersion: "1.0", Type: e.name, Time: e.ts, @@ -1175,6 +1234,91 @@ var ( rawCfgMu sync.RWMutex ) +// lastConfigFile and lastConfigAdapter remember the source config +// file and adapter used when Caddy was started via the CLI "run" command. +// These are consulted by the SIGUSR1 handler to attempt reloading from +// the same source. They are intentionally not set for other entrypoints +// such as "caddy start" or subcommands like file-server. +var ( + lastConfigMu sync.RWMutex + lastConfigFile string + lastConfigAdapter string +) + +// reloadFromSourceFunc is the type of stored callback +// which is called when we receive a SIGUSR1 signal. +type reloadFromSourceFunc func(file, adapter string) error + +// reloadFromSourceCallback is the stored callback +// which is called when we receive a SIGUSR1 signal. +var reloadFromSourceCallback reloadFromSourceFunc + +// errReloadFromSourceUnavailable is returned when no reload-from-source callback is set. +var errReloadFromSourceUnavailable = errors.New("reload from source unavailable in this process") //nolint:unused + +// SetLastConfig records the given source file and adapter as the +// last-known external configuration source. Intended to be called +// only when starting via "caddy run --config --adapter ". +func SetLastConfig(file, adapter string, fn reloadFromSourceFunc) { + lastConfigMu.Lock() + lastConfigFile = file + lastConfigAdapter = adapter + reloadFromSourceCallback = fn + lastConfigMu.Unlock() +} + +// ClearLastConfigIfDifferent clears the recorded last-config if the provided +// source file/adapter do not match the recorded last-config. If both srcFile +// and srcAdapter are empty, the last-config is cleared. +func ClearLastConfigIfDifferent(srcFile, srcAdapter string) { + if (srcFile != "" || srcAdapter != "") && lastConfigMatches(srcFile, srcAdapter) { + return + } + SetLastConfig("", "", nil) +} + +// getLastConfig returns the last-known config file and adapter. +func getLastConfig() (file, adapter string, fn reloadFromSourceFunc) { + lastConfigMu.RLock() + f, a, cb := lastConfigFile, lastConfigAdapter, reloadFromSourceCallback + lastConfigMu.RUnlock() + return f, a, cb +} + +// lastConfigMatches returns true if the provided source file and/or adapter +// matches the recorded last-config. Matching rules (in priority order): +// 1. If srcAdapter is provided and differs from the recorded adapter, no match. +// 2. If srcFile exactly equals the recorded file, match. +// 3. If both sides can be made absolute and equal, match. +// 4. If basenames are equal, match. +func lastConfigMatches(srcFile, srcAdapter string) bool { + lf, la, _ := getLastConfig() + + // If adapter is provided, it must match. + if srcAdapter != "" && srcAdapter != la { + return false + } + + // Quick equality check. + if srcFile == lf { + return true + } + + // Try absolute path comparison. + sAbs, sErr := filepath.Abs(srcFile) + lAbs, lErr := filepath.Abs(lf) + if sErr == nil && lErr == nil && sAbs == lAbs { + return true + } + + // Final fallback: basename equality. + if filepath.Base(srcFile) == filepath.Base(lf) { + return true + } + + return false +} + // errSameConfig is returned if the new config is the same // as the old one. This isn't usually an actual, actionable // error; it's mostly a sentinel value. diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/adapter.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/adapter.go index da4f98337..449370dc6 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/adapter.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/adapter.go @@ -68,7 +68,7 @@ func (a Adapter) Adapt(body []byte, options map[string]any) ([]byte, []caddyconf // TODO: also perform this check on imported files func FormattingDifference(filename string, body []byte) (caddyconfig.Warning, bool) { // replace windows-style newlines to normalize comparison - normalizedBody := bytes.Replace(body, []byte("\r\n"), []byte("\n"), -1) + normalizedBody := bytes.ReplaceAll(body, []byte("\r\n"), []byte("\n")) formatted := Format(normalizedBody) if bytes.Equal(formatted, normalizedBody) { diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/dispenser.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/dispenser.go index 325bb54d3..66b9b1087 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/dispenser.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/dispenser.go @@ -270,7 +270,7 @@ func (d *Dispenser) File() string { // targets are left unchanged. If all the targets are filled, // then true is returned. func (d *Dispenser) Args(targets ...*string) bool { - for i := 0; i < len(targets); i++ { + for i := range targets { if !d.NextArg() { return false } @@ -308,9 +308,9 @@ func (d *Dispenser) CountRemainingArgs() int { } // RemainingArgs loads any more arguments (tokens on the same line) -// into a slice and returns them. Open curly brace tokens also indicate -// the end of arguments, and the curly brace is not included in -// the return value nor is it loaded. +// into a slice of strings and returns them. Open curly brace tokens +// also indicate the end of arguments, and the curly brace is not +// included in the return value nor is it loaded. func (d *Dispenser) RemainingArgs() []string { var args []string for d.NextArg() { @@ -320,9 +320,9 @@ func (d *Dispenser) RemainingArgs() []string { } // RemainingArgsRaw loads any more arguments (tokens on the same line, -// retaining quotes) into a slice and returns them. Open curly brace -// tokens also indicate the end of arguments, and the curly brace is -// not included in the return value nor is it loaded. +// retaining quotes) into a slice of strings and returns them. +// Open curly brace tokens also indicate the end of arguments, +// and the curly brace is not included in the return value nor is it loaded. func (d *Dispenser) RemainingArgsRaw() []string { var args []string for d.NextArg() { @@ -331,6 +331,18 @@ func (d *Dispenser) RemainingArgsRaw() []string { return args } +// RemainingArgsAsTokens loads any more arguments (tokens on the same line) +// into a slice of Token-structs and returns them. Open curly brace tokens +// also indicate the end of arguments, and the curly brace is not included +// in the return value nor is it loaded. +func (d *Dispenser) RemainingArgsAsTokens() []Token { + var args []Token + for d.NextArg() { + args = append(args, d.Token()) + } + return args +} + // NewFromNextSegment returns a new dispenser with a copy of // the tokens from the current token until the end of the // "directive" whether that be to the end of the line or diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/formatter.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/formatter.go index f1d12fa51..14315a3f1 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/formatter.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/formatter.go @@ -18,6 +18,7 @@ import ( "bytes" "io" "slices" + "strings" "unicode" ) @@ -52,19 +53,43 @@ func Format(input []byte) []byte { newLines int // count of newlines consumed - comment bool // whether we're in a comment - quoted bool // whether we're in a quoted segment - escaped bool // whether current char is escaped + comment bool // whether we're in a comment + quotes string // encountered quotes ('', '`', '"', '"`', '`"') + escaped bool // whether current char is escaped heredoc heredocState // whether we're in a heredoc heredocEscaped bool // whether heredoc is escaped heredocMarker []rune heredocClosingMarker []rune - nesting int // indentation level - withinBackquote bool + nesting int // indentation level + + currentToken strings.Builder + currentLineFirstToken string + previousLineWasTopLevelImport bool + openBraceOwnLine bool ) + finishToken := func() { + if currentToken.Len() == 0 { + return + } + if currentLineFirstToken == "" { + currentLineFirstToken = currentToken.String() + } + currentToken.Reset() + } + + finishLine := func() { + finishToken() + if currentLineFirstToken != "" { + previousLineWasTopLevelImport = nesting == 0 && currentLineFirstToken == "import" + } else if !openBrace || !openBraceOwnLine || openBraceWritten { + previousLineWasTopLevelImport = false + } + currentLineFirstToken = "" + } + write := func(ch rune) { out.WriteRune(ch) last = ch @@ -89,12 +114,8 @@ func Format(input []byte) []byte { } panic(err) } - if ch == '`' { - withinBackquote = !withinBackquote - } - // detect whether we have the start of a heredoc - if !quoted && !(heredoc != heredocClosed || heredocEscaped) && + if quotes == "" && (heredoc == heredocClosed && !heredocEscaped) && space && last == '<' && ch == '<' { write(ch) heredoc = heredocOpening @@ -180,22 +201,55 @@ func Format(input []byte) []byte { continue } - if quoted { + if ch == '`' { + switch quotes { + case "\"`": + quotes = "\"" + case "`": + quotes = "" + case "\"": + quotes = "\"`" + default: + quotes = "`" + } + } + + if quotes == "\"" { if ch == '"' { - quoted = false + quotes = "" } write(ch) continue } - if space && ch == '"' { - quoted = true + if ch == '"' { + switch quotes { + case "": + if space { + quotes = "\"" + } + case "`\"": + quotes = "`" + case "\"`": + quotes = "" + } + } + + if strings.Contains(quotes, "`") { + if ch == '`' && space && !beginningOfLine { + write(' ') + } + write(ch) + space = false + continue } if unicode.IsSpace(ch) { + finishToken() space = true heredocEscaped = false if ch == '\n' { + finishLine() newLines++ } continue @@ -222,13 +276,19 @@ func Format(input []byte) []byte { } openBrace = false - if beginningOfLine { + if openBraceOwnLine && previousLineWasTopLevelImport { + if last != '\n' { + nextLine() + } + indent() + } else if beginningOfLine { indent() - } else if !openBraceSpace { + } else if !openBraceSpace || !unicode.IsSpace(last) { write(' ') } write('{') openBraceWritten = true + openBraceOwnLine = false nextLine() newLines = 0 // prevent infinite nesting from ridiculous inputs (issue #4169) @@ -239,21 +299,25 @@ func Format(input []byte) []byte { switch { case ch == '{': + finishToken() openBrace = true openBraceSpace = spacePrior && !beginningOfLine - if openBraceSpace { + openBraceOwnLine = newLines > 0 + if openBraceSpace && newLines == 0 { write(' ') } openBraceWritten = false - if withinBackquote { + if quotes == "`" { write('{') openBraceWritten = true + openBraceOwnLine = false continue } continue case ch == '}' && (spacePrior || !openBrace): - if withinBackquote { + finishToken() + if quotes == "`" { write('}') continue } @@ -297,6 +361,7 @@ func Format(input []byte) []byte { space = true } + currentToken.WriteRune(ch) write(ch) beginningOfLine = false diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/lexer.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/lexer.go index 9b523f397..60dabe43d 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/lexer.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/lexer.go @@ -137,7 +137,7 @@ func (l *lexer) next() (bool, error) { } // detect whether we have the start of a heredoc - if !(quoted || btQuoted) && !(inHeredoc || heredocEscaped) && + if (!quoted && !btQuoted) && (!inHeredoc && !heredocEscaped) && len(val) > 1 && string(val[:2]) == "<<" { // a space means it's just a regular token and not a heredoc if ch == ' ' { @@ -323,7 +323,8 @@ func (l *lexer) finalizeHeredoc(val []rune, marker string) ([]rune, error) { // if the padding doesn't match exactly at the start then we can't safely strip if index != 0 { - return nil, fmt.Errorf("mismatched leading whitespace in heredoc <<%s on line #%d [%s], expected whitespace [%s] to match the closing marker", marker, l.line+lineNum+1, lineText, paddingToStrip) + cleanLineText := strings.TrimRight(lineText, "\r\n") + return nil, fmt.Errorf("mismatched leading whitespace in heredoc <<%s on line #%d [%s], expected whitespace [%s] to match the closing marker", marker, l.line+lineNum+1, cleanLineText, paddingToStrip) } // strip, then append the line, with the newline, to the output. diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/parse.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/parse.go index d04a1ac46..58d9b272c 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/parse.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/caddyfile/parse.go @@ -379,28 +379,23 @@ func (p *parser) doImport(nesting int) error { if len(blockTokens) > 0 { // use such tokens to create a new dispenser, and then use it to parse each block bd := NewDispenser(blockTokens) + + // one iteration processes one sub-block inside the import for bd.Next() { - // see if we can grab a key - var currentMappingKey string - if bd.Val() == "{" { + currentMappingKey := bd.Val() + + if currentMappingKey == "{" { return p.Err("anonymous blocks are not supported") } - currentMappingKey = bd.Val() - currentMappingTokens := []Token{} - // read all args until end of line / { - if bd.NextArg() { + + // load up all arguments (if there even are any) + currentMappingTokens := bd.RemainingArgsAsTokens() + + // load up the entire block + for mappingNesting := bd.Nesting(); bd.NextBlock(mappingNesting); { currentMappingTokens = append(currentMappingTokens, bd.Token()) - for bd.NextArg() { - currentMappingTokens = append(currentMappingTokens, bd.Token()) - } - // TODO(elee1766): we don't enter another mapping here because it's annoying to extract the { and } properly. - // maybe someone can do that in the future - } else { - // attempt to enter a block and add tokens to the currentMappingTokens - for mappingNesting := bd.Nesting(); bd.NextBlock(mappingNesting); { - currentMappingTokens = append(currentMappingTokens, bd.Token()) - } } + blockMapping[currentMappingKey] = currentMappingTokens } } @@ -512,7 +507,7 @@ func (p *parser) doImport(nesting int) error { // format, won't check for nesting correctness or any other error, that's what parser does. if !maybeSnippet && nesting == 0 { // first of the line - if i == 0 || isNextOnNewLine(tokensCopy[i-1], token) { + if i == 0 || isNextOnNewLine(tokensCopy[len(tokensCopy)-1], token) { index = 0 } else { index++ @@ -538,25 +533,24 @@ func (p *parser) doImport(nesting int) error { } // if it is {block}, we substitute with all tokens in the block // if it is {blocks.*}, we substitute with the tokens in the mapping for the * - var skip bool var tokensToAdd []Token + foundBlockDirective := false switch { case token.Text == "{block}": + foundBlockDirective = true tokensToAdd = blockTokens case strings.HasPrefix(token.Text, "{blocks.") && strings.HasSuffix(token.Text, "}"): + foundBlockDirective = true // {blocks.foo.bar} will be extracted to key `foo.bar` blockKey := strings.TrimPrefix(strings.TrimSuffix(token.Text, "}"), "{blocks.") val, ok := blockMapping[blockKey] if ok { tokensToAdd = val } - default: - skip = true } - if !skip { - if len(tokensToAdd) == 0 { - // if there is no content in the snippet block, don't do any replacement - // this allows snippets which contained {block}/{block.*} before this change to continue functioning as normal + + if foundBlockDirective { + if maybeSnippet { tokensCopy = append(tokensCopy, token) } else { tokensCopy = append(tokensCopy, tokensToAdd...) @@ -626,7 +620,7 @@ func (p *parser) doSingleImport(importFile string) ([]Token, error) { if err != nil { return nil, p.Errf("Failed to get absolute path of file: %s: %v", importFile, err) } - for i := 0; i < len(importedTokens); i++ { + for i := range importedTokens { importedTokens[i].File = filename } @@ -692,11 +686,28 @@ func (p *parser) directive() error { // a opening curly brace. It does NOT advance the token. func (p *parser) openCurlyBrace() error { if p.Val() != "{" { + if p.valLooksLikeGlobalOptionsAfterImportedSnippets() { + return p.Err("global options block must appear before import directives; move the global options block to the top of the Caddyfile") + } return p.SyntaxErr("{") } return nil } +func (p *parser) valLooksLikeGlobalOptionsAfterImportedSnippets() bool { + if p.Val() != "import" || len(p.block.Keys) == 0 { + return false + } + + for _, key := range p.block.Keys { + if !strings.HasPrefix(key.Text, "(") || !strings.HasSuffix(key.Text, ")") { + return false + } + } + + return true +} + // closeCurlyBrace expects the current token to be // a closing curly brace. This acts like an assertion // because it returns an error if the token is not @@ -771,7 +782,7 @@ type ServerBlock struct { } func (sb ServerBlock) GetKeysText() []string { - res := []string{} + res := make([]string, 0, len(sb.Keys)) for _, k := range sb.Keys { res = append(res, k.Text) } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/configadapters.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/configadapters.go index 0ca3c3af1..8a5a37f08 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/configadapters.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/configadapters.go @@ -81,7 +81,11 @@ func JSONModuleObject(val any, fieldName, fieldVal string, warnings *[]Warning) err = json.Unmarshal(enc, &tmp) if err != nil { if warnings != nil { - *warnings = append(*warnings, Warning{Message: err.Error()}) + message := err.Error() + if jsonErr, ok := err.(*json.SyntaxError); ok { + message = fmt.Sprintf("%v, at offset %d", jsonErr.Error(), jsonErr.Offset) + } + *warnings = append(*warnings, Warning{Message: message}) } return nil } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/httploader.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/httploader.go index a25041a34..a0a46460a 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/httploader.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/httploader.go @@ -136,7 +136,7 @@ func (hl HTTPLoader) LoadConfig(ctx caddy.Context) ([]byte, error) { } func attemptHttpCall(client *http.Client, request *http.Request) (*http.Response, error) { - resp, err := client.Do(request) + resp, err := client.Do(request) //nolint:gosec // no SSRF; comes from trusted config if err != nil { return nil, fmt.Errorf("problem calling http loader url: %v", err) } else if resp.StatusCode < 200 || resp.StatusCode > 499 { @@ -151,7 +151,7 @@ func doHttpCallWithRetries(ctx caddy.Context, client *http.Client, request *http var err error const maxAttempts = 10 - for i := 0; i < maxAttempts; i++ { + for i := range maxAttempts { resp, err = attemptHttpCall(client, request) if err != nil && i < maxAttempts-1 { select { diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/load.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/load.go index 9f5cda905..d2498ed6f 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/load.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/caddyconfig/load.go @@ -106,7 +106,7 @@ func (adminLoad) handleLoad(w http.ResponseWriter, r *http.Request) error { if err != nil { caddy.Log().Named("admin.api.load").Error(err.Error()) } - _, _ = w.Write(respBody) + _, _ = w.Write(respBody) //nolint:gosec // false positive: no XSS here } body = result } @@ -121,6 +121,13 @@ func (adminLoad) handleLoad(w http.ResponseWriter, r *http.Request) error { } } + // If this request changed the config, clear the last + // config info we have stored, if it is different from + // the original source. + caddy.ClearLastConfigIfDifferent( + r.Header.Get("Caddy-Config-Source-File"), + r.Header.Get("Caddy-Config-Source-Adapter")) + caddy.Log().Named("admin.api").Info("load complete") return nil diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/cobra.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/cobra.go index 9ecb389e2..14c8d2988 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/cobra.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/cobra.go @@ -9,9 +9,14 @@ import ( ) var defaultFactory = newRootCommandFactory(func() *cobra.Command { - return &cobra.Command{ - Use: "caddy", - Long: `Caddy is an extensible server platform written in Go. + bin := caddy.CustomBinaryName + if bin == "" { + bin = "caddy" + } + + long := caddy.CustomLongDescription + if long == "" { + long = `Caddy is an extensible server platform written in Go. At its core, Caddy merely manages configuration. Modules are plugged in statically at compile-time to provide useful functionality. Caddy's @@ -91,7 +96,12 @@ package installers: https://caddyserver.com/docs/install Instructions for running Caddy in production are also available: https://caddyserver.com/docs/running -`, +` + } + + return &cobra.Command{ + Use: bin, + Long: long, Example: ` $ caddy run $ caddy run --config caddy.json $ caddy reload --config caddy.json diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/commandfuncs.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/commandfuncs.go index 5127c0f90..faa275b03 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/commandfuncs.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/commandfuncs.go @@ -24,6 +24,7 @@ import ( "io" "io/fs" "log" + "maps" "net" "net/http" "os" @@ -73,7 +74,7 @@ func cmdStart(fl Flags) (int, error) { // ensure it's the process we're expecting - we can be // sure by giving it some random bytes and having it echo // them back to us) - cmd := exec.Command(os.Args[0], "run", "--pingback", ln.Addr().String()) + cmd := exec.Command(os.Args[0], "run", "--pingback", ln.Addr().String()) //nolint:gosec // no command injection that I can determine... // we should be able to run caddy in relative paths if errors.Is(cmd.Err, exec.ErrDot) { cmd.Err = nil @@ -171,9 +172,19 @@ func cmdStart(fl Flags) (int, error) { func cmdRun(fl Flags) (int, error) { caddy.TrapSignals() - logger := caddy.Log() + // set up buffered logging for early startup + // so that we can hold onto logs until after + // the config is loaded (or fails to load) + // so that we can write the logs to the user's + // configured output. we must be sure to flush + // on any error before the config is loaded. + logger, defaultLogger, logBuffer := caddy.BufferedLog() + undoMaxProcs := setResourceLimits(logger) defer undoMaxProcs() + // release the local reference to the undo function so it can be GC'd; + // the deferred call above has already captured the actual function value. + undoMaxProcs = nil //nolint:ineffassign,wastedassign configFlag := fl.String("config") configAdapterFlag := fl.String("adapter") @@ -186,6 +197,7 @@ func cmdRun(fl Flags) (int, error) { // load all additional envs as soon as possible err := handleEnvFileFlag(fl) if err != nil { + logBuffer.FlushTo(defaultLogger) return caddy.ExitCodeFailedStartup, err } @@ -203,6 +215,7 @@ func cmdRun(fl Flags) (int, error) { logger.Info("no autosave file exists", zap.String("autosave_file", caddy.ConfigAutosavePath)) resumeFlag = false } else if err != nil { + logBuffer.FlushTo(defaultLogger) return caddy.ExitCodeFailedStartup, err } else { if configFlag == "" { @@ -218,9 +231,11 @@ func cmdRun(fl Flags) (int, error) { } // we don't use 'else' here since this value might have been changed in 'if' block; i.e. not mutually exclusive var configFile string + var adapterUsed string if !resumeFlag { - config, configFile, err = LoadConfig(configFlag, configAdapterFlag) + config, configFile, adapterUsed, err = LoadConfig(configFlag, configAdapterFlag) if err != nil { + logBuffer.FlushTo(defaultLogger) return caddy.ExitCodeFailedStartup, err } } @@ -235,11 +250,35 @@ func cmdRun(fl Flags) (int, error) { } } + // If we have a source config file (we're running via 'caddy run --config ...'), + // record it so SIGUSR1 can reload from the same file. Also provide a callback + // that knows how to load/adapt that source when requested by the main process. + if configFile != "" { + caddy.SetLastConfig(configFile, adapterUsed, func(file, adapter string) error { + cfg, _, _, err := LoadConfig(file, adapter) + if err != nil { + return err + } + return caddy.Load(cfg, true) + }) + } + // run the initial config err = caddy.Load(config, true) if err != nil { + logBuffer.FlushTo(defaultLogger) return caddy.ExitCodeFailedStartup, fmt.Errorf("loading initial config: %v", err) } + // release the reference to the config so it can be GC'd + config = nil //nolint:ineffassign,wastedassign + + // at this stage the config will have replaced the + // default logger to the configured one, so we can + // log normally, now that the config is running. + // also clear our ref to the buffer so it can get GC'd + logger = caddy.Log() + defaultLogger = nil //nolint:ineffassign,wastedassign + logBuffer = nil //nolint:wastedassign,ineffassign logger.Info("serving initial configuration") // if we are to report to another process the successful start @@ -255,18 +294,22 @@ func cmdRun(fl Flags) (int, error) { return caddy.ExitCodeFailedStartup, fmt.Errorf("dialing confirmation address: %v", err) } - defer conn.Close() _, err = conn.Write(confirmationBytes) if err != nil { return caddy.ExitCodeFailedStartup, fmt.Errorf("writing confirmation bytes to %s: %v", pingbackFlag, err) } + // close (non-defer because we `select {}` below) + // and release references so they can be GC'd + conn.Close() + confirmationBytes = nil //nolint:ineffassign,wastedassign + conn = nil //nolint:wastedassign,ineffassign } // if enabled, reload config file automatically on changes // (this better only be used in dev!) if watchFlag { - go watchConfigFile(configFile, configAdapterFlag) + go watchConfigFile(configFile, adapterUsed) } // warn if the environment does not provide enough information about the disk @@ -288,6 +331,9 @@ func cmdRun(fl Flags) (int, error) { } } + // release the last local logger reference + logger = nil //nolint:wastedassign,ineffassign + select {} } @@ -318,7 +364,7 @@ func cmdReload(fl Flags) (int, error) { forceFlag := fl.Bool("force") // get the config in caddy's native format - config, configFile, err := LoadConfig(configFlag, configAdapterFlag) + config, configFile, adapterUsed, err := LoadConfig(configFlag, configAdapterFlag) if err != nil { return caddy.ExitCodeFailedStartup, err } @@ -326,7 +372,7 @@ func cmdReload(fl Flags) (int, error) { return caddy.ExitCodeFailedStartup, fmt.Errorf("no config file to load") } - adminAddr, err := DetermineAdminAPIAddress(addressFlag, config, configFlag, configAdapterFlag) + adminAddr, err := DetermineAdminAPIAddress(addressFlag, config, configFile, configAdapterFlag) if err != nil { return caddy.ExitCodeFailedStartup, fmt.Errorf("couldn't determine admin API address: %v", err) } @@ -336,6 +382,10 @@ func cmdReload(fl Flags) (int, error) { if forceFlag { headers.Set("Cache-Control", "must-revalidate") } + // Provide the source file/adapter to the running process so it can + // preserve its last-config knowledge if this reload came from the same source. + headers.Set("Caddy-Config-Source-File", configFile) + headers.Set("Caddy-Config-Source-Adapter", adapterUsed) resp, err := AdminAPIRequest(adminAddr, http.MethodPost, "/load", headers, bytes.NewReader(config)) if err != nil { @@ -361,11 +411,65 @@ func cmdBuildInfo(_ Flags) (int, error) { return caddy.ExitCodeSuccess, nil } +// jsonModuleInfo holds metadata about a Caddy module for JSON output. +type jsonModuleInfo struct { + ModuleName string `json:"module_name"` + ModuleType string `json:"module_type"` + Version string `json:"version,omitempty"` + PackageURL string `json:"package_url,omitempty"` +} + func cmdListModules(fl Flags) (int, error) { packages := fl.Bool("packages") versions := fl.Bool("versions") skipStandard := fl.Bool("skip-standard") + jsonOutput := fl.Bool("json") + + // Organize modules by whether they come with the standard distribution + standard, nonstandard, unknown, err := getModules() + if err != nil { + // If module info can't be fetched, just print the IDs and exit + for _, m := range caddy.Modules() { + fmt.Println(m) + } + return caddy.ExitCodeSuccess, nil + } + + // Logic for JSON output + if jsonOutput { + output := []jsonModuleInfo{} + + // addToOutput is a helper to convert internal module info to the JSON-serializable struct + addToOutput := func(list []moduleInfo, moduleType string) { + for _, mi := range list { + item := jsonModuleInfo{ + ModuleName: mi.caddyModuleID, + ModuleType: moduleType, // Mapping the type here + } + if mi.goModule != nil { + item.Version = mi.goModule.Version + item.PackageURL = mi.goModule.Path + } + output = append(output, item) + } + } + // Pass the respective type for each category + if !skipStandard { + addToOutput(standard, "standard") + } + addToOutput(nonstandard, "non-standard") + addToOutput(unknown, "unknown") + + jsonBytes, err := json.MarshalIndent(output, "", " ") + if err != nil { + return caddy.ExitCodeFailedQuit, err + } + fmt.Println(string(jsonBytes)) + return caddy.ExitCodeSuccess, nil + } + + // Logic for Text output (Fallback) printModuleInfo := func(mi moduleInfo) { fmt.Print(mi.caddyModuleID) if versions && mi.goModule != nil { @@ -383,16 +487,6 @@ func cmdListModules(fl Flags) (int, error) { fmt.Println() } - // organize modules by whether they come with the standard distribution - standard, nonstandard, unknown, err := getModules() - if err != nil { - // oh well, just print the module IDs and exit - for _, m := range caddy.Modules() { - fmt.Println(m) - } - return caddy.ExitCodeSuccess, nil - } - // Standard modules (always shipped with Caddy) if !skipStandard { if len(standard) > 0 { @@ -411,8 +505,8 @@ func cmdListModules(fl Flags) (int, error) { for _, mod := range nonstandard { printModuleInfo(mod) } + fmt.Printf("\n Non-standard modules: %d\n", len(nonstandard)) } - fmt.Printf("\n Non-standard modules: %d\n", len(nonstandard)) // Unknown modules (couldn't get Caddy module info) if len(unknown) > 0 { @@ -422,8 +516,8 @@ func cmdListModules(fl Flags) (int, error) { for _, mod := range unknown { printModuleInfo(mod) } + fmt.Printf("\n Unknown modules: %d\n", len(unknown)) } - fmt.Printf("\n Unknown modules: %d\n", len(unknown)) return caddy.ExitCodeSuccess, nil } @@ -440,16 +534,20 @@ func cmdEnviron(fl Flags) (int, error) { } func cmdAdaptConfig(fl Flags) (int, error) { - inputFlag := fl.String("config") + configFlag := fl.String("config") adapterFlag := fl.String("adapter") prettyFlag := fl.Bool("pretty") validateFlag := fl.Bool("validate") var err error - inputFlag, err = configFileWithRespectToDefault(caddy.Log(), inputFlag) + configFlag, err = configFileWithRespectToDefault(caddy.Log(), configFlag) if err != nil { return caddy.ExitCodeFailedStartup, err } + if configFlag == "" { + return caddy.ExitCodeFailedStartup, + fmt.Errorf("input file required when there is no Caddyfile in current directory (use --config flag)") + } // load all additional envs as soon as possible err = handleEnvFileFlag(fl) @@ -468,13 +566,19 @@ func cmdAdaptConfig(fl Flags) (int, error) { fmt.Errorf("unrecognized config adapter: %s", adapterFlag) } - input, err := os.ReadFile(inputFlag) + var input []byte + // read from stdin if the file name is "-" + if configFlag == "-" { + input, err = io.ReadAll(os.Stdin) + } else { + input, err = os.ReadFile(configFlag) + } if err != nil { return caddy.ExitCodeFailedStartup, fmt.Errorf("reading input file: %v", err) } - opts := map[string]any{"filename": inputFlag} + opts := map[string]any{"filename": configFlag} adaptedConfig, warnings, err := cfgAdapter.Adapt(input, opts) if err != nil { @@ -540,7 +644,7 @@ func cmdValidateConfig(fl Flags) (int, error) { fmt.Errorf("input file required when there is no Caddyfile in current directory (use --config flag)") } - input, _, err := LoadConfig(configFlag, adapterFlag) + input, _, _, err := LoadConfig(configFlag, adapterFlag) if err != nil { return caddy.ExitCodeFailedStartup, err } @@ -593,7 +697,7 @@ func cmdFmt(fl Flags) (int, error) { output := caddyfile.Format(input) if fl.Bool("overwrite") { - if err := os.WriteFile(configFile, output, 0o600); err != nil { + if err := os.WriteFile(configFile, output, 0o600); err != nil { //nolint:gosec // path traversal is not really a thing here, this is either "Caddyfile" or admin-controlled return caddy.ExitCodeFailedStartup, fmt.Errorf("overwriting formatted file: %v", err) } return caddy.ExitCodeSuccess, nil @@ -703,9 +807,7 @@ func AdminAPIRequest(adminAddr, method, uri string, headers http.Header, body io if body != nil { req.Header.Set("Content-Type", "application/json") } - for k, v := range headers { - req.Header[k] = v - } + maps.Copy(req.Header, headers) // make an HTTP client that dials our network type, since admin // endpoints aren't always TCP, which is what the default transport @@ -718,7 +820,7 @@ func AdminAPIRequest(adminAddr, method, uri string, headers http.Header, body io }, } - resp, err := client.Do(req) + resp, err := client.Do(req) //nolint:gosec // the only SSRF here would be self-sabatoge I think if err != nil { return nil, fmt.Errorf("performing request: %v", err) } @@ -757,7 +859,7 @@ func DetermineAdminAPIAddress(address string, config []byte, configFile, configA loadedConfig := config if len(loadedConfig) == 0 { // get the config in caddy's native format - loadedConfig, loadedConfigFile, err = LoadConfig(configFile, configAdapter) + loadedConfig, loadedConfigFile, _, err = LoadConfig(configFile, configAdapter) if err != nil { return "", err } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/commands.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/commands.go index 259dd358f..417720f06 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/commands.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/commands.go @@ -20,6 +20,7 @@ import ( "os" "regexp" "strings" + "sync" "github.com/spf13/cobra" "github.com/spf13/cobra/doc" @@ -80,10 +81,16 @@ type CommandFunc func(Flags) (int, error) // Commands returns a list of commands initialised by // RegisterCommand func Commands() map[string]Command { + commandsMu.RLock() + defer commandsMu.RUnlock() + return commands } -var commands = make(map[string]Command) +var ( + commandsMu sync.RWMutex + commands = make(map[string]Command) +) func init() { RegisterCommand(Command{ @@ -222,12 +229,13 @@ documentation: https://go.dev/doc/modules/version-numbers RegisterCommand(Command{ Name: "list-modules", - Usage: "[--packages] [--versions] [--skip-standard]", + Usage: "[--packages] [--versions] [--skip-standard] [--json]", Short: "Lists the installed Caddy modules", CobraFunc: func(cmd *cobra.Command) { cmd.Flags().BoolP("packages", "", false, "Print package paths") cmd.Flags().BoolP("versions", "", false, "Print version information") cmd.Flags().BoolP("skip-standard", "s", false, "Skip printing standard modules") + cmd.Flags().BoolP("json", "", false, "Print modules in JSON format") cmd.RunE = WrapCommandFuncForCobra(cmdListModules) }, }) @@ -286,6 +294,8 @@ zero exit status will be returned. If --envfile is specified, an environment file with environment variables in the KEY=VALUE format will be loaded into the Caddy process. + +If you wish to use stdin instead of a regular file, use - as the path. `, CobraFunc: func(cmd *cobra.Command) { cmd.Flags().StringP("config", "c", "", "Configuration file to adapt (required)") @@ -383,7 +393,7 @@ lines will be prefixed with '-' and '+' where they differ. Note that unchanged lines are prefixed with two spaces for alignment, and that this is not a valid patch format. -If you wish you use stdin instead of a regular file, use - as the path. +If you wish to use stdin instead of a regular file, use - as the path. When reading from stdin, the --overwrite flag has no effect: the result is always printed to stdout. `, @@ -441,7 +451,7 @@ EXPERIMENTAL: May be changed or removed. }) defaultFactory.Use(func(rootCmd *cobra.Command) { - rootCmd.AddCommand(caddyCmdToCobra(Command{ + manpageCommand := Command{ Name: "manpage", Usage: "--directory ", Short: "Generates the manual pages for Caddy commands", @@ -471,11 +481,12 @@ argument of --directory. If the directory does not exist, it will be created. return caddy.ExitCodeSuccess, nil }) }, - })) + } - // source: https://github.com/spf13/cobra/blob/main/shell_completions.md - rootCmd.AddCommand(&cobra.Command{ - Use: "completion [bash|zsh|fish|powershell]", + // source: https://github.com/spf13/cobra/blob/6dec1ae26659a130bdb4c985768d1853b0e1bc06/site/content/completions/_index.md + completionCommand := Command{ + Name: "completion", + Usage: "[bash|zsh|fish|powershell]", Short: "Generate completion script", Long: fmt.Sprintf(`To load completions: @@ -516,24 +527,37 @@ argument of --directory. If the directory does not exist, it will be created. PS> %[1]s completion powershell > %[1]s.ps1 # and source this file from your PowerShell profile. `, rootCmd.Root().Name()), - DisableFlagsInUseLine: true, - ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, - Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), - RunE: func(cmd *cobra.Command, args []string) error { - switch args[0] { - case "bash": - return cmd.Root().GenBashCompletion(os.Stdout) - case "zsh": - return cmd.Root().GenZshCompletion(os.Stdout) - case "fish": - return cmd.Root().GenFishCompletion(os.Stdout, true) - case "powershell": - return cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) - default: - return fmt.Errorf("unrecognized shell: %s", args[0]) + CobraFunc: func(cmd *cobra.Command) { + cmd.DisableFlagsInUseLine = true + cmd.ValidArgs = []string{"bash", "zsh", "fish", "powershell"} + cmd.Args = cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs) + cmd.RunE = func(cmd *cobra.Command, args []string) error { + switch args[0] { + case "bash": + return cmd.Root().GenBashCompletion(os.Stdout) + case "zsh": + return cmd.Root().GenZshCompletion(os.Stdout) + case "fish": + return cmd.Root().GenFishCompletion(os.Stdout, true) + case "powershell": + return cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) + default: + return fmt.Errorf("unrecognized shell: %s", args[0]) + } } }, - }) + } + + rootCmd.AddCommand(caddyCmdToCobra(manpageCommand)) + rootCmd.AddCommand(caddyCmdToCobra(completionCommand)) + + // add manpage and completion commands to the map of + // available commands, because they're not registered + // through RegisterCommand. + commandsMu.Lock() + commands[manpageCommand.Name] = manpageCommand + commands[completionCommand.Name] = completionCommand + commandsMu.Unlock() }) } @@ -552,6 +576,9 @@ argument of --directory. If the directory does not exist, it will be created. // // This function should be used in init(). func RegisterCommand(cmd Command) { + commandsMu.Lock() + defer commandsMu.Unlock() + if cmd.Name == "" { panic("command name is required") } @@ -570,6 +597,7 @@ func RegisterCommand(cmd Command) { defaultFactory.Use(func(rootCmd *cobra.Command) { rootCmd.AddCommand(caddyCmdToCobra(cmd)) }) + commands[cmd.Name] = cmd } var commandNameRegex = regexp.MustCompile(`^[a-z0-9]$|^([a-z0-9]+-?[a-z0-9]*)+[a-z0-9]$`) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/main.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/main.go index 87fa9fb95..07666072f 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/main.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/main.go @@ -100,7 +100,12 @@ func handlePingbackConn(conn net.Conn, expect []byte) error { // there is no config available. It prints any warnings to stderr, // and returns the resulting JSON config bytes along with // the name of the loaded config file (if any). -func LoadConfig(configFile, adapterName string) ([]byte, string, error) { +// The return values are: +// - config bytes (nil if no config) +// - config file used ("" if none) +// - adapter used ("" if none) +// - error, if any +func LoadConfig(configFile, adapterName string) ([]byte, string, string, error) { return loadConfigWithLogger(caddy.Log(), configFile, adapterName) } @@ -138,7 +143,7 @@ func isCaddyfile(configFile, adapterName string) (bool, error) { return false, nil } -func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([]byte, string, error) { +func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([]byte, string, string, error) { // if no logger is provided, use a nop logger // just so we don't have to check for nil if logger == nil { @@ -147,7 +152,7 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([ // specifying an adapter without a config file is ambiguous if adapterName != "" && configFile == "" { - return nil, "", fmt.Errorf("cannot adapt config without config file (use --config)") + return nil, "", "", fmt.Errorf("cannot adapt config without config file (use --config)") } // load initial config and adapter @@ -158,13 +163,13 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([ if configFile == "-" { config, err = io.ReadAll(os.Stdin) if err != nil { - return nil, "", fmt.Errorf("reading config from stdin: %v", err) + return nil, "", "", fmt.Errorf("reading config from stdin: %v", err) } logger.Info("using config from stdin") } else { config, err = os.ReadFile(configFile) if err != nil { - return nil, "", fmt.Errorf("reading config from file: %v", err) + return nil, "", "", fmt.Errorf("reading config from file: %v", err) } logger.Info("using config from file", zap.String("file", configFile)) } @@ -179,7 +184,7 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([ cfgAdapter = nil } else if err != nil { // default Caddyfile exists, but error reading it - return nil, "", fmt.Errorf("reading default Caddyfile: %v", err) + return nil, "", "", fmt.Errorf("reading default Caddyfile: %v", err) } else { // success reading default Caddyfile configFile = "Caddyfile" @@ -191,14 +196,14 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([ if yes, err := isCaddyfile(configFile, adapterName); yes { adapterName = "caddyfile" } else if err != nil { - return nil, "", err + return nil, "", "", err } // load config adapter if adapterName != "" { cfgAdapter = caddyconfig.GetAdapter(adapterName) if cfgAdapter == nil { - return nil, "", fmt.Errorf("unrecognized config adapter: %s", adapterName) + return nil, "", "", fmt.Errorf("unrecognized config adapter: %s", adapterName) } } @@ -208,7 +213,7 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([ "filename": configFile, }) if err != nil { - return nil, "", fmt.Errorf("adapting config using %s: %v", adapterName, err) + return nil, "", "", fmt.Errorf("adapting config using %s: %v", adapterName, err) } logger.Info("adapted config to JSON", zap.String("adapter", adapterName)) for _, warn := range warnings { @@ -226,11 +231,14 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([ // validate that the config is at least valid JSON err = json.Unmarshal(config, new(any)) if err != nil { - return nil, "", fmt.Errorf("config is not valid JSON: %v; did you mean to use a config adapter (the --adapter flag)?", err) + if jsonErr, ok := err.(*json.SyntaxError); ok { + return nil, "", "", fmt.Errorf("config is not valid JSON: %w, at offset %d; did you mean to use a config adapter (the --adapter flag)?", err, jsonErr.Offset) + } + return nil, "", "", fmt.Errorf("config is not valid JSON: %w; did you mean to use a config adapter (the --adapter flag)?", err) } } - return config, configFile, nil + return config, configFile, adapterName, nil } // watchConfigFile watches the config file at filename for changes @@ -256,7 +264,7 @@ func watchConfigFile(filename, adapterName string) { } // get current config - lastCfg, _, err := loadConfigWithLogger(nil, filename, adapterName) + lastCfg, _, _, err := loadConfigWithLogger(nil, filename, adapterName) if err != nil { logger().Error("unable to load latest config", zap.Error(err)) return @@ -268,7 +276,7 @@ func watchConfigFile(filename, adapterName string) { //nolint:staticcheck for range time.Tick(1 * time.Second) { // get current config - newCfg, _, err := loadConfigWithLogger(nil, filename, adapterName) + newCfg, _, _, err := loadConfigWithLogger(nil, filename, adapterName) if err != nil { logger().Error("unable to load latest config", zap.Error(err)) return @@ -418,7 +426,7 @@ func parseEnvFile(envInput io.Reader) (map[string]string, error) { // quoted value: support newlines if strings.HasPrefix(val, `"`) || strings.HasPrefix(val, "'") { quote := string(val[0]) - for !(strings.HasSuffix(line, quote) && !strings.HasSuffix(line, `\`+quote)) { + for !strings.HasSuffix(line, quote) || strings.HasSuffix(line, `\`+quote) { val = strings.ReplaceAll(val, `\`+quote, quote) if !scanner.Scan() { break @@ -476,7 +484,13 @@ func setResourceLimits(logger *zap.Logger) func() { // See https://pkg.go.dev/runtime/debug#SetMemoryLimit _, _ = memlimit.SetGoMemLimitWithOpts( memlimit.WithLogger( - slog.New(zapslog.NewHandler(logger.Core())), + slog.New(zapslog.NewHandler( + logger.Core(), + zapslog.WithName("memlimit"), + // the default enables traces at ERROR level, this disables + // them by setting it to a level higher than any other level + zapslog.AddStacktraceAt(slog.Level(127)), + )), ), memlimit.WithProvider( memlimit.ApplyFallback( diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/packagesfuncs.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/packagesfuncs.go index 695232001..a26919922 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/packagesfuncs.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/packagesfuncs.go @@ -62,7 +62,7 @@ func splitModule(arg string) (module, version string, err error) { err = fmt.Errorf("module name is required") } - return + return module, version, err } func cmdAddPackage(fl Flags) (int, error) { @@ -84,7 +84,7 @@ func cmdAddPackage(fl Flags) (int, error) { return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid module name: %v", err) } // only allow a version to be specified if it's different from the existing version - if _, ok := pluginPkgs[module]; ok && !(version != "" && pluginPkgs[module].Version != version) { + if _, ok := pluginPkgs[module]; ok && (version == "" || pluginPkgs[module].Version == version) { return caddy.ExitCodeFailedStartup, fmt.Errorf("package is already added") } pluginPkgs[module] = pluginPackage{Version: version, Path: module} @@ -217,7 +217,7 @@ func getModules() (standard, nonstandard, unknown []moduleInfo, err error) { bi, ok := debug.ReadBuildInfo() if !ok { err = fmt.Errorf("no build info") - return + return standard, nonstandard, unknown, err } for _, modID := range caddy.Modules() { @@ -234,7 +234,7 @@ func getModules() (standard, nonstandard, unknown []moduleInfo, err error) { // not sure why), and since New() should return a pointer // value, we need to dereference it first iface := any(modInfo.New()) - if rv := reflect.ValueOf(iface); rv.Kind() == reflect.Ptr { + if rv := reflect.ValueOf(iface); rv.Kind() == reflect.Pointer { iface = reflect.New(reflect.TypeOf(iface).Elem()).Elem().Interface() } modPkgPath := reflect.TypeOf(iface).PkgPath() @@ -260,7 +260,7 @@ func getModules() (standard, nonstandard, unknown []moduleInfo, err error) { nonstandard = append(nonstandard, caddyModGoMod) } } - return + return standard, nonstandard, unknown, err } func listModules(path string) error { diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/storagefuncs.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/storagefuncs.go index 3c4219719..5606fe4ae 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/storagefuncs.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/cmd/storagefuncs.go @@ -36,7 +36,7 @@ type storVal struct { // determineStorage returns the top-level storage module from the given config. // It may return nil even if no error. func determineStorage(configFile string, configAdapter string) (*storVal, error) { - cfg, _, err := LoadConfig(configFile, configAdapter) + cfg, _, _, err := LoadConfig(configFile, configAdapter) if err != nil { return nil, err } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/context.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/context.go index a65814f03..f71d635e2 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/context.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/context.go @@ -21,12 +21,14 @@ import ( "log" "log/slog" "reflect" + "sync" "github.com/caddyserver/certmagic" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "go.uber.org/zap" "go.uber.org/zap/exp/zapslog" + "go.uber.org/zap/zapcore" "github.com/caddyserver/caddy/v2/internal/filesystems" ) @@ -61,10 +63,17 @@ type Context struct { // modules which are loaded will be properly unloaded. // See standard library context package's documentation. func NewContext(ctx Context) (Context, context.CancelFunc) { + newCtx, cancelCause := NewContextWithCause(ctx) + return newCtx, func() { cancelCause(nil) } +} + +// NewContextWithCause is like NewContext but returns a context.CancelCauseFunc. +// EXPERIMENTAL: This API is subject to change. +func NewContextWithCause(ctx Context) (Context, context.CancelCauseFunc) { newCtx := Context{moduleInstances: make(map[string][]Module), cfg: ctx.cfg, metricsRegistry: prometheus.NewPedanticRegistry()} - c, cancel := context.WithCancel(ctx.Context) - wrappedCancel := func() { - cancel() + c, cancel := context.WithCancelCause(ctx.Context) + wrappedCancel := func(cause error) { + cancel(cause) for _, f := range ctx.cleanupFuncs { f() @@ -369,7 +378,7 @@ func (ctx Context) LoadModuleByID(id string, rawMsg json.RawMessage) (any, error // value must be a pointer for unmarshaling into concrete type, even if // the module's concrete type is a slice or map; New() *should* return // a pointer, otherwise unmarshaling errors or panics will occur - if rv := reflect.ValueOf(val); rv.Kind() != reflect.Ptr { + if rv := reflect.ValueOf(val); rv.Kind() != reflect.Pointer { log.Printf("[WARNING] ModuleInfo.New() for module '%s' did not return a pointer,"+ " so we are using reflection to make a pointer instead; please fix this by"+ " using new(Type) or &Type notation in your module's New() function.", id) @@ -393,6 +402,8 @@ func (ctx Context) LoadModuleByID(id string, rawMsg json.RawMessage) (any, error return nil, fmt.Errorf("module value cannot be null") } + var err error + // if this is an app module, keep a reference to it, // since submodules may need to reference it during // provisioning (even though the parent app module @@ -402,12 +413,17 @@ func (ctx Context) LoadModuleByID(id string, rawMsg json.RawMessage) (any, error // module has been configured for DNS challenges) if appModule, ok := val.(App); ok { ctx.cfg.apps[id] = appModule + defer func() { + if err != nil { + ctx.cfg.failedApps[id] = err + } + }() } ctx.ancestry = append(ctx.ancestry, val) if prov, ok := val.(Provisioner); ok { - err := prov.Provision(ctx) + err = prov.Provision(ctx) if err != nil { // incomplete provisioning could have left state // dangling, so make sure it gets cleaned up @@ -422,7 +438,7 @@ func (ctx Context) LoadModuleByID(id string, rawMsg json.RawMessage) (any, error } if validator, ok := val.(Validator); ok { - err := validator.Validate() + err = validator.Validate() if err != nil { // since the module was already provisioned, make sure we clean up if cleanerUpper, ok := val.(CleanerUpper); ok { @@ -487,6 +503,10 @@ func (ctx Context) loadModuleInline(moduleNameKey, moduleScope string, raw json. // or stop App modules. The caller is expected to assert to the // concrete type. func (ctx Context) App(name string) (any, error) { + // if the app failed to load before, return the cached error + if err, ok := ctx.cfg.failedApps[name]; ok { + return nil, fmt.Errorf("loading %s app module: %v", name, err) + } if app, ok := ctx.cfg.apps[name]; ok { return app, nil } @@ -511,6 +531,10 @@ func (ctx Context) AppIfConfigured(name string) (any, error) { if ctx.cfg == nil { return nil, fmt.Errorf("app module %s: %w", name, ErrNotConfigured) } + // if the app failed to load before, return the cached error + if err, ok := ctx.cfg.failedApps[name]; ok { + return nil, fmt.Errorf("loading %s app module: %v", name, err) + } if app, ok := ctx.cfg.apps[name]; ok { return app, nil } @@ -568,24 +592,62 @@ func (ctx Context) Logger(module ...Module) *zap.Logger { return ctx.cfg.Logging.Logger(mod) } +type slogHandlerFactory func(handler slog.Handler, core zapcore.Core, moduleID string) slog.Handler + +var ( + slogHandlerFactories []slogHandlerFactory + slogHandlerFactoriesMu sync.RWMutex +) + +// RegisterSlogHandlerFactory allows modules to register custom log/slog.Handler, +// for instance, to add contextual data to the logs. +func RegisterSlogHandlerFactory(factory slogHandlerFactory) { + slogHandlerFactoriesMu.Lock() + slogHandlerFactories = append(slogHandlerFactories, factory) + slogHandlerFactoriesMu.Unlock() +} + // Slogger returns a slog logger that is intended for use by // the most recent module associated with the context. func (ctx Context) Slogger() *slog.Logger { + var ( + handler slog.Handler + core zapcore.Core + moduleID string + ) + + // the default enables traces at ERROR level, this disables + // them by setting it to a level higher than any other level + tracesOpt := zapslog.AddStacktraceAt(slog.Level(127)) + if ctx.cfg == nil { // often the case in tests; just use a dev logger l, err := zap.NewDevelopment() if err != nil { panic("config missing, unable to create dev logger: " + err.Error()) } - return slog.New(zapslog.NewHandler(l.Core(), nil)) + + core = l.Core() + handler = zapslog.NewHandler(core, tracesOpt) + } else { + mod := ctx.Module() + if mod == nil { + core = Log().Core() + handler = zapslog.NewHandler(core, tracesOpt) + } else { + moduleID = string(mod.CaddyModule().ID) + core = ctx.cfg.Logging.Logger(mod).Core() + handler = zapslog.NewHandler(core, zapslog.WithName(moduleID), tracesOpt) + } } - mod := ctx.Module() - if mod == nil { - return slog.New(zapslog.NewHandler(Log().Core(), nil)) + + slogHandlerFactoriesMu.RLock() + for _, f := range slogHandlerFactories { + handler = f(handler, core, moduleID) } - return slog.New(zapslog.NewHandler(ctx.cfg.Logging.Logger(mod).Core(), - zapslog.WithName(string(mod.CaddyModule().ID)), - )) + slogHandlerFactoriesMu.RUnlock() + + return slog.New(handler) } // Modules returns the lineage of modules that this context provisioned, diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/internal/logbuffer.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/internal/logbuffer.go new file mode 100644 index 000000000..991041bd8 --- /dev/null +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/internal/logbuffer.go @@ -0,0 +1,82 @@ +// Copyright 2015 Matthew Holt and The Caddy 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 internal + +import ( + "sync" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +// LogBufferCore is a zapcore.Core that buffers log entries in memory. +type LogBufferCore struct { + mu sync.Mutex + entries []zapcore.Entry + fields [][]zapcore.Field + level zapcore.LevelEnabler +} + +type LogBufferCoreInterface interface { + zapcore.Core + FlushTo(*zap.Logger) +} + +func NewLogBufferCore(level zapcore.LevelEnabler) *LogBufferCore { + return &LogBufferCore{ + level: level, + } +} + +func (c *LogBufferCore) Enabled(lvl zapcore.Level) bool { + return c.level.Enabled(lvl) +} + +func (c *LogBufferCore) With(fields []zapcore.Field) zapcore.Core { + return c +} + +func (c *LogBufferCore) Check(entry zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry { + if c.Enabled(entry.Level) { + return ce.AddCore(entry, c) + } + return ce +} + +func (c *LogBufferCore) Write(entry zapcore.Entry, fields []zapcore.Field) error { + c.mu.Lock() + defer c.mu.Unlock() + c.entries = append(c.entries, entry) + c.fields = append(c.fields, fields) + return nil +} + +func (c *LogBufferCore) Sync() error { return nil } + +// FlushTo flushes buffered logs to the given zap.Logger. +func (c *LogBufferCore) FlushTo(logger *zap.Logger) { + c.mu.Lock() + defer c.mu.Unlock() + for idx, entry := range c.entries { + logger.WithOptions().Check(entry.Level, entry.Message).Write(c.fields[idx]...) + } + c.entries = nil + c.fields = nil +} + +var ( + _ zapcore.Core = (*LogBufferCore)(nil) + _ LogBufferCoreInterface = (*LogBufferCore)(nil) +) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/internal/logmarshalers.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/internal/logmarshalers.go new file mode 100644 index 000000000..3a8a553e6 --- /dev/null +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/internal/logmarshalers.go @@ -0,0 +1,54 @@ +package internal + +import ( + "net/http" + "strings" + + "go.uber.org/zap/zapcore" +) + +// LoggableHTTPHeader makes an HTTP header loggable with zap.Object(). +// Headers with potentially sensitive information (Cookie, Set-Cookie, +// Authorization, and Proxy-Authorization) are logged with empty values. +type LoggableHTTPHeader struct { + http.Header + + ShouldLogCredentials bool +} + +// MarshalLogObject satisfies the zapcore.ObjectMarshaler interface. +func (h LoggableHTTPHeader) MarshalLogObject(enc zapcore.ObjectEncoder) error { + if h.Header == nil { + return nil + } + for key, val := range h.Header { + if !h.ShouldLogCredentials { + switch strings.ToLower(key) { + case "cookie", "set-cookie", "authorization", "proxy-authorization": + val = []string{"REDACTED"} // see #5669. I still think ▒▒▒▒ would be cool. + } + } + enc.AddArray(key, LoggableStringArray(val)) + } + return nil +} + +// LoggableStringArray makes a slice of strings marshalable for logging. +type LoggableStringArray []string + +// MarshalLogArray satisfies the zapcore.ArrayMarshaler interface. +func (sa LoggableStringArray) MarshalLogArray(enc zapcore.ArrayEncoder) error { + if sa == nil { + return nil + } + for _, s := range sa { + enc.AppendString(s) + } + return nil +} + +// Interface guards +var ( + _ zapcore.ObjectMarshaler = (*LoggableHTTPHeader)(nil) + _ zapcore.ArrayMarshaler = (*LoggableStringArray)(nil) +) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen.go index 1a7051bbf..21df13ff4 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen.go @@ -30,10 +30,6 @@ import ( "go.uber.org/zap" ) -func reuseUnixSocket(_, _ string) (any, error) { - return nil, nil -} - func listenReusable(ctx context.Context, lnKey string, network, address string, config net.ListenConfig) (any, error) { var socketFile *os.File @@ -107,7 +103,8 @@ func listenReusable(ctx context.Context, lnKey string, network, address string, if err != nil { return nil, err } - return &fakeCloseListener{sharedListener: sharedLn.(*sharedListener), keepAlivePeriod: config.KeepAlive}, nil + + return &fakeCloseListener{sharedListener: sharedLn.(*sharedListener), keepAliveConfig: config.KeepAliveConfig}, nil } // fakeCloseListener is a private wrapper over a listener that @@ -119,19 +116,18 @@ func listenReusable(ctx context.Context, lnKey string, network, address string, // re-wrapped in a new fakeCloseListener each time the listener // is reused. This type is atomic and values must not be copied. type fakeCloseListener struct { - closed int32 // accessed atomically; belongs to this struct only - *sharedListener // embedded, so we also become a net.Listener - keepAlivePeriod time.Duration + closed atomic.Bool + *sharedListener // embedded, so we also become a net.Listener + keepAliveConfig net.KeepAliveConfig } -type canSetKeepAlive interface { - SetKeepAlivePeriod(d time.Duration) error - SetKeepAlive(bool) error +type canSetKeepAliveConfig interface { + SetKeepAliveConfig(config net.KeepAliveConfig) error } func (fcl *fakeCloseListener) Accept() (net.Conn, error) { // if the listener is already "closed", return error - if atomic.LoadInt32(&fcl.closed) == 1 { + if fcl.closed.Load() { return nil, fakeClosedErr(fcl) } @@ -140,12 +136,8 @@ func (fcl *fakeCloseListener) Accept() (net.Conn, error) { if err == nil { // if 0, do nothing, Go's default is already set // and if the connection allows setting KeepAlive, set it - if tconn, ok := conn.(canSetKeepAlive); ok && fcl.keepAlivePeriod != 0 { - if fcl.keepAlivePeriod > 0 { - err = tconn.SetKeepAlivePeriod(fcl.keepAlivePeriod) - } else { // negative - err = tconn.SetKeepAlive(false) - } + if tconn, ok := conn.(canSetKeepAliveConfig); ok && fcl.keepAliveConfig.Enable { + err = tconn.SetKeepAliveConfig(fcl.keepAliveConfig) if err != nil { Log().With(zap.String("server", fcl.sharedListener.key)).Warn("unable to set keepalive for new connection:", zap.Error(err)) } @@ -159,7 +151,7 @@ func (fcl *fakeCloseListener) Accept() (net.Conn, error) { // that we set when Close() was called, and return a non-temporary and // non-timeout error value to the caller, masking the "true" error, so // that server loops / goroutines won't retry, linger, and leak - if atomic.LoadInt32(&fcl.closed) == 1 { + if fcl.closed.Load() { // we dereference the sharedListener explicitly even though it's embedded // so that it's clear in the code that side-effects are shared with other // users of this listener, not just our own reference to it; we also don't @@ -179,7 +171,7 @@ func (fcl *fakeCloseListener) Accept() (net.Conn, error) { // underlying listener. The underlying listener is only closed // if the caller is the last known user of the socket. func (fcl *fakeCloseListener) Close() error { - if atomic.CompareAndSwapInt32(&fcl.closed, 0, 1) { + if fcl.closed.CompareAndSwap(false, true) { // There are two ways I know of to get an Accept() // function to return to the server loop that called // it: close the listener, or set a deadline in the @@ -242,13 +234,13 @@ func (sl *sharedListener) Destruct() error { // fakeClosePacketConn is like fakeCloseListener, but for PacketConns, // or more specifically, *net.UDPConn type fakeClosePacketConn struct { - closed int32 // accessed atomically; belongs to this struct only - *sharedPacketConn // embedded, so we also become a net.PacketConn; its key is used in Close + closed atomic.Bool + *sharedPacketConn // embedded, so we also become a net.PacketConn; its key is used in Close } func (fcpc *fakeClosePacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) { // if the listener is already "closed", return error - if atomic.LoadInt32(&fcpc.closed) == 1 { + if fcpc.closed.Load() { return 0, nil, &net.OpError{ Op: "readfrom", Net: fcpc.LocalAddr().Network(), @@ -262,22 +254,22 @@ func (fcpc *fakeClosePacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err e if err != nil { // this server was stopped, so clear the deadline and let // any new server continue reading; but we will exit - if atomic.LoadInt32(&fcpc.closed) == 1 { + if fcpc.closed.Load() { if netErr, ok := err.(net.Error); ok && netErr.Timeout() { if err = fcpc.SetReadDeadline(time.Time{}); err != nil { - return + return n, addr, err } } } - return + return n, addr, err } - return + return n, addr, err } // Close won't close the underlying socket unless there is no more reference, then listenerPool will close it. func (fcpc *fakeClosePacketConn) Close() error { - if atomic.CompareAndSwapInt32(&fcpc.closed, 0, 1) { + if fcpc.closed.CompareAndSwap(false, true) { _ = fcpc.SetReadDeadline(time.Now()) // unblock ReadFrom() calls to kick old servers out of their loops _, _ = listenerPool.Delete(fcpc.sharedPacketConn.key) } diff --git a/plugins/traefik/vendor/go.uber.org/mock/mockgen/version.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen_reuseUnixSocket.go similarity index 60% rename from plugins/traefik/vendor/go.uber.org/mock/mockgen/version.go rename to plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen_reuseUnixSocket.go index 6db160ac2..006610edc 100644 --- a/plugins/traefik/vendor/go.uber.org/mock/mockgen/version.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen_reuseUnixSocket.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2015 Matthew Holt and The Caddy Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,20 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -package main +//go:build (!unix || solaris) && !windows -import ( - "fmt" - "log" - "runtime/debug" -) +package caddy -func printModuleVersion() { - if bi, exists := debug.ReadBuildInfo(); exists { - fmt.Println(bi.Main.Version) - } else { - log.Printf("No version information found. Make sure to use " + - "GO111MODULE=on when running 'go get' in order to use specific " + - "version of the binary.") - } +func reuseUnixSocket(_, _ string) (any, error) { + return nil, nil } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen_reuseUnixSocket_windows.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen_reuseUnixSocket_windows.go new file mode 100644 index 000000000..9c547933e --- /dev/null +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen_reuseUnixSocket_windows.go @@ -0,0 +1,89 @@ +// Copyright 2015 Matthew Holt and The Caddy 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. + +//go:build windows + +package caddy + +import ( + "errors" + "fmt" + "io/fs" + "net" + "os" + "strings" + "syscall" + "time" +) + +var errUnixSocketAlreadyInUse = errors.New("unix socket is already in use by another process") + +func reuseUnixSocket(network, addr string) (any, error) { + if !IsUnixNetwork(network) { + return nil, nil + } + + // Note: This is here mainly for proper compatibility, because Unix sockets with abstract names are in an interesting limbo state on Windows: + // Go already translates `@` characters to `\0` for Windows: https://github.com/golang/go/blob/65d5c5f6dd8aa7b221cff6ec3f5101ea2e5f3efa/src/syscall/syscall_windows.go#L910 + // ...but there still is an open issue about the fact that this is not properly supported: https://github.com/microsoft/WSL/issues/4240#issuecomment-620805115 + // The main issue is that the original announcement proclaimed support for this feature, but it was (apparently) never implemented: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ + isAbstractUnixSocket := strings.HasPrefix(addr, "@") + + if isAbstractUnixSocket { + // Abstract Unix sockets do not require us to remove stale socket files. + return nil, nil + } + + // On Windows, we're using the `fakeCloseListener` wrappers around a single, ever-living listener. + // So, if there's an active listener entry in the pool, we're the current owner of the Unix socket file. + _, socketBelongsToCurrentProcess := listenerPool.References(listenerKey(network, addr)) + + if socketBelongsToCurrentProcess { + // Reuse/cleanup is entirely handled by the refcounting mechanism in `listenerPool`. + return nil, nil + } + + // If the socket file does not exist or has no backing server process, this will fail instantly. + connection, err := net.DialTimeout("unix", addr, 10*time.Millisecond) + + if err == nil { + connection.Close() + return nil, fmt.Errorf("cannot reuse socket %v: %w", addr, errUnixSocketAlreadyInUse) + } + + // Windows returns this error code both if the socket file does not exist and if it isn't backed by a server process anymore. + // See: https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2#wsaeconnrefused + const WSAECONNREFUSED syscall.Errno = 10061 + + var errno syscall.Errno + hasNoListeningServerProcess := errors.As(err, &errno) && errno == WSAECONNREFUSED + + if !hasNoListeningServerProcess { + return nil, fmt.Errorf("cannot reuse socket %v: %w", addr, errUnixSocketAlreadyInUse) + } + + // If the socket file exists, it hasn't been created by our process, and it seemingly + // isn't backed by a server process anymore. Try to delete it so we can bind to it later. + err = os.Remove(addr) + + if err == nil { + return nil, nil + } else if errors.Is(err, fs.ErrNotExist) { + // Either the file didn't exist in the first place, or it was deleted before we were able to. + return nil, nil + } else { + // We failed to delete the file. Likely, it belongs to another (active) process. + return nil, err + } +} diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen_unix.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen_unix.go index d6ae0cb8e..d60f69f3b 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen_unix.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listen_unix.go @@ -63,7 +63,7 @@ func reuseUnixSocket(network, addr string) (any, error) { if err != nil { return nil, err } - atomic.AddInt32(unixSocket.count, 1) + unixSocket.count.Add(1) unixSockets[socketKey] = &unixListener{ln.(*net.UnixListener), socketKey, unixSocket.count} case *unixConn: @@ -71,7 +71,7 @@ func reuseUnixSocket(network, addr string) (any, error) { if err != nil { return nil, err } - atomic.AddInt32(unixSocket.count, 1) + unixSocket.count.Add(1) unixSockets[socketKey] = &unixConn{pc.(*net.UnixConn), socketKey, unixSocket.count} } @@ -165,8 +165,9 @@ func listenReusable(ctx context.Context, lnKey string, network, address string, if !fd { // TODO: Not 100% sure this is necessary, but we do this for net.UnixListener, so... if unix, ok := ln.(*net.UnixConn); ok { - one := int32(1) - ln = &unixConn{unix, lnKey, &one} + cnt := new(atomic.Int32) + cnt.Store(1) + ln = &unixConn{unix, lnKey, cnt} unixSockets[lnKey] = ln.(*unixConn) } } @@ -181,8 +182,9 @@ func listenReusable(ctx context.Context, lnKey string, network, address string, // (we do our own "unlink on close" -- not required, but more tidy) if unix, ok := ln.(*net.UnixListener); ok { unix.SetUnlinkOnClose(false) - one := int32(1) - ln = &unixListener{unix, lnKey, &one} + cnt := new(atomic.Int32) + cnt.Store(1) + ln = &unixListener{unix, lnKey, cnt} unixSockets[lnKey] = ln.(*unixListener) } } @@ -216,11 +218,11 @@ func reusePort(network, address string, conn syscall.RawConn) error { type unixListener struct { *net.UnixListener mapKey string - count *int32 // accessed atomically + count *atomic.Int32 } func (uln *unixListener) Close() error { - newCount := atomic.AddInt32(uln.count, -1) + newCount := uln.count.Add(-1) if newCount == 0 { file, err := uln.File() var name string @@ -242,11 +244,11 @@ func (uln *unixListener) Close() error { type unixConn struct { *net.UnixConn mapKey string - count *int32 // accessed atomically + count *atomic.Int32 } func (uc *unixConn) Close() error { - newCount := atomic.AddInt32(uc.count, -1) + newCount := uc.count.Add(-1) if newCount == 0 { file, err := uc.File() var name string diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listeners.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listeners.go index 9e0057678..6031f98e4 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listeners.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/listeners.go @@ -31,7 +31,7 @@ import ( "github.com/quic-go/quic-go" "github.com/quic-go/quic-go/http3" - "github.com/quic-go/quic-go/qlog" + h3qlog "github.com/quic-go/quic-go/http3/qlog" "go.uber.org/zap" "golang.org/x/time/rate" @@ -229,7 +229,7 @@ func (na NetworkAddress) JoinHostPort(offset uint) string { func (na NetworkAddress) Expand() []NetworkAddress { size := na.PortRangeSize() addrs := make([]NetworkAddress, size) - for portOffset := uint(0); portOffset < size; portOffset++ { + for portOffset := range size { addrs[portOffset] = na.At(portOffset) } return addrs @@ -382,7 +382,7 @@ func SplitNetworkAddress(a string) (network, host, port string, err error) { a = afterSlash if IsUnixNetwork(network) || IsFdNetwork(network) { host = a - return + return network, host, port, err } } @@ -402,7 +402,7 @@ func SplitNetworkAddress(a string) (network, host, port string, err error) { err = errors.Join(firstErr, err) } - return + return network, host, port, err } // JoinNetworkAddress combines network, host, and port into a single @@ -430,7 +430,8 @@ func JoinNetworkAddress(network, host, port string) string { // address instead. // // NOTE: This API is EXPERIMENTAL and may be changed or removed. -func (na NetworkAddress) ListenQUIC(ctx context.Context, portOffset uint, config net.ListenConfig, tlsConf *tls.Config) (http3.QUICEarlyListener, error) { +// NOTE: user should close the returned listener twice, once to stop accepting new connections, the second time to free up the packet conn. +func (na NetworkAddress) ListenQUIC(ctx context.Context, portOffset uint, config net.ListenConfig, tlsConf *tls.Config, pcWrappers []PacketConnWrapper, allow0rttconf *bool) (http3.QUICListener, error) { lnKey := listenerKey("quic"+na.Network, na.JoinHostPort(portOffset)) sharedEarlyListener, _, err := listenerPool.LoadOrNew(lnKey, func() (Destructor, error) { @@ -442,19 +443,29 @@ func (na NetworkAddress) ListenQUIC(ctx context.Context, portOffset uint, config ln := lnAny.(net.PacketConn) h3ln := ln - for { - // retrieve the underlying socket, so quic-go can optimize. - if unwrapper, ok := h3ln.(interface{ Unwrap() net.PacketConn }); ok { - h3ln = unwrapper.Unwrap() - } else { - break + if len(pcWrappers) == 0 { + for { + // retrieve the underlying socket, so quic-go can optimize. + if unwrapper, ok := h3ln.(interface{ Unwrap() net.PacketConn }); ok { + h3ln = unwrapper.Unwrap() + } else { + break + } + } + } else { + // wrap packet conn before QUIC + for _, pcWrapper := range pcWrappers { + h3ln = pcWrapper.WrapPacketConn(h3ln) } } sqs := newSharedQUICState(tlsConf) // http3.ConfigureTLSConfig only uses this field and tls App sets this field as well //nolint:gosec - quicTlsConfig := &tls.Config{GetConfigForClient: sqs.getConfigForClient} + quicTlsConfig := &tls.Config{ + GetConfigForClient: sqs.getConfigForClient, + GetEncryptedClientHelloKeys: sqs.getEncryptedClientHelloKeys, + } // Require clients to verify their source address when we're handling more than 1000 handshakes per second. // TODO: make tunable? limiter := rate.NewLimiter(1000, 1000) @@ -462,11 +473,15 @@ func (na NetworkAddress) ListenQUIC(ctx context.Context, portOffset uint, config Conn: h3ln, VerifySourceAddress: func(addr net.Addr) bool { return !limiter.Allow() }, } + allow0rtt := true + if allow0rttconf != nil { + allow0rtt = *allow0rttconf + } earlyLn, err := tr.ListenEarly( http3.ConfigureTLSConfig(quicTlsConfig), &quic.Config{ - Allow0RTT: true, - Tracer: qlog.DefaultConnectionTracer, + Allow0RTT: allow0rtt, + Tracer: h3qlog.DefaultConnectionTracer, }, ) if err != nil { @@ -500,7 +515,7 @@ func ListenerUsage(network, addr string) int { // contextAndCancelFunc groups context and its cancelFunc type contextAndCancelFunc struct { context.Context - context.CancelFunc + context.CancelCauseFunc } // sharedQUICState manages GetConfigForClient @@ -528,19 +543,29 @@ func (sqs *sharedQUICState) getConfigForClient(ch *tls.ClientHelloInfo) (*tls.Co return sqs.activeTlsConf.GetConfigForClient(ch) } +// getEncryptedClientHelloKeys is used as tls.Config's GetEncryptedClientHelloKeys field. +func (sqs *sharedQUICState) getEncryptedClientHelloKeys(ch *tls.ClientHelloInfo) ([]tls.EncryptedClientHelloKey, error) { + sqs.rmu.RLock() + defer sqs.rmu.RUnlock() + if sqs.activeTlsConf.GetEncryptedClientHelloKeys == nil { + return nil, nil + } + return sqs.activeTlsConf.GetEncryptedClientHelloKeys(ch) +} + // addState adds tls.Config and activeRequests to the map if not present and returns the corresponding context and its cancelFunc // so that when cancelled, the active tls.Config will change -func (sqs *sharedQUICState) addState(tlsConfig *tls.Config) (context.Context, context.CancelFunc) { +func (sqs *sharedQUICState) addState(tlsConfig *tls.Config) (context.Context, context.CancelCauseFunc) { sqs.rmu.Lock() defer sqs.rmu.Unlock() if cacc, ok := sqs.tlsConfs[tlsConfig]; ok { - return cacc.Context, cacc.CancelFunc + return cacc.Context, cacc.CancelCauseFunc } - ctx, cancel := context.WithCancel(context.Background()) - wrappedCancel := func() { - cancel() + ctx, cancel := context.WithCancelCause(context.Background()) + wrappedCancel := func(cause error) { + cancel(cause) sqs.rmu.Lock() defer sqs.rmu.Unlock() @@ -596,13 +621,13 @@ func fakeClosedErr(l interface{ Addr() net.Addr }) error { // indicating that it is pretending to be closed so that the // server using it can terminate, while the underlying // socket is actually left open. -var errFakeClosed = fmt.Errorf("listener 'closed' 😉") +var errFakeClosed = fmt.Errorf("QUIC listener 'closed' 😉") type fakeCloseQuicListener struct { - closed int32 // accessed atomically; belongs to this struct only - *sharedQuicListener // embedded, so we also become a quic.EarlyListener + closed atomic.Int32 + *sharedQuicListener // embedded, so we also become a quic.EarlyListener context context.Context - contextCancel context.CancelFunc + contextCancel context.CancelCauseFunc } // Currently Accept ignores the passed context, however a situation where @@ -610,22 +635,23 @@ type fakeCloseQuicListener struct { // server on which Accept would be called with non-empty contexts // (mind that the default net listeners' Accept doesn't take a context argument) // sounds way too rare for us to sacrifice efficiency here. -func (fcql *fakeCloseQuicListener) Accept(_ context.Context) (quic.EarlyConnection, error) { +func (fcql *fakeCloseQuicListener) Accept(_ context.Context) (*quic.Conn, error) { conn, err := fcql.sharedQuicListener.Accept(fcql.context) if err == nil { return conn, nil } // if the listener is "closed", return a fake closed error instead - if atomic.LoadInt32(&fcql.closed) == 1 && errors.Is(err, context.Canceled) { + if fcql.closed.Load() == 1 && errors.Is(err, context.Canceled) { return nil, fakeClosedErr(fcql) } return nil, err } func (fcql *fakeCloseQuicListener) Close() error { - if atomic.CompareAndSwapInt32(&fcql.closed, 0, 1) { - fcql.contextCancel() + if fcql.closed.CompareAndSwap(0, 1) { + fcql.contextCancel(errFakeClosed) + } else if fcql.closed.CompareAndSwap(1, 2) { _, _ = listenerPool.Delete(fcql.sharedQuicListener.key) } return nil @@ -693,6 +719,19 @@ type ListenerWrapper interface { WrapListener(net.Listener) net.Listener } +// PacketConnWrapper is a type that wraps a packet conn +// so it can modify the input packet conn methods. +// Modules that implement this interface are found +// in the caddy.packetconns namespace. Usually, to +// wrap a packet conn, you will define your own struct +// type that embeds the input packet conn, then +// implement your own methods that you want to wrap, +// calling the underlying packet conn methods where +// appropriate. +type PacketConnWrapper interface { + WrapPacketConn(net.PacketConn) net.PacketConn +} + // listenerPool stores and allows reuse of active listeners. var listenerPool = NewUsagePool() diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/logging.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/logging.go index 128a54de7..2734b5425 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/logging.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/logging.go @@ -28,6 +28,8 @@ import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "golang.org/x/term" + + "github.com/caddyserver/caddy/v2/internal" ) func init() { @@ -162,7 +164,9 @@ func (logging *Logging) setupNewDefault(ctx Context) error { if err != nil { return fmt.Errorf("setting up default log: %v", err) } - newDefault.logger = zap.New(newDefault.CustomLog.core, options...) + + filteringCore := &filteringCore{newDefault.CustomLog.core, newDefault.CustomLog} + newDefault.logger = zap.New(filteringCore, options...) // redirect the default caddy logs defaultLoggerMu.Lock() @@ -188,6 +192,13 @@ func (logging *Logging) setupNewDefault(ctx Context) error { ) } + // if we had a buffered core, flush its contents ASAP + // before we try to log anything else, so the order of + // logs is preserved + if oldBufferCore, ok := oldDefault.logger.Core().(*internal.LogBufferCore); ok { + oldBufferCore.FlushTo(newDefault.logger) + } + return nil } @@ -771,6 +782,21 @@ func Log() *zap.Logger { return defaultLogger.logger } +// BufferedLog sets the default logger to one that buffers +// logs before a config is loaded. +// Returns the buffered logger, the original default logger +// (for flushing on errors), and the buffer core so that the +// caller can flush the logs after the config is loaded or +// fails to load. +func BufferedLog() (*zap.Logger, *zap.Logger, *internal.LogBufferCore) { + defaultLoggerMu.Lock() + defer defaultLoggerMu.Unlock() + origLogger := defaultLogger.logger + bufferCore := internal.NewLogBufferCore(zap.InfoLevel) + defaultLogger.logger = zap.New(bufferCore) + return defaultLogger.logger, origLogger, bufferCore +} + var ( coloringEnabled = os.Getenv("NO_COLOR") == "" && os.Getenv("TERM") != "xterm-mono" defaultLogger, _ = newDefaultProductionLog() diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules.go index 37b56a988..93a9343f6 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules.go @@ -342,12 +342,18 @@ func ParseStructTag(tag string) (map[string]string, error) { func StrictUnmarshalJSON(data []byte, v any) error { dec := json.NewDecoder(bytes.NewReader(data)) dec.DisallowUnknownFields() - return dec.Decode(v) + err := dec.Decode(v) + if jsonErr, ok := err.(*json.SyntaxError); ok { + return fmt.Errorf("%w, at offset %d", jsonErr, jsonErr.Offset) + } + return err } +var JSONRawMessageType = reflect.TypeFor[json.RawMessage]() + // isJSONRawMessage returns true if the type is encoding/json.RawMessage. func isJSONRawMessage(typ reflect.Type) bool { - return typ.PkgPath() == "encoding/json" && typ.Name() == "RawMessage" + return typ == JSONRawMessageType } // isModuleMapType returns true if the type is map[string]json.RawMessage. diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyevents/app.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyevents/app.go index 9fc8fa8ed..6c2abbf7c 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyevents/app.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyevents/app.go @@ -249,8 +249,8 @@ func (app *App) Emit(ctx caddy.Context, eventName string, data map[string]any) c return e.Data, true } - if strings.HasPrefix(key, "event.data.") { - key = strings.TrimPrefix(key, "event.data.") + if after, ok0 := strings.CutPrefix(key, "event.data."); ok0 { + key = after if val, ok := e.Data[key]; ok { return val, true } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/app.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/app.go index b550904e2..bc2b896cd 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/app.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/app.go @@ -18,8 +18,8 @@ import ( "cmp" "context" "crypto/tls" + "errors" "fmt" - "maps" "net" "net/http" "strconv" @@ -28,7 +28,6 @@ import ( "go.uber.org/zap" "golang.org/x/net/http2" - "golang.org/x/net/http2/h2c" "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/modules/caddyevents" @@ -52,6 +51,7 @@ func init() { // Placeholder | Description // ------------|--------------- // `{http.request.body}` | The request body (⚠️ inefficient; use only for debugging) +// `{http.request.body_base64}` | The request body, base64-encoded (⚠️ for debugging) // `{http.request.cookie.*}` | HTTP request cookie // `{http.request.duration}` | Time up to now spent handling the request (after decoding headers from client) // `{http.request.duration_ms}` | Same as 'duration', but in milliseconds. @@ -68,6 +68,7 @@ func init() { // `{http.request.orig_uri.path.dir}` | The request's original directory // `{http.request.orig_uri.path.file}` | The request's original filename // `{http.request.orig_uri.query}` | The request's original query string (without `?`) +// `{http.request.orig_uri.prefixed_query}` | The request's original query string with a `?` prefix, if non-empty // `{http.request.port}` | The port part of the request's Host header // `{http.request.proto}` | The protocol of the request // `{http.request.local.host}` | The host (IP) part of the local address the connection arrived on @@ -83,6 +84,7 @@ func init() { // `{http.request.tls.proto}` | The negotiated next protocol // `{http.request.tls.proto_mutual}` | The negotiated next protocol was advertised by the server // `{http.request.tls.server_name}` | The server name requested by the client, if any +// `{http.request.tls.ech}` | Whether ECH was offered by the client and accepted by the server // `{http.request.tls.client.fingerprint}` | The SHA256 checksum of the client certificate // `{http.request.tls.client.public_key}` | The public key of the client certificate. // `{http.request.tls.client.public_key_sha256}` | The SHA256 checksum of the client's public key. @@ -96,11 +98,15 @@ func init() { // `{http.request.tls.client.san.ips.*}` | SAN IP addresses (index optional) // `{http.request.tls.client.san.uris.*}` | SAN URIs (index optional) // `{http.request.uri}` | The full request URI +// `{http.request.uri_escaped}` | The full request URI with query-style URL encoding applied (using url.QueryEscape) // `{http.request.uri.path}` | The path component of the request URI +// `{http.request.uri.path_escaped}` | The path component of the request URI with query-style URL encoding applied (using url.QueryEscape) // `{http.request.uri.path.*}` | Parts of the path, split by `/` (0-based from left) // `{http.request.uri.path.dir}` | The directory, excluding leaf filename // `{http.request.uri.path.file}` | The filename of the path, excluding directory // `{http.request.uri.query}` | The query string (without `?`) +// `{http.request.uri.query_escaped}` | The query string with query-style URL encoding applied (using url.QueryEscape) +// `{http.request.uri.prefixed_query}` | The query string with a `?` prefix, if non-empty // `{http.request.uri.query.*}` | Individual query string value // `{http.response.header.*}` | Specific response header field // `{http.vars.*}` | Custom variables in the HTTP handler chain @@ -151,6 +157,11 @@ type App struct { logger *zap.Logger tlsApp *caddytls.TLS + // stopped indicates whether the app has stopped + // It can only happen if it has started successfully in the first place. + // Otherwise, Cleanup will call Stop to clean up resources. + stopped bool + // used temporarily between phases 1 and 2 of auto HTTPS allCertDomains map[string]struct{} } @@ -166,13 +177,15 @@ func (App) CaddyModule() caddy.ModuleInfo { // Provision sets up the app. func (app *App) Provision(ctx caddy.Context) error { // store some references + app.logger = ctx.Logger() + app.ctx = ctx + + // provision TLS and events apps tlsAppIface, err := ctx.App("tls") if err != nil { return fmt.Errorf("getting tls app: %v", err) } app.tlsApp = tlsAppIface.(*caddytls.TLS) - app.ctx = ctx - app.logger = ctx.Logger() eventsAppIface, err := ctx.App("events") if err != nil { @@ -192,6 +205,11 @@ func (app *App) Provision(ctx caddy.Context) error { if app.Metrics != nil { app.Metrics.init = sync.Once{} app.Metrics.httpMetrics = &httpMetrics{} + // Scan config for allowed hosts to prevent cardinality explosion + app.Metrics.scanConfigForHosts(app) + if err := app.Metrics.provisionOTLP(ctx); err != nil { + return err + } } // prepare each server oldContext := ctx.Context @@ -203,8 +221,6 @@ func (app *App) Provision(ctx caddy.Context) error { srv.ctx = ctx srv.logger = app.logger.Named("log") srv.errorLogger = app.logger.Named("log.error") - srv.shutdownAtMu = new(sync.RWMutex) - if srv.Metrics != nil { srv.logger.Warn("per-server 'metrics' is deprecated; use 'metrics' in the root 'http' app instead") app.Metrics = cmp.Or(app.Metrics, &Metrics{ @@ -224,21 +240,7 @@ func (app *App) Provision(ctx caddy.Context) error { // if no protocols configured explicitly, enable all except h2c if len(srv.Protocols) == 0 { - srv.Protocols = []string{"h1", "h2", "h3"} - } - - srvProtocolsUnique := map[string]struct{}{} - for _, srvProtocol := range srv.Protocols { - srvProtocolsUnique[srvProtocol] = struct{}{} - } - _, h1ok := srvProtocolsUnique["h1"] - _, h2ok := srvProtocolsUnique["h2"] - _, h2cok := srvProtocolsUnique["h2c"] - - // the Go standard library does not let us serve only HTTP/2 using - // http.Server; we would probably need to write our own server - if !h1ok && (h2ok || h2cok) { - return fmt.Errorf("server %s: cannot enable HTTP/2 or H2C without enabling HTTP/1.1; add h1 to protocols or remove h2/h2c", srvName) + srv.Protocols = srv.protocolsWithDefaults() } if srv.ListenProtocols != nil { @@ -249,44 +251,7 @@ func (app *App) Provision(ctx caddy.Context) error { for i, lnProtocols := range srv.ListenProtocols { if lnProtocols != nil { - // populate empty listen protocols with server protocols - lnProtocolsDefault := false - var lnProtocolsInclude []string - srvProtocolsInclude := maps.Clone(srvProtocolsUnique) - - // keep existing listener protocols unless they are empty - for _, lnProtocol := range lnProtocols { - if lnProtocol == "" { - lnProtocolsDefault = true - } else { - lnProtocolsInclude = append(lnProtocolsInclude, lnProtocol) - delete(srvProtocolsInclude, lnProtocol) - } - } - - // append server protocols to listener protocols if any listener protocols were empty - if lnProtocolsDefault { - for _, srvProtocol := range srv.Protocols { - if _, ok := srvProtocolsInclude[srvProtocol]; ok { - lnProtocolsInclude = append(lnProtocolsInclude, srvProtocol) - } - } - } - - lnProtocolsIncludeUnique := map[string]struct{}{} - for _, lnProtocol := range lnProtocolsInclude { - lnProtocolsIncludeUnique[lnProtocol] = struct{}{} - } - _, h1ok := lnProtocolsIncludeUnique["h1"] - _, h2ok := lnProtocolsIncludeUnique["h2"] - _, h2cok := lnProtocolsIncludeUnique["h2c"] - - // check if any listener protocols contain h2 or h2c without h1 - if !h1ok && (h2ok || h2cok) { - return fmt.Errorf("server %s, listener %d: cannot enable HTTP/2 or H2C without enabling HTTP/1.1; add h1 to protocols or remove h2/h2c", srvName, i) - } - - srv.ListenProtocols[i] = lnProtocolsInclude + srv.ListenProtocols[i] = srv.listenerProtocolsWithDefaults(lnProtocols) } } } @@ -360,6 +325,20 @@ func (app *App) Provision(ctx caddy.Context) error { srv.listenerWrappers = append([]caddy.ListenerWrapper{new(tlsPlaceholderWrapper)}, srv.listenerWrappers...) } } + + // set up each packet conn modifier + if srv.PacketConnWrappersRaw != nil { + vals, err := ctx.LoadModule(srv, "PacketConnWrappersRaw") + if err != nil { + return fmt.Errorf("loading packet conn wrapper modules: %v", err) + } + // if any wrappers were configured, they come before the QUIC handshake; + // unlike TLS above, there is no QUIC placeholder + for _, val := range vals.([]any) { + srv.packetConnWrappers = append(srv.packetConnWrappers, val.(caddy.PacketConnWrapper)) + } + } + // pre-compile the primary handler chain, and be sure to wrap it in our // route handler so that important security checks are done, etc. primaryRoute := emptyHandler @@ -443,6 +422,25 @@ func (app *App) Validate() error { return nil } +func removeTLSALPN(srv *Server, target string) { + for _, cp := range srv.TLSConnPolicies { + // the TLSConfig was already provisioned, so... manually remove it + for i, np := range cp.TLSConfig.NextProtos { + if np == target { + cp.TLSConfig.NextProtos = append(cp.TLSConfig.NextProtos[:i], cp.TLSConfig.NextProtos[i+1:]...) + break + } + } + // remove it from the parent connection policy too, just to keep things tidy + for i, alpn := range cp.ALPN { + if alpn == target { + cp.ALPN = append(cp.ALPN[:i], cp.ALPN[i+1:]...) + break + } + } + } +} + // Start runs the app. It finishes automatic HTTPS if enabled, // including management of certificates. func (app *App) Start() error { @@ -461,32 +459,44 @@ func (app *App) Start() error { MaxHeaderBytes: srv.MaxHeaderBytes, Handler: srv, ErrorLog: serverLogger, + Protocols: new(http.Protocols), ConnContext: func(ctx context.Context, c net.Conn) context.Context { - return context.WithValue(ctx, ConnCtxKey, c) + if nc, ok := c.(interface{ tlsNetConn() net.Conn }); ok { + getTlsConStateFunc := sync.OnceValue(func() *tls.ConnectionState { + tlsConnState := nc.tlsNetConn().(connectionStater).ConnectionState() + return &tlsConnState + }) + ctx = context.WithValue(ctx, tlsConnectionStateFuncCtxKey, getTlsConStateFunc) + } + return ctx }, } - h2server := new(http2.Server) // disable HTTP/2, which we enabled by default during provisioning if !srv.protocol("h2") { srv.server.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler)) - for _, cp := range srv.TLSConnPolicies { - // the TLSConfig was already provisioned, so... manually remove it - for i, np := range cp.TLSConfig.NextProtos { - if np == "h2" { - cp.TLSConfig.NextProtos = append(cp.TLSConfig.NextProtos[:i], cp.TLSConfig.NextProtos[i+1:]...) - break - } - } - // remove it from the parent connection policy too, just to keep things tidy - for i, alpn := range cp.ALPN { - if alpn == "h2" { - cp.ALPN = append(cp.ALPN[:i], cp.ALPN[i+1:]...) - break - } - } - } - } else { + removeTLSALPN(srv, "h2") + } + if !srv.protocol("h1") { + removeTLSALPN(srv, "http/1.1") + } + + // configure the http versions the server will serve + if srv.protocol("h1") { + srv.server.Protocols.SetHTTP1(true) + } + + if srv.protocol("h2") || srv.protocol("h2c") { + // skip setting h2 because if NextProtos is present, it's list of alpn versions will take precedence. + // it will always be present because http2.ConfigureServer will populate that field + // enabling h2c because some listener wrapper will wrap the connection that is no longer *tls.Conn + // However, we need to handle the case that if the connection is h2c but h2c is not enabled. We identify + // this type of connection by checking if it's behind a TLS listener wrapper or if it implements tls.ConnectionState. + srv.server.Protocols.SetUnencryptedHTTP2(true) + // when h2c is enabled but h2 disabled, we already removed h2 from NextProtos + // the handshake will never succeed with h2 + // http2.ConfigureServer will enable the server to handle both h2 and h2c + h2server := new(http2.Server) //nolint:errcheck http2.ConfigureServer(srv.server, h2server) } @@ -496,11 +506,6 @@ func (app *App) Start() error { tlsCfg := srv.TLSConnPolicies.TLSConfig(app.ctx) srv.configureServer(srv.server) - // enable H2C if configured - if srv.protocol("h2c") { - srv.server.Handler = h2c.NewHandler(srv, h2server) - } - for lnIndex, lnAddr := range srv.Listen { listenAddr, err := caddy.ParseNetworkAddress(lnAddr) if err != nil { @@ -531,7 +536,14 @@ func (app *App) Start() error { if h1ok || h2ok && useTLS || h2cok { // create the listener for this socket - lnAny, err := listenAddr.Listen(app.ctx, portOffset, net.ListenConfig{KeepAlive: time.Duration(srv.KeepAliveInterval)}) + lnAny, err := listenAddr.Listen(app.ctx, portOffset, net.ListenConfig{ + KeepAliveConfig: net.KeepAliveConfig{ + Enable: srv.KeepAliveInterval >= 0, + Interval: time.Duration(srv.KeepAliveInterval), + Idle: time.Duration(srv.KeepAliveIdle), + Count: srv.KeepAliveCount, + }, + }) if err != nil { return fmt.Errorf("listening on %s: %v", listenAddr.At(portOffset), err) } @@ -560,15 +572,13 @@ func (app *App) Start() error { ln = srv.listenerWrappers[i].WrapListener(ln) } - // handle http2 if use tls listener wrapper - if h2ok { - http2lnWrapper := &http2Listener{ - Listener: ln, - server: srv.server, - h2server: h2server, - } - srv.h2listeners = append(srv.h2listeners, http2lnWrapper) - ln = http2lnWrapper + // check if the connection is h2c + ln = &http2Listener{ + useTLS: useTLS, + useH1: h1ok, + useH2: h2ok || h2cok, + Listener: ln, + logger: app.logger, } // if binding to port 0, the OS chooses a port for us; @@ -586,11 +596,8 @@ func (app *App) Start() error { srv.listeners = append(srv.listeners, ln) - // enable HTTP/1 if configured - if h1ok { - //nolint:errcheck - go srv.server.Serve(ln) - } + //nolint:errcheck + go srv.server.Serve(ln) } if h2ok && !useTLS { @@ -658,9 +665,7 @@ func (app *App) Stop() error { for _, addr := range na.Expand() { if caddy.ListenerUsage(addr.Network, addr.JoinHostPort(0)) < 2 { app.logger.Debug("listener closing and shutdown delay is configured", zap.String("address", addr.String())) - server.shutdownAtMu.Lock() - server.shutdownAt = scheduledTime - server.shutdownAtMu.Unlock() + server.shutdownAt.Store(&scheduledTime) delay = true } else { app.logger.Debug("shutdown delay configured but listener will remain open", zap.String("address", addr.String())) @@ -681,9 +686,10 @@ func (app *App) Stop() error { // enforce grace period if configured if app.GracePeriod > 0 { var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, time.Duration(app.GracePeriod)) + timeout := time.Duration(app.GracePeriod) + ctx, cancel = context.WithTimeoutCause(ctx, timeout, fmt.Errorf("server graceful shutdown %ds timeout", int(timeout.Seconds()))) defer cancel() - app.logger.Info("servers shutting down; grace period initiated", zap.Duration("duration", time.Duration(app.GracePeriod))) + app.logger.Info("servers shutting down; grace period initiated", zap.Duration("duration", timeout)) } else { app.logger.Info("servers shutting down with eternal grace period") } @@ -703,7 +709,15 @@ func (app *App) Stop() error { defer finishedShutdown.Done() startedShutdown.Done() + // possible if server failed to Start + if server.server == nil { + return + } + if err := server.server.Shutdown(ctx); err != nil { + if cause := context.Cause(ctx); cause != nil && errors.Is(err, context.DeadlineExceeded) { + err = cause + } app.logger.Error("server shutdown", zap.Error(err), zap.Strings("addresses", server.Listen)) @@ -717,31 +731,39 @@ func (app *App) Stop() error { return } + // closing quic listeners won't affect accepted connections now + // so like stdlib, close listeners first, but keep the net.PacketConns open + for _, h3ln := range server.quicListeners { + if err := h3ln.Close(); err != nil { + app.logger.Error("http3 listener close", + zap.Error(err)) + } + } + if err := server.h3server.Shutdown(ctx); err != nil { + if cause := context.Cause(ctx); cause != nil && errors.Is(err, context.DeadlineExceeded) { + err = cause + } app.logger.Error("HTTP/3 server shutdown", zap.Error(err), zap.Strings("addresses", server.Listen)) } - } - stopH2Listener := func(server *Server) { - defer finishedShutdown.Done() - startedShutdown.Done() - for i, s := range server.h2listeners { - if err := s.Shutdown(ctx); err != nil { - app.logger.Error("http2 listener shutdown", - zap.Error(err), - zap.Int("index", i)) + // close the underlying net.PacketConns now + // see the comment for ListenQUIC + for _, h3ln := range server.quicListeners { + if err := h3ln.Close(); err != nil { + app.logger.Error("http3 listener close socket", + zap.Error(err)) } } } for _, server := range app.Servers { - startedShutdown.Add(3) - finishedShutdown.Add(3) + startedShutdown.Add(2) + finishedShutdown.Add(2) go stopServer(server) go stopH3Server(server) - go stopH2Listener(server) } // block until all the goroutines have been run by the scheduler; @@ -768,9 +790,26 @@ func (app *App) Stop() error { } } + // flush and shut down the OTLP metrics exporter (if configured) so any + // last data point reaches the collector before the process exits + if err := app.Metrics.shutdown(ctx); err != nil { + app.logger.Error("shutting down OTLP metrics", zap.Error(err)) + } + + app.stopped = true return nil } +// Cleanup will close remaining listeners if they still remain +// because some of the servers fail to start. +// It simply calls Stop because Stop won't be called when Start fails. +func (app *App) Cleanup() error { + if app.stopped { + return nil + } + return app.Stop() +} + func (app *App) httpPort() int { if app.HTTPPort == 0 { return DefaultHTTPPort diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/autohttps.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/autohttps.go index ce8e6f8df..4e5b85f65 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/autohttps.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/autohttps.go @@ -90,7 +90,16 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er // the log configuration for an HTTPS enabled server var logCfg *ServerLogConfig - for srvName, srv := range app.Servers { + // Sort server names to ensure deterministic iteration. + // This prevents race conditions where the order of server processing + // could affect which server gets assigned the HTTP->HTTPS redirect listener. + srvNames := make([]string, 0, len(app.Servers)) + for name := range app.Servers { + srvNames = append(srvNames, name) + } + slices.Sort(srvNames) + for _, srvName := range srvNames { + srv := app.Servers[srvName] // as a prerequisite, provision route matchers; this is // required for all routes on all servers, and must be // done before we attempt to do phase 1 of auto HTTPS, @@ -164,7 +173,7 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er for d := range serverDomainSet { echDomains = append(echDomains, d) } - app.tlsApp.RegisterServerNames(echDomains) + app.tlsApp.RegisterServerNames(echDomains, httpsRRALPNs(srv)) // nothing more to do here if there are no domains that qualify for // automatic HTTPS and there are no explicit TLS connection policies: @@ -249,22 +258,33 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er // an empty string to indicate a catch-all, which we have to // treat special later if len(serverDomainSet) == 0 { - redirDomains[""] = append(redirDomains[""], addr) + app.recordAutoHTTPSRedirectAddress(redirDomains, "", addr) continue } // ...and associate it with each domain in this server for d := range serverDomainSet { - // if this domain is used on more than one HTTPS-enabled - // port, we'll have to choose one, so prefer the HTTPS port - if _, ok := redirDomains[d]; !ok || - addr.StartPort == uint(app.httpsPort()) { - redirDomains[d] = append(redirDomains[d], addr) - } + app.recordAutoHTTPSRedirectAddress(redirDomains, d, addr) } } } + // if all servers have auto_https disabled and no domains need certs, + // skip the rest of the TLS automation setup to avoid creating + // unnecessary PKI infrastructure and automation policies + allServersDisabled := true + for _, srv := range app.Servers { + if srv.AutoHTTPS == nil || !srv.AutoHTTPS.Disabled { + allServersDisabled = false + break + } + } + + if allServersDisabled && len(uniqueDomainsForCerts) == 0 { + logger.Debug("all servers have automatic HTTPS disabled and no domains need certificates, skipping TLS automation setup") + return nil + } + // we now have a list of all the unique names for which we need certs var internal, tailscale []string uniqueDomainsLoop: @@ -343,7 +363,7 @@ uniqueDomainsLoop: // match on known domain names, unless it's our special case of a // catch-all which is an empty string (common among catch-all sites // that enable on-demand TLS for yet-unknown domain names) - if !(len(domains) == 1 && domains[0] == "") { + if len(domains) != 1 || domains[0] != "" { matcherSet = append(matcherSet, MatchHost(domains)) } @@ -382,15 +402,60 @@ uniqueDomainsLoop: return append(routes, app.makeRedirRoute(uint(app.httpsPort()), MatcherSet{MatchProtocol("http")})) } + // Sort redirect addresses to ensure deterministic process + redirServerAddrsSorted := make([]string, 0, len(redirServers)) + for addr := range redirServers { + redirServerAddrsSorted = append(redirServerAddrsSorted, addr) + } + slices.Sort(redirServerAddrsSorted) + redirServersLoop: - for redirServerAddr, routes := range redirServers { + for _, redirServerAddr := range redirServerAddrsSorted { + routes := redirServers[redirServerAddr] // for each redirect listener, see if there's already a // server configured to listen on that exact address; if so, // insert the redirect route to the end of its route list // after any other routes with host matchers; otherwise, // we'll create a new server for all the listener addresses // that are unused and serve the remaining redirects from it - for _, srv := range app.Servers { + + // Sort redirect routes by host specificity to ensure exact matches + // take precedence over wildcards, preventing ambiguous routing. + slices.SortFunc(routes, func(a, b Route) int { + hostA := getFirstHostFromRoute(a) + hostB := getFirstHostFromRoute(b) + + // Catch-all routes (empty host) have the lowest priority + if hostA == "" && hostB != "" { + return 1 + } + if hostB == "" && hostA != "" { + return -1 + } + + hasWildcardA := strings.Contains(hostA, "*") + hasWildcardB := strings.Contains(hostB, "*") + + // Exact domains take precedence over wildcards + if !hasWildcardA && hasWildcardB { + return -1 + } + if hasWildcardA && !hasWildcardB { + return 1 + } + + // If both are exact or both are wildcards, the longer one is more specific + if len(hostA) != len(hostB) { + return len(hostB) - len(hostA) + } + + // Tie-breaker: alphabetical order to ensure determinism + return strings.Compare(hostA, hostB) + }) + + // Use the sorted srvNames to consistently find the target server + for _, srvName := range srvNames { + srv := app.Servers[srvName] // only look at servers which listen on an address which // we want to add redirects to if !srv.hasListenerAddress(redirServerAddr) { @@ -447,6 +512,35 @@ redirServersLoop: return nil } +// recordAutoHTTPSRedirectAddress stores redirect destinations for one domain +// using a single winning port while keeping all bind addresses on that port. +// +// This is needed to avoid two opposite regressions in auto-HTTPS redirects: +// preserve all listener addresses when a site binds multiple addresses on the +// same HTTPS port, but do not mix in alternate HTTPS ports when the canonical +// app HTTPS port is also available. +func (app *App) recordAutoHTTPSRedirectAddress(redirDomains map[string][]caddy.NetworkAddress, domain string, addr caddy.NetworkAddress) { + existing := redirDomains[domain] + if len(existing) == 0 { + redirDomains[domain] = []caddy.NetworkAddress{addr} + return + } + + existingPort := existing[0].StartPort + if addr.StartPort != existingPort { + if addr.StartPort == uint(app.httpsPort()) && existingPort != uint(app.httpsPort()) { + redirDomains[domain] = []caddy.NetworkAddress{addr} + } + return + } + + if slices.Contains(existing, addr) { + return + } + + redirDomains[domain] = append(existing, addr) +} + func (app *App) makeRedirRoute(redirToPort uint, matcherSet MatcherSet) Route { redirTo := "https://{http.request.host}" @@ -480,6 +574,20 @@ func (app *App) makeRedirRoute(redirToPort uint, matcherSet MatcherSet) Route { } } +func httpsRRALPNs(srv *Server) []string { + alpn := make(map[string]struct{}, 3) + if srv.protocol("h3") { + alpn["h3"] = struct{}{} + } + if srv.protocol("h2") { + alpn["h2"] = struct{}{} + } + if srv.protocol("h1") { + alpn["http/1.1"] = struct{}{} + } + return caddytls.OrderedHTTPSRRALPN(alpn) +} + // createAutomationPolicies ensures that automated certificates for this // app are managed properly. This adds up to two automation policies: // one for the public names, and one for the internal names. If a catch-all @@ -544,6 +652,27 @@ func (app *App) createAutomationPolicies(ctx caddy.Context, internalNames, tails } } + // Ensure automation policies' CertMagic configs are rebuilt when + // ACME issuer templates may have been modified above (for example, + // alternate ports filled in by the HTTP app). If a policy is already + // provisioned, perform a lightweight rebuild of the CertMagic config + // so issuers receive SetConfig with the updated templates; otherwise + // run a normal Provision to initialize the policy. + for i, ap := range app.tlsApp.Automation.Policies { + // If the policy is already provisioned, rebuild only the CertMagic + // config so issuers get SetConfig with updated templates. Otherwise + // provision the policy normally (which may load modules). + if ap.IsProvisioned() { + if err := ap.RebuildCertMagic(app.tlsApp); err != nil { + return fmt.Errorf("rebuilding certmagic config for automation policy %d: %v", i, err) + } + } else { + if err := ap.Provision(app.tlsApp); err != nil { + return fmt.Errorf("provisioning automation policy %d after auto-HTTPS defaults: %v", i, err) + } + } + } + if basePolicy == nil { // no base policy found; we will make one basePolicy = new(caddytls.AutomationPolicy) @@ -757,3 +886,26 @@ func isTailscaleDomain(name string) bool { } type acmeCapable interface{ GetACMEIssuer() *caddytls.ACMEIssuer } + +// getFirstHostFromRoute traverses a route's matchers to find the Host rule. +// Since we are dealing with internally generated redirect routes, the host +// is typically the first string within the MatchHost. +func getFirstHostFromRoute(r Route) string { + for _, matcherSet := range r.MatcherSets { + for _, m := range matcherSet { + // Check if the matcher is of type MatchHost (value or pointer) + switch hm := m.(type) { + case MatchHost: + if len(hm) > 0 { + return hm[0] + } + case *MatchHost: + if len(*hm) > 0 { + return (*hm)[0] + } + } + } + } + // Return an empty string if it's a catch-all route (no specific host) + return "" +} diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/celmatcher.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/celmatcher.go index 3d118ea79..3038c8926 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/celmatcher.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/celmatcher.go @@ -412,10 +412,12 @@ func CELMatcherImpl(macroName, funcName string, matcherDataTypes []*cel.Type, fa return nil, fmt.Errorf("unsupported matcher data type: %s, %s", matcherDataTypes[0], matcherDataTypes[1]) } case 3: + // nolint:gosec // false positive, impossible to be out of bounds; see: https://github.com/securego/gosec/issues/1525 if matcherDataTypes[0] == cel.StringType && matcherDataTypes[1] == cel.StringType && matcherDataTypes[2] == cel.StringType { macro = parser.NewGlobalMacro(macroName, 3, celMatcherStringListMacroExpander(funcName)) matcherDataTypes = []*cel.Type{cel.ListType(cel.StringType)} } else { + // nolint:gosec // false positive, impossible to be out of bounds; see: https://github.com/securego/gosec/issues/1525 return nil, fmt.Errorf("unsupported matcher data type: %s, %s, %s", matcherDataTypes[0], matcherDataTypes[1], matcherDataTypes[2]) } } @@ -665,12 +667,29 @@ func celMatcherJSONMacroExpander(funcName string) parser.MacroExpander { // map literals containing heterogeneous values, in this case string and list // of string. func CELValueToMapStrList(data ref.Val) (map[string][]string, error) { - mapStrType := reflect.TypeOf(map[string]any{}) + // Prefer map[string]any, but newer cel-go versions may return map[any]any + mapStrType := reflect.TypeFor[map[string]any]() mapStrRaw, err := data.ConvertToNative(mapStrType) + var mapStrIface map[string]any if err != nil { - return nil, err + // Try map[any]any and convert keys to strings + mapAnyType := reflect.TypeFor[map[any]any]() + mapAnyRaw, err2 := data.ConvertToNative(mapAnyType) + if err2 != nil { + return nil, err + } + mapAnyIface := mapAnyRaw.(map[any]any) + mapStrIface = make(map[string]any, len(mapAnyIface)) + for k, v := range mapAnyIface { + ks, ok := k.(string) + if !ok { + return nil, fmt.Errorf("unsupported map key type in header match: %T", k) + } + mapStrIface[ks] = v + } + } else { + mapStrIface = mapStrRaw.(map[string]any) } - mapStrIface := mapStrRaw.(map[string]any) mapStrListStr := make(map[string][]string, len(mapStrIface)) for k, v := range mapStrIface { switch val := v.(type) { @@ -685,13 +704,26 @@ func CELValueToMapStrList(data ref.Val) (map[string][]string, error) { for i, elem := range val { strVal, ok := elem.(types.String) if !ok { - return nil, fmt.Errorf("unsupported value type in header match: %T", val) + return nil, fmt.Errorf("unsupported value type in matcher input: %T", val) } convVals[i] = string(strVal) } mapStrListStr[k] = convVals + case []any: + convVals := make([]string, len(val)) + for i, elem := range val { + switch e := elem.(type) { + case string: + convVals[i] = e + case types.String: + convVals[i] = string(e) + default: + return nil, fmt.Errorf("unsupported element type in matcher input list: %T", elem) + } + } + mapStrListStr[k] = convVals default: - return nil, fmt.Errorf("unsupported value type in header match: %T", val) + return nil, fmt.Errorf("unsupported value type in matcher input: %T", val) } } return mapStrListStr, nil diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/errors.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/errors.go index fc8ffbfaa..673368e2e 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/errors.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/errors.go @@ -17,7 +17,7 @@ package caddyhttp import ( "errors" "fmt" - weakrand "math/rand" + weakrand "math/rand/v2" "path" "runtime" "strings" @@ -98,7 +98,7 @@ func randString(n int, sameCase bool) string { b := make([]byte, n) for i := range b { //nolint:gosec - b[i] = dict[weakrand.Int63()%int64(len(dict))] + b[i] = dict[weakrand.IntN(len(dict))] } return string(b) } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/http2listener.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/http2listener.go index 51b356a77..ad5991790 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/http2listener.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/http2listener.go @@ -1,102 +1,131 @@ package caddyhttp import ( - "context" "crypto/tls" - weakrand "math/rand" + "io" "net" - "net/http" - "sync/atomic" - "time" + "go.uber.org/zap" "golang.org/x/net/http2" ) +type connectionStater interface { + ConnectionState() tls.ConnectionState +} + // http2Listener wraps the listener to solve the following problems: -// 1. server h2 natively without using h2c hack when listener handles tls connection but -// don't return *tls.Conn -// 2. graceful shutdown. the shutdown logic is copied from stdlib http.Server, it's an extra maintenance burden but -// whatever, the shutdown logic maybe extracted to be used with h2c graceful shutdown. http2.Server supports graceful shutdown -// sending GO_AWAY frame to connected clients, but doesn't track connection status. It requires explicit call of http2.ConfigureServer +// 1. prevent genuine h2c connections from succeeding if h2c is not enabled +// and the connection doesn't implment connectionStater or the resulting NegotiatedProtocol +// isn't http2. +// This does allow a connection to pass as tls enabled even if it's not, listener wrappers +// can do this. +// 2. After wrapping the connection doesn't implement connectionStater, emit a warning so that listener +// wrapper authors will hopefully implement it. +// 3. check if the connection matches a specific http version. h2/h2c has a distinct preface. type http2Listener struct { - cnt uint64 + useTLS bool + useH1 bool + useH2 bool net.Listener - server *http.Server - h2server *http2.Server -} - -type connectionStateConn interface { - net.Conn - ConnectionState() tls.ConnectionState + logger *zap.Logger } func (h *http2Listener) Accept() (net.Conn, error) { - for { - conn, err := h.Listener.Accept() - if err != nil { - return nil, err - } + conn, err := h.Listener.Accept() + if err != nil { + return nil, err + } - if csc, ok := conn.(connectionStateConn); ok { - // *tls.Conn will return empty string because it's only populated after handshake is complete - if csc.ConnectionState().NegotiatedProtocol == http2.NextProtoTLS { - go h.serveHttp2(csc) - continue - } - } + // *tls.Conn doesn't need to be wrapped because we already removed unwanted alpns + // and handshake won't succeed without mutually supported alpns + if tlsConn, ok := conn.(*tls.Conn); ok { + return tlsConn, nil + } + + _, isConnectionStater := conn.(connectionStater) + // emit a warning + if h.useTLS && !isConnectionStater { + h.logger.Warn("tls is enabled, but listener wrapper returns a connection that doesn't implement connectionStater") + } else if !h.useTLS && isConnectionStater { + h.logger.Warn("tls is disabled, but listener wrapper returns a connection that implements connectionStater") + } + // if both h1 and h2 are enabled, we don't need to check the preface + if h.useH1 && h.useH2 { + if isConnectionStater { + return tlsStateConn{conn}, nil + } return conn, nil } + + // impossible both are false, either useH1 or useH2 must be true, + // or else the listener wouldn't be created + h2Conn := &http2Conn{ + h2Expected: h.useH2, + logger: h.logger, + Conn: conn, + } + if isConnectionStater { + return tlsStateConn{http2StateConn{h2Conn}}, nil + } + return h2Conn, nil } -func (h *http2Listener) serveHttp2(csc connectionStateConn) { - atomic.AddUint64(&h.cnt, 1) - h.runHook(csc, http.StateNew) - defer func() { - csc.Close() - atomic.AddUint64(&h.cnt, ^uint64(0)) - h.runHook(csc, http.StateClosed) - }() - h.h2server.ServeConn(csc, &http2.ServeConnOpts{ - Context: h.server.ConnContext(context.Background(), csc), - BaseConfig: h.server, - Handler: h.server.Handler, - }) +// tlsStateConn wraps a net.Conn that implements connectionStater to hide that method +// we can call netConn to get the original net.Conn and get the tls connection state +// golang 1.25 will call that method, and it breaks h2 with connections other than *tls.Conn +type tlsStateConn struct { + net.Conn } -const shutdownPollIntervalMax = 500 * time.Millisecond +func (conn tlsStateConn) tlsNetConn() net.Conn { + return conn.Conn +} -func (h *http2Listener) Shutdown(ctx context.Context) error { - pollIntervalBase := time.Millisecond - nextPollInterval := func() time.Duration { - // Add 10% jitter. - //nolint:gosec - interval := pollIntervalBase + time.Duration(weakrand.Intn(int(pollIntervalBase/10))) - // Double and clamp for next time. - pollIntervalBase *= 2 - if pollIntervalBase > shutdownPollIntervalMax { - pollIntervalBase = shutdownPollIntervalMax - } - return interval - } +type http2StateConn struct { + *http2Conn +} - timer := time.NewTimer(nextPollInterval()) - defer timer.Stop() - for { - if atomic.LoadUint64(&h.cnt) == 0 { - return nil - } - select { - case <-ctx.Done(): - return ctx.Err() - case <-timer.C: - timer.Reset(nextPollInterval()) - } - } +func (conn http2StateConn) ConnectionState() tls.ConnectionState { + return conn.Conn.(connectionStater).ConnectionState() +} + +type http2Conn struct { + // current index where the preface should match, + // no matching is done if idx is >= len(http2.ClientPreface) + idx int + // whether the connection is expected to be h2/h2c + h2Expected bool + // log if one such connection is detected + logger *zap.Logger + net.Conn } -func (h *http2Listener) runHook(conn net.Conn, state http.ConnState) { - if h.server.ConnState != nil { - h.server.ConnState(conn, state) +func (c *http2Conn) Read(p []byte) (int, error) { + if c.idx >= len(http2.ClientPreface) { + return c.Conn.Read(p) + } + n, err := c.Conn.Read(p) + for i := range n { + // first mismatch + if p[i] != http2.ClientPreface[c.idx] { + // close the connection if h2 is expected + if c.h2Expected { + c.logger.Debug("h1 connection detected, but h1 is not enabled") + _ = c.Conn.Close() + return 0, io.EOF + } + // no need to continue matching anymore + c.idx = len(http2.ClientPreface) + return n, err + } + c.idx++ + // matching complete + if c.idx == len(http2.ClientPreface) && !c.h2Expected { + c.logger.Debug("h2/h2c connection detected, but h2/h2c is not enabled") + _ = c.Conn.Close() + return 0, io.EOF + } } + return n, err } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/ip_matchers.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/ip_matchers.go index 5e0b356e7..9335112e8 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/ip_matchers.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/ip_matchers.go @@ -20,7 +20,6 @@ import ( "net" "net/http" "net/netip" - "reflect" "strings" "github.com/google/cel-go/cel" @@ -109,7 +108,7 @@ func (MatchRemoteIP) CELLibrary(ctx caddy.Context) (cel.Library, error) { []*cel.Type{cel.ListType(cel.StringType)}, // function to convert a constant list of strings to a MatchPath instance. func(data ref.Val) (RequestMatcherWithError, error) { - refStringList := reflect.TypeOf([]string{}) + refStringList := stringSliceType strList, err := data.ConvertToNative(refStringList) if err != nil { return nil, err @@ -222,7 +221,7 @@ func (MatchClientIP) CELLibrary(ctx caddy.Context) (cel.Library, error) { []*cel.Type{cel.ListType(cel.StringType)}, // function to convert a constant list of strings to a MatchPath instance. func(data ref.Val) (RequestMatcherWithError, error) { - refStringList := reflect.TypeOf([]string{}) + refStringList := stringSliceType strList, err := data.ConvertToNative(refStringList) if err != nil { return nil, err diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/logging.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/logging.go index 87298ac3c..b937a6f1e 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/logging.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/logging.go @@ -15,18 +15,28 @@ package caddyhttp import ( + "context" "encoding/json" "errors" + "log/slog" "net" "net/http" "strings" + "sync" "go.uber.org/zap" + "go.uber.org/zap/exp/zapslog" "go.uber.org/zap/zapcore" "github.com/caddyserver/caddy/v2" ) +func init() { + caddy.RegisterSlogHandlerFactory(func(handler slog.Handler, core zapcore.Core, moduleID string) slog.Handler { + return &extraFieldsSlogHandler{defaultHandler: handler, core: core, moduleID: moduleID} + }) +} + // ServerLogConfig describes a server's logging configuration. If // enabled without customization, all requests to this server are // logged to the default logger; logger destinations may be @@ -209,7 +219,7 @@ func errLogValues(err error) (status int, msg string, fields func() []zapcore.Fi zap.String("err_trace", handlerErr.Trace), } } - return + return status, msg, fields } fields = func() []zapcore.Field { return []zapcore.Field{ @@ -218,22 +228,26 @@ func errLogValues(err error) (status int, msg string, fields func() []zapcore.Fi } status = http.StatusInternalServerError msg = err.Error() - return + return status, msg, fields } // ExtraLogFields is a list of extra fields to log with every request. type ExtraLogFields struct { - fields []zapcore.Field + fields []zapcore.Field + handlers sync.Map } // Add adds a field to the list of extra fields to log. func (e *ExtraLogFields) Add(field zap.Field) { + e.handlers.Clear() e.fields = append(e.fields, field) } // Set sets a field in the list of extra fields to log. // If the field already exists, it is replaced. func (e *ExtraLogFields) Set(field zap.Field) { + e.handlers.Clear() + for i := range e.fields { if e.fields[i].Key == field.Key { e.fields[i] = field @@ -243,6 +257,29 @@ func (e *ExtraLogFields) Set(field zap.Field) { e.fields = append(e.fields, field) } +func (e *ExtraLogFields) getSloggerHandler(handler *extraFieldsSlogHandler) (h slog.Handler) { + if existing, ok := e.handlers.Load(handler); ok { + return existing.(slog.Handler) + } + + if handler.moduleID == "" { + h = zapslog.NewHandler(handler.core.With(e.fields)) + } else { + h = zapslog.NewHandler(handler.core.With(e.fields), zapslog.WithName(handler.moduleID)) + } + + if handler.group != "" { + h = h.WithGroup(handler.group) + } + if handler.attrs != nil { + h = h.WithAttrs(handler.attrs) + } + + e.handlers.Store(handler, h) + + return h +} + const ( // Variable name used to indicate that this request // should be omitted from the access logs @@ -254,3 +291,43 @@ const ( // Variable name used to indicate the logger to be used AccessLoggerNameVarKey string = "access_logger_names" ) + +type extraFieldsSlogHandler struct { + defaultHandler slog.Handler + core zapcore.Core + moduleID string + group string + attrs []slog.Attr +} + +func (e *extraFieldsSlogHandler) Enabled(ctx context.Context, level slog.Level) bool { + return e.defaultHandler.Enabled(ctx, level) +} + +func (e *extraFieldsSlogHandler) Handle(ctx context.Context, record slog.Record) error { + if elf, ok := ctx.Value(ExtraLogFieldsCtxKey).(*ExtraLogFields); ok { + return elf.getSloggerHandler(e).Handle(ctx, record) + } + + return e.defaultHandler.Handle(ctx, record) +} + +func (e *extraFieldsSlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + return &extraFieldsSlogHandler{ + e.defaultHandler.WithAttrs(attrs), + e.core, + e.moduleID, + e.group, + append(e.attrs, attrs...), + } +} + +func (e *extraFieldsSlogHandler) WithGroup(name string) slog.Handler { + return &extraFieldsSlogHandler{ + e.defaultHandler.WithGroup(name), + e.core, + e.moduleID, + name, + e.attrs, + } +} diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/marshalers.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/marshalers.go index 9bce377f4..15fa3e8bc 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/marshalers.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/marshalers.go @@ -18,9 +18,10 @@ import ( "crypto/tls" "net" "net/http" - "strings" "go.uber.org/zap/zapcore" + + "github.com/caddyserver/caddy/v2/internal" ) // LoggableHTTPRequest makes an HTTP request loggable with zap.Object(). @@ -47,12 +48,12 @@ func (r LoggableHTTPRequest) MarshalLogObject(enc zapcore.ObjectEncoder) error { enc.AddString("method", r.Method) enc.AddString("host", r.Host) enc.AddString("uri", r.RequestURI) - enc.AddObject("headers", LoggableHTTPHeader{ + enc.AddObject("headers", internal.LoggableHTTPHeader{ Header: r.Header, ShouldLogCredentials: r.ShouldLogCredentials, }) if r.TransferEncoding != nil { - enc.AddArray("transfer_encoding", LoggableStringArray(r.TransferEncoding)) + enc.AddArray("transfer_encoding", internal.LoggableStringArray(r.TransferEncoding)) } if r.TLS != nil { enc.AddObject("tls", LoggableTLSConnState(*r.TLS)) @@ -61,44 +62,10 @@ func (r LoggableHTTPRequest) MarshalLogObject(enc zapcore.ObjectEncoder) error { } // LoggableHTTPHeader makes an HTTP header loggable with zap.Object(). -// Headers with potentially sensitive information (Cookie, Set-Cookie, -// Authorization, and Proxy-Authorization) are logged with empty values. -type LoggableHTTPHeader struct { - http.Header - - ShouldLogCredentials bool -} - -// MarshalLogObject satisfies the zapcore.ObjectMarshaler interface. -func (h LoggableHTTPHeader) MarshalLogObject(enc zapcore.ObjectEncoder) error { - if h.Header == nil { - return nil - } - for key, val := range h.Header { - if !h.ShouldLogCredentials { - switch strings.ToLower(key) { - case "cookie", "set-cookie", "authorization", "proxy-authorization": - val = []string{"REDACTED"} // see #5669. I still think ▒▒▒▒ would be cool. - } - } - enc.AddArray(key, LoggableStringArray(val)) - } - return nil -} +type LoggableHTTPHeader = internal.LoggableHTTPHeader // LoggableStringArray makes a slice of strings marshalable for logging. -type LoggableStringArray []string - -// MarshalLogArray satisfies the zapcore.ArrayMarshaler interface. -func (sa LoggableStringArray) MarshalLogArray(enc zapcore.ArrayEncoder) error { - if sa == nil { - return nil - } - for _, s := range sa { - enc.AppendString(s) - } - return nil -} +type LoggableStringArray = internal.LoggableStringArray // LoggableTLSConnState makes a TLS connection state loggable with zap.Object(). type LoggableTLSConnState tls.ConnectionState @@ -110,6 +77,7 @@ func (t LoggableTLSConnState) MarshalLogObject(enc zapcore.ObjectEncoder) error enc.AddUint16("cipher_suite", t.CipherSuite) enc.AddString("proto", t.NegotiatedProtocol) enc.AddString("server_name", t.ServerName) + enc.AddBool("ech", t.ECHAccepted) if len(t.PeerCertificates) > 0 { enc.AddString("client_common_name", t.PeerCertificates[0].Subject.CommonName) enc.AddString("client_serial", t.PeerCertificates[0].SerialNumber.String()) @@ -120,7 +88,5 @@ func (t LoggableTLSConnState) MarshalLogObject(enc zapcore.ObjectEncoder) error // Interface guards var ( _ zapcore.ObjectMarshaler = (*LoggableHTTPRequest)(nil) - _ zapcore.ObjectMarshaler = (*LoggableHTTPHeader)(nil) - _ zapcore.ArrayMarshaler = (*LoggableStringArray)(nil) _ zapcore.ObjectMarshaler = (*LoggableTLSConnState)(nil) ) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/matchers.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/matchers.go index 01bd7b8b4..f179b9c11 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/matchers.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/matchers.go @@ -23,7 +23,6 @@ import ( "net/textproto" "net/url" "path" - "reflect" "regexp" "runtime" "slices" @@ -263,13 +262,17 @@ func (m MatchHost) Provision(_ caddy.Context) error { if err != nil { return fmt.Errorf("converting hostname '%s' to ASCII: %v", host, err) } - if asciiHost != host { - m[i] = asciiHost - } normalizedHost := strings.ToLower(asciiHost) if firstI, ok := seen[normalizedHost]; ok { return fmt.Errorf("host at index %d is repeated at index %d: %s", firstI, i, host) } + // Normalize exact hosts for standardized comparison in large-list fastpath later on. + // Keep wildcards/placeholders untouched. + if m.fuzzy(asciiHost) { + m[i] = asciiHost + } else { + m[i] = normalizedHost + } seen[normalizedHost] = i } @@ -313,14 +316,15 @@ func (m MatchHost) MatchWithError(r *http.Request) (bool, error) { } if m.large() { + reqHostLower := strings.ToLower(reqHost) // fast path: locate exact match using binary search (about 100-1000x faster for large lists) pos := sort.Search(len(m), func(i int) bool { if m.fuzzy(m[i]) { return false } - return m[i] >= reqHost + return m[i] >= reqHostLower }) - if pos < len(m) && m[pos] == reqHost { + if pos < len(m) && m[pos] == reqHostLower { return true, nil } } @@ -373,7 +377,7 @@ func (MatchHost) CELLibrary(ctx caddy.Context) (cel.Library, error) { "host_match_request_list", []*cel.Type{cel.ListType(cel.StringType)}, func(data ref.Val) (RequestMatcherWithError, error) { - refStringList := reflect.TypeOf([]string{}) + refStringList := stringSliceType strList, err := data.ConvertToNative(refStringList) if err != nil { return nil, err @@ -534,6 +538,7 @@ func (m MatchPath) MatchWithError(r *http.Request) (bool, error) { } func (MatchPath) matchPatternWithEscapeSequence(escapedPath, matchPath string) bool { + escapedPath = strings.ToLower(escapedPath) // We would just compare the pattern against r.URL.Path, // but the pattern contains %, indicating that we should // compare at least some part of the path in raw/escaped @@ -552,7 +557,6 @@ func (MatchPath) matchPatternWithEscapeSequence(escapedPath, matchPath string) b if iPattern >= len(matchPath) || iPath >= len(escapedPath) { break } - // get the next character from the request path pathCh := string(escapedPath[iPath]) @@ -634,8 +638,8 @@ func (MatchPath) matchPatternWithEscapeSequence(escapedPath, matchPath string) b // we can now treat rawpath globs (%*) as regular globs (*) matchPath = strings.ReplaceAll(matchPath, "%*", "*") - // ignore error here because we can't handle it anyway= - matches, _ := path.Match(matchPath, sb.String()) + // ignore error here because we can't handle it anyway + matches, _ := path.Match(matchPath, strings.ToLower(sb.String())) return matches } @@ -655,7 +659,7 @@ func (MatchPath) CELLibrary(ctx caddy.Context) (cel.Library, error) { []*cel.Type{cel.ListType(cel.StringType)}, // function to convert a constant list of strings to a MatchPath instance. func(data ref.Val) (RequestMatcherWithError, error) { - refStringList := reflect.TypeOf([]string{}) + refStringList := stringSliceType strList, err := data.ConvertToNative(refStringList) if err != nil { return nil, err @@ -734,7 +738,7 @@ func (MatchPathRE) CELLibrary(ctx caddy.Context) (cel.Library, error) { "path_regexp_request_string_string", []*cel.Type{cel.StringType, cel.StringType}, func(data ref.Val) (RequestMatcherWithError, error) { - refStringList := reflect.TypeOf([]string{}) + refStringList := stringSliceType params, err := data.ConvertToNative(refStringList) if err != nil { return nil, err @@ -803,7 +807,7 @@ func (MatchMethod) CELLibrary(_ caddy.Context) (cel.Library, error) { "method_request_list", []*cel.Type{cel.ListType(cel.StringType)}, func(data ref.Val) (RequestMatcherWithError, error) { - refStringList := reflect.TypeOf([]string{}) + refStringList := stringSliceType strList, err := data.ConvertToNative(refStringList) if err != nil { return nil, err @@ -1174,7 +1178,7 @@ func (MatchHeaderRE) CELLibrary(ctx caddy.Context) (cel.Library, error) { "header_regexp_request_string_string", []*cel.Type{cel.StringType, cel.StringType}, func(data ref.Val) (RequestMatcherWithError, error) { - refStringList := reflect.TypeOf([]string{}) + refStringList := stringSliceType params, err := data.ConvertToNative(refStringList) if err != nil { return nil, err @@ -1197,7 +1201,7 @@ func (MatchHeaderRE) CELLibrary(ctx caddy.Context) (cel.Library, error) { "header_regexp_request_string_string_string", []*cel.Type{cel.StringType, cel.StringType, cel.StringType}, func(data ref.Val) (RequestMatcherWithError, error) { - refStringList := reflect.TypeOf([]string{}) + refStringList := stringSliceType params, err := data.ConvertToNative(refStringList) if err != nil { return nil, err @@ -1547,7 +1551,7 @@ func (mre *MatchRegexp) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return nil } -// ParseCaddyfileNestedMatcher parses the Caddyfile tokens for a nested +// ParseCaddyfileNestedMatcherSet parses the Caddyfile tokens for a nested // matcher set, and returns its raw module map value. func ParseCaddyfileNestedMatcherSet(d *caddyfile.Dispenser) (caddy.ModuleMap, error) { matcherMap := make(map[string]any) @@ -1558,6 +1562,14 @@ func ParseCaddyfileNestedMatcherSet(d *caddyfile.Dispenser) (caddy.ModuleMap, er // instances of the matcher in this set tokensByMatcherName := make(map[string][]caddyfile.Token) for nesting := d.Nesting(); d.NextArg() || d.NextBlock(nesting); { + // if the token is quoted (backtick), treat it as a shorthand + // for an expression matcher, same as @named matcher parsing + if d.Token().Quoted() { + expressionToken := d.Token().Clone() + expressionToken.Text = "expression" + tokensByMatcherName["expression"] = append(tokensByMatcherName["expression"], expressionToken, d.Token()) + continue + } matcherName := d.Val() tokensByMatcherName[matcherName] = append(tokensByMatcherName[matcherName], d.NextSegment()...) } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/metrics.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/metrics.go index 9bb97e0b4..8d20e01b6 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/metrics.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/metrics.go @@ -3,6 +3,7 @@ package caddyhttp import ( "context" "errors" + "fmt" "net/http" "strings" "sync" @@ -10,21 +11,82 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + otelprom "go.opentelemetry.io/contrib/bridges/prometheus" + "go.opentelemetry.io/contrib/exporters/autoexport" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.26.0" "github.com/caddyserver/caddy/v2" - "github.com/caddyserver/caddy/v2/internal/metrics" + caddymetrics "github.com/caddyserver/caddy/v2/internal/metrics" ) // Metrics configures metrics observations. // EXPERIMENTAL and subject to change or removal. +// +// Example configuration: +// +// { +// "apps": { +// "http": { +// "metrics": { +// "per_host": true, +// "observe_catchall_hosts": false +// }, +// "servers": { +// "srv0": { +// "routes": [{ +// "match": [{"host": ["example.com", "www.example.com"]}], +// "handle": [{"handler": "static_response", "body": "Hello"}] +// }] +// } +// } +// } +// } +// } +// +// In this configuration: +// - Requests to example.com and www.example.com get individual host labels +// - All other hosts (e.g., attacker.com) are aggregated under "_other" label +// - This prevents unlimited cardinality from arbitrary Host headers type Metrics struct { // Enable per-host metrics. Enabling this option may // incur high-memory consumption, depending on the number of hosts // managed by Caddy. + // + // CARDINALITY PROTECTION: To prevent unbounded cardinality attacks, + // only explicitly configured hosts (via host matchers) are allowed + // by default. Other hosts are aggregated under the "_other" label. + // See AllowCatchAllHosts to change this behavior. PerHost bool `json:"per_host,omitempty"` - init sync.Once - httpMetrics *httpMetrics `json:"-"` + // Allow metrics for catch-all hosts (hosts without explicit configuration). + // When false (default), only hosts explicitly configured via host matchers + // will get individual metrics labels. All other hosts will be aggregated + // under the "_other" label to prevent cardinality explosion. + // + // This is automatically enabled for HTTPS servers (since certificates provide + // some protection against unbounded cardinality), but disabled for HTTP servers + // by default to prevent cardinality attacks from arbitrary Host headers. + // + // Set to true to allow all hosts to get individual metrics (NOT RECOMMENDED + // for production environments exposed to the internet). + ObserveCatchallHosts bool `json:"observe_catchall_hosts,omitempty"` + + // Enable pushing metrics via OTLP in addition to the existing Prometheus + // scrape endpoints. When set, a PeriodicReader is attached to the shared + // Prometheus registry (via a Prometheus -> OpenTelemetry bridge), and the + // exporter is autoconfigured from the standard OTEL_* environment + // variables (OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_PROTOCOL, + // OTEL_METRICS_EXPORTER, ...). Set OTEL_METRICS_EXPORTER=none or simply + // keep this field false to disable OTLP export. + OTLP bool `json:"otlp,omitempty"` + + init sync.Once + httpMetrics *httpMetrics + allowedHosts map[string]struct{} + hasHTTPSServer bool + meterProvider *sdkmetric.MeterProvider } type httpMetrics struct { @@ -101,6 +163,127 @@ func initHTTPMetrics(ctx caddy.Context, metrics *Metrics) { }, httpLabels) } +// provisionOTLP wires a MeterProvider that periodically reads the process-wide +// Prometheus registry and pushes the result via OTLP. The exporter and reader +// are autoconfigured from the standard OTEL_* environment variables, matching +// the ergonomics of the existing `tracing` directive. It is a no-op when +// m.OTLP is false, and honors OTEL_METRICS_EXPORTER=none (autoexport +// short-circuits to a no-op reader in that case). +func (m *Metrics) provisionOTLP(ctx caddy.Context) error { + if !m.OTLP { + return nil + } + + // Register a Prometheus -> OpenTelemetry bridge against the process-wide + // Prometheus registry as the *default* source the NewMetricReader below + // will read from. + // + // NB: despite the "With*" naming, autoexport.WithFallbackMetricProducer is + // a package-level setter (it returns nothing) — it mutates autoexport's + // internal producer registry and takes effect on the very next call to + // NewMetricReader. It is NOT a MetricOption and must not be passed as one. + // Users can still override the source by setting OTEL_METRICS_PRODUCERS. + reg := ctx.GetMetricsRegistry() + autoexport.WithFallbackMetricProducer(func(context.Context) (sdkmetric.Producer, error) { + return otelprom.NewMetricProducer(otelprom.WithGatherer(reg)), nil + }) + + reader, err := autoexport.NewMetricReader(ctx) + if err != nil { + return fmt.Errorf("creating OTLP metric reader: %w", err) + } + + version, _ := caddy.Version() + res, err := resource.Merge(resource.Default(), resource.NewSchemaless( + semconv.WebEngineName(ServerHeader), + semconv.WebEngineVersion(version), + )) + if err != nil { + return fmt.Errorf("building OTLP metrics resource: %w", err) + } + + m.meterProvider = sdkmetric.NewMeterProvider( + sdkmetric.WithResource(res), + sdkmetric.WithReader(reader), + ) + + return nil +} + +// shutdown flushes and tears down the OTLP MeterProvider if one was provisioned. +// Both ForceFlush and Shutdown are always attempted so that a flush failure +// does not prevent the reader goroutines from being stopped; errors from both +// are returned joined. +func (m *Metrics) shutdown(ctx context.Context) error { + if m == nil || m.meterProvider == nil { + return nil + } + + // ForceFlush gives the final collection a chance to reach the collector + // before the reader goroutine is stopped by Shutdown. + return errors.Join( + m.meterProvider.ForceFlush(ctx), + m.meterProvider.Shutdown(ctx), + ) +} + +// scanConfigForHosts scans the HTTP app configuration to build a set of allowed hosts +// for metrics collection, similar to how auto-HTTPS scans for domain names. +func (m *Metrics) scanConfigForHosts(app *App) { + if !m.PerHost { + return + } + + m.allowedHosts = make(map[string]struct{}) + m.hasHTTPSServer = false + + for _, srv := range app.Servers { + // Check if this server has TLS enabled + serverHasTLS := len(srv.TLSConnPolicies) > 0 + if serverHasTLS { + m.hasHTTPSServer = true + } + + // Collect hosts from route matchers + for _, route := range srv.Routes { + for _, matcherSet := range route.MatcherSets { + for _, matcher := range matcherSet { + if hm, ok := matcher.(*MatchHost); ok { + for _, host := range *hm { + // Only allow non-fuzzy hosts to prevent unbounded cardinality + if !hm.fuzzy(host) { + m.allowedHosts[strings.ToLower(host)] = struct{}{} + } + } + } + } + } + } + } +} + +// shouldAllowHostMetrics determines if metrics should be collected for the given host. +// This implements the cardinality protection by only allowing metrics for: +// 1. Explicitly configured hosts +// 2. Catch-all requests on HTTPS servers (if AllowCatchAllHosts is true or auto-enabled) +// 3. Catch-all requests on HTTP servers only if explicitly allowed +func (m *Metrics) shouldAllowHostMetrics(host string, isHTTPS bool) bool { + if !m.PerHost { + return true // host won't be used in labels anyway + } + + normalizedHost := strings.ToLower(host) + + // Always allow explicitly configured hosts + if _, exists := m.allowedHosts[normalizedHost]; exists { + return true + } + + // For catch-all requests (not in allowed hosts) + allowCatchAll := m.ObserveCatchallHosts || (isHTTPS && m.hasHTTPSServer) + return allowCatchAll +} + // serverNameFromContext extracts the current server name from the context. // Returns "UNKNOWN" if none is available (should probably never happen). func serverNameFromContext(ctx context.Context) string { @@ -111,31 +294,44 @@ func serverNameFromContext(ctx context.Context) string { return srv.name } -type metricsInstrumentedHandler struct { +// metricsInstrumentedRoute wraps a compiled route Handler with metrics +// instrumentation. It wraps the entire compiled route chain once, +// collecting metrics only once per route match. +type metricsInstrumentedRoute struct { handler string - mh MiddlewareHandler + next Handler metrics *Metrics } -func newMetricsInstrumentedHandler(ctx caddy.Context, handler string, mh MiddlewareHandler, metrics *Metrics) *metricsInstrumentedHandler { - metrics.init.Do(func() { - initHTTPMetrics(ctx, metrics) +func newMetricsInstrumentedRoute(ctx caddy.Context, handler string, next Handler, m *Metrics) *metricsInstrumentedRoute { + m.init.Do(func() { + initHTTPMetrics(ctx, m) }) - return &metricsInstrumentedHandler{handler, mh, metrics} + return &metricsInstrumentedRoute{handler: handler, next: next, metrics: m} } -func (h *metricsInstrumentedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request, next Handler) error { +func (h *metricsInstrumentedRoute) ServeHTTP(w http.ResponseWriter, r *http.Request) error { server := serverNameFromContext(r.Context()) labels := prometheus.Labels{"server": server, "handler": h.handler} - method := metrics.SanitizeMethod(r.Method) + method := caddymetrics.SanitizeMethod(r.Method) // the "code" value is set later, but initialized here to eliminate the possibility // of a panic statusLabels := prometheus.Labels{"server": server, "handler": h.handler, "method": method, "code": ""} + // Determine if this is an HTTPS request + isHTTPS := r.TLS != nil + if h.metrics.PerHost { - labels["host"] = strings.ToLower(r.Host) - statusLabels["host"] = strings.ToLower(r.Host) + // Apply cardinality protection for host metrics + if h.metrics.shouldAllowHostMetrics(r.Host, isHTTPS) { + labels["host"] = strings.ToLower(r.Host) + statusLabels["host"] = strings.ToLower(r.Host) + } else { + // Use a catch-all label for unallowed hosts to prevent cardinality explosion + labels["host"] = "_other" + statusLabels["host"] = "_other" + } } inFlight := h.metrics.httpMetrics.requestInFlight.With(labels) @@ -148,13 +344,13 @@ func (h *metricsInstrumentedHandler) ServeHTTP(w http.ResponseWriter, r *http.Re // being called when the headers are written. // Effectively the same behaviour as promhttp.InstrumentHandlerTimeToWriteHeader. writeHeaderRecorder := ShouldBufferFunc(func(status int, header http.Header) bool { - statusLabels["code"] = metrics.SanitizeCode(status) + statusLabels["code"] = caddymetrics.SanitizeCode(status) ttfb := time.Since(start).Seconds() h.metrics.httpMetrics.responseDuration.With(statusLabels).Observe(ttfb) return false }) wrec := NewResponseRecorder(w, nil, writeHeaderRecorder) - err := h.mh.ServeHTTP(wrec, r, next) + err := h.next.ServeHTTP(wrec, r) dur := time.Since(start).Seconds() h.metrics.httpMetrics.requestCount.With(labels).Inc() @@ -164,7 +360,7 @@ func (h *metricsInstrumentedHandler) ServeHTTP(w http.ResponseWriter, r *http.Re if statusLabels["code"] == "" { // we still sanitize it, even though it's likely to be 0. A 200 is // returned on fallthrough so we want to reflect that. - statusLabels["code"] = metrics.SanitizeCode(status) + statusLabels["code"] = caddymetrics.SanitizeCode(status) } h.metrics.httpMetrics.requestDuration.With(statusLabels).Observe(dur) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/replacer.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/replacer.go index 776aa6294..623a6ef4b 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/replacer.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/replacer.go @@ -172,8 +172,12 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo // current URI, including any internal rewrites case "http.request.uri": return req.URL.RequestURI(), true + case "http.request.uri_escaped": + return url.QueryEscape(req.URL.RequestURI()), true case "http.request.uri.path": return req.URL.Path, true + case "http.request.uri.path_escaped": + return url.QueryEscape(req.URL.Path), true case "http.request.uri.path.file": _, file := path.Split(req.URL.Path) return file, true @@ -186,6 +190,8 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo return path.Ext(req.URL.Path), true case "http.request.uri.query": return req.URL.RawQuery, true + case "http.request.uri.query_escaped": + return url.QueryEscape(req.URL.RawQuery), true case "http.request.uri.prefixed_query": if req.URL.RawQuery == "" { return "", true @@ -223,6 +229,21 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo req.Body = io.NopCloser(buf) // replace real body with buffered data return buf.String(), true + case "http.request.body_base64": + if req.Body == nil { + return "", true + } + // normally net/http will close the body for us, but since we + // are replacing it with a fake one, we have to ensure we close + // the real body ourselves when we're done + defer req.Body.Close() + // read the request body into a buffer (can't pool because we + // don't know its lifetime and would have to make a copy anyway) + buf := new(bytes.Buffer) + _, _ = io.Copy(buf, req.Body) // can't handle error, so just ignore it + req.Body = io.NopCloser(buf) // replace real body with buffered data + return base64.StdEncoding.EncodeToString(buf.Bytes()), true + // original request, before any internal changes case "http.request.orig_method": or, _ := req.Context().Value(OriginalRequestCtxKey).(http.Request) @@ -283,7 +304,7 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo return prefix.String(), true } - // hostname labels + // hostname labels (case insensitive, so normalize to lowercase) if strings.HasPrefix(key, reqHostLabelsReplPrefix) { idxStr := key[len(reqHostLabelsReplPrefix):] idx, err := strconv.Atoi(idxStr) @@ -298,7 +319,7 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo if idx >= len(hostLabels) { return "", true } - return hostLabels[len(hostLabels)-idx-1], true + return strings.ToLower(hostLabels[len(hostLabels)-idx-1]), true } // path parts @@ -363,20 +384,17 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo } } - switch { - case key == "http.shutting_down": + switch key { + case "http.shutting_down": server := req.Context().Value(ServerCtxKey).(*Server) - server.shutdownAtMu.RLock() - defer server.shutdownAtMu.RUnlock() - return !server.shutdownAt.IsZero(), true - case key == "http.time_until_shutdown": + return server.shutdownAt.Load() != nil, true + case "http.time_until_shutdown": server := req.Context().Value(ServerCtxKey).(*Server) - server.shutdownAtMu.RLock() - defer server.shutdownAtMu.RUnlock() - if server.shutdownAt.IsZero() { + t := server.shutdownAt.Load() + if t == nil { return nil, true } - return time.Until(server.shutdownAt), true + return time.Until(*t), true } return nil, false @@ -399,7 +417,16 @@ func getReqTLSReplacement(req *http.Request, key string) (any, bool) { if strings.HasPrefix(field, "client.") { cert := getTLSPeerCert(req.TLS) if cert == nil { - return nil, false + // Instead of returning (nil, false) here, we set it to a dummy + // value to fix #7530. This way, even if there is no client cert, + // evaluating placeholders with ReplaceKnown() will still remove + // the placeholder, which would be expected. It is not expected + // for the placeholder to sometimes get removed based on whether + // the client presented a cert. We also do not return true here + // because we probably should remain accurate about whether a + // placeholder is, in fact, known or not. + // (This allocation may be slightly inefficient.) + cert = new(x509.Certificate) } // subject alternate names (SANs) @@ -505,6 +532,8 @@ func getReqTLSReplacement(req *http.Request, key string) (any, bool) { return true, true case "server_name": return req.TLS.ServerName, true + case "ech": + return req.TLS.ECHAccepted, true } return nil, false } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/routes.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/routes.go index ccb5f2515..7cc6dd79d 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/routes.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/routes.go @@ -18,6 +18,8 @@ import ( "encoding/json" "fmt" "net/http" + "slices" + "strings" "github.com/caddyserver/caddy/v2" ) @@ -96,7 +98,10 @@ type Route struct { MatcherSets MatcherSets `json:"-"` Handlers []MiddlewareHandler `json:"-"` - middleware []Middleware + middleware []Middleware + metrics *Metrics + metricsCtx caddy.Context + handlerName string } // Empty returns true if the route has all zero/default values. @@ -110,14 +115,16 @@ func (r Route) Empty() bool { } func (r Route) String() string { - handlersRaw := "[" + var handlersRaw strings.Builder + handlersRaw.WriteByte('[') for _, hr := range r.HandlersRaw { - handlersRaw += " " + string(hr) + handlersRaw.WriteByte(' ') + handlersRaw.WriteString(string(hr)) } - handlersRaw += "]" + handlersRaw.WriteByte(']') return fmt.Sprintf(`{Group:"%s" MatcherSetsRaw:%s HandlersRaw:%s Terminal:%t}`, - r.Group, r.MatcherSetsRaw, handlersRaw, r.Terminal) + r.Group, r.MatcherSetsRaw, handlersRaw.String(), r.Terminal) } // Provision sets up both the matchers and handlers in the route. @@ -159,12 +166,20 @@ func (r *Route) ProvisionHandlers(ctx caddy.Context, metrics *Metrics) error { r.Handlers = append(r.Handlers, handler.(MiddlewareHandler)) } + // Store metrics info for route-level instrumentation (applied once + // per route in wrapRoute, instead of per-handler which was redundant). + r.metrics = metrics + r.metricsCtx = ctx + if len(r.Handlers) > 0 { + r.handlerName = caddy.GetModuleName(r.Handlers[0]) + } + // Make ProvisionHandlers idempotent by clearing the middleware field r.middleware = []Middleware{} // pre-compile the middleware handler chain for _, midhandler := range r.Handlers { - r.middleware = append(r.middleware, wrapMiddleware(ctx, midhandler, metrics)) + r.middleware = append(r.middleware, wrapMiddleware(ctx, midhandler)) } return nil } @@ -227,8 +242,8 @@ func (routes RouteList) Compile(next Handler) Handler { mid = append(mid, wrapRoute(route)) } stack := next - for i := len(mid) - 1; i >= 0; i-- { - stack = mid[i](stack) + for _, middleware := range slices.Backward(mid) { + stack = middleware(stack) } return stack } @@ -291,8 +306,18 @@ func wrapRoute(route Route) Middleware { } // compile this route's handler stack - for i := len(route.middleware) - 1; i >= 0; i-- { - nextCopy = route.middleware[i](nextCopy) + for _, middleware := range slices.Backward(route.middleware) { + nextCopy = middleware(nextCopy) + } + + // Apply metrics instrumentation once for the entire route, + // rather than wrapping each individual handler. This avoids + // redundant metrics collection that caused significant CPU + // overhead (see issue #4644). + if route.metrics != nil { + nextCopy = newMetricsInstrumentedRoute( + route.metricsCtx, route.handlerName, nextCopy, route.metrics, + ) } return nextCopy.ServeHTTP(rw, req) @@ -302,33 +327,15 @@ func wrapRoute(route Route) Middleware { // wrapMiddleware wraps mh such that it can be correctly // appended to a list of middleware in preparation for -// compiling into a handler chain. We can't do this inline -// inside a loop, because it relies on a reference to mh -// not changing until the execution of its handler (which -// is deferred by multiple func closures). In other words, -// we need to pull this particular MiddlewareHandler -// pointer into its own stack frame to preserve it so it -// won't be overwritten in future loop iterations. -func wrapMiddleware(ctx caddy.Context, mh MiddlewareHandler, metrics *Metrics) Middleware { - handlerToUse := mh - if metrics != nil { - // wrap the middleware with metrics instrumentation - handlerToUse = newMetricsInstrumentedHandler(ctx, caddy.GetModuleName(mh), mh, metrics) - } - +// compiling into a handler chain. +func wrapMiddleware(ctx caddy.Context, mh MiddlewareHandler) Middleware { return func(next Handler) Handler { - // copy the next handler (it's an interface, so it's - // just a very lightweight copy of a pointer); this - // is a safeguard against the handler changing the - // value, which could affect future requests (yikes) - nextCopy := next - return HandlerFunc(func(w http.ResponseWriter, r *http.Request) error { // EXPERIMENTAL: Trace each module that gets invoked if server, ok := r.Context().Value(ServerCtxKey).(*Server); ok && server != nil { - server.logTrace(handlerToUse) + server.logTrace(mh) } - return handlerToUse.ServeHTTP(w, r, nextCopy) + return mh.ServeHTTP(w, r, next) }) } } @@ -452,13 +459,15 @@ func (ms *MatcherSets) FromInterface(matcherSets any) error { // TODO: Is this used? func (ms MatcherSets) String() string { - result := "[" + var result strings.Builder + result.WriteByte('[') for _, matcherSet := range ms { for _, matcher := range matcherSet { - result += fmt.Sprintf(" %#v", matcher) + fmt.Fprintf(&result, " %#v", matcher) } } - return result + " ]" + result.WriteByte(']') + return result.String() } var routeGroupCtxKey = caddy.CtxKey("route_group") diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/server.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/server.go index a2b29d658..66f93989b 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/server.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/server.go @@ -18,6 +18,7 @@ import ( "context" "crypto/tls" "encoding/json" + "errors" "fmt" "io" "net" @@ -27,13 +28,13 @@ import ( "runtime" "slices" "strings" - "sync" + "sync/atomic" "time" "github.com/caddyserver/certmagic" "github.com/quic-go/quic-go" "github.com/quic-go/quic-go/http3" - "github.com/quic-go/quic-go/qlog" + h3qlog "github.com/quic-go/quic-go/http3/qlog" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -55,6 +56,10 @@ type Server struct { // of the base listener. They are applied in the given order. ListenerWrappersRaw []json.RawMessage `json:"listener_wrappers,omitempty" caddy:"namespace=caddy.listeners inline_key=wrapper"` + // A list of packet conn wrapper modules, which can modify the behavior + // of the base packet conn. They are applied in the given order. + PacketConnWrappersRaw []json.RawMessage `json:"packet_conn_wrappers,omitempty" caddy:"namespace=caddy.packetconns inline_key=wrapper"` + // How long to allow a read from a client's upload. Setting this // to a short, non-zero value can mitigate slowloris attacks, but // may also affect legitimately slow clients. @@ -76,9 +81,25 @@ type Server struct { // KeepAliveInterval is the interval at which TCP keepalive packets // are sent to keep the connection alive at the TCP layer when no other - // data is being transmitted. The default is 15s. + // data is being transmitted. + // If zero, the default is 15s. + // If negative, keepalive packets are not sent and other keepalive parameters + // are ignored. KeepAliveInterval caddy.Duration `json:"keepalive_interval,omitempty"` + // KeepAliveIdle is the time that the connection must be idle before + // the first TCP keep-alive probe is sent when no other data is being + // transmitted. + // If zero, the default is 15s. + // If negative, underlying socket value is unchanged. + KeepAliveIdle caddy.Duration `json:"keepalive_idle,omitempty"` + + // KeepAliveCount is the maximum number of TCP keep-alive probes that + // should be sent before dropping a connection. + // If zero, the default is 9. + // If negative, underlying socket value is unchanged. + KeepAliveCount int `json:"keepalive_count,omitempty"` + // MaxHeaderBytes is the maximum size to parse from a client's // HTTP request headers. MaxHeaderBytes int `json:"max_header_bytes,omitempty"` @@ -186,6 +207,13 @@ type Server struct { // This option is disabled by default. TrustedProxiesStrict int `json:"trusted_proxies_strict,omitempty"` + // If greater than zero, enables trusting socket connections + // (e.g. Unix domain sockets) as coming from a trusted + // proxy. + // + // This option is disabled by default. + TrustedProxiesUnix bool `json:"trusted_proxies_unix,omitempty"` + // Enables access logging and configures how access logs are handled // in this server. To minimally enable access logs, simply set this // to a non-null, empty struct. @@ -225,6 +253,16 @@ type Server struct { // A nil value or element indicates that Protocols will be used instead. ListenProtocols [][]string `json:"listen_protocols,omitempty"` + // If set, overrides whether QUIC listeners allow 0-RTT (early data). + // If nil, the default behavior is used (currently allowed). + // + // One reason to disable 0-RTT is if a remote IP matcher is used, + // which introduces a dependency on the remote address being verified + // if routing happens before the TLS handshake completes. An HTTP 425 + // response is written in that case, but some clients misbehave and + // don't perform a retry, so disabling 0-RTT can smooth it out. + Allow0RTT *bool `json:"allow_0rtt,omitempty"` + // If set, metrics observations will be enabled. // This setting is EXPERIMENTAL and subject to change. // DEPRECATED: Use the app-level `metrics` field. @@ -235,7 +273,9 @@ type Server struct { primaryHandlerChain Handler errorHandlerChain Handler listenerWrappers []caddy.ListenerWrapper + packetConnWrappers []caddy.PacketConnWrapper listeners []net.Listener + quicListeners []http3.QUICListener // http3 now leave the quic.Listener management to us tlsApp *caddytls.TLS events *caddyevents.App @@ -245,15 +285,13 @@ type Server struct { traceLogger *zap.Logger ctx caddy.Context - server *http.Server - h3server *http3.Server - h2listeners []*http2Listener - addresses []caddy.NetworkAddress + server *http.Server + h3server *http3.Server + addresses []caddy.NetworkAddress trustedProxies IPRangeSource - shutdownAt time.Time - shutdownAtMu *sync.RWMutex + shutdownAt atomic.Pointer[time.Time] // registered callback functions connStateFuncs []func(net.Conn, http.ConnState) @@ -262,69 +300,55 @@ type Server struct { onStopFuncs []func(context.Context) error // TODO: Experimental (Nov. 2023) } +var defaultProtocols = []string{"h1", "h2", "h3"} + +var ( + ServerHeader = "Caddy" + serverHeader = []string{ServerHeader} +) + // ServeHTTP is the entry point for all HTTP requests. func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { + start := time.Now() + // If there are listener wrappers that process tls connections but don't return a *tls.Conn, this field will be nil. - // TODO: Can be removed if https://github.com/golang/go/pull/56110 is ever merged. if r.TLS == nil { - // not all requests have a conn (like virtual requests) - see #5698 - if conn, ok := r.Context().Value(ConnCtxKey).(net.Conn); ok { - if csc, ok := conn.(connectionStateConn); ok { - r.TLS = new(tls.ConnectionState) - *r.TLS = csc.ConnectionState() - } + if tlsConnStateFunc, ok := r.Context().Value(tlsConnectionStateFuncCtxKey).(func() *tls.ConnectionState); ok { + r.TLS = tlsConnStateFunc() } } - w.Header().Set("Server", "Caddy") - - // advertise HTTP/3, if enabled - if s.h3server != nil { - if r.ProtoMajor < 3 { - err := s.h3server.SetQUICHeaders(w.Header()) - if err != nil { - if c := s.logger.Check(zapcore.ErrorLevel, "setting HTTP/3 Alt-Svc header"); c != nil { - c.Write(zap.Error(err)) - } + // enable full-duplex for HTTP/1, ensuring the entire + // request body gets consumed before writing the response + if s.EnableFullDuplex && r.ProtoMajor == 1 { + if err := http.NewResponseController(w).EnableFullDuplex(); err != nil { //nolint:bodyclose + if c := s.logger.Check(zapcore.WarnLevel, "failed to enable full duplex"); c != nil { + c.Write(zap.Error(err)) } } } - // reject very long methods; probably a mistake or an attack - if len(r.Method) > 32 { - if s.shouldLogRequest(r) { - if c := s.accessLogger.Check(zapcore.DebugLevel, "rejecting request with long method"); c != nil { - c.Write( - zap.String("method_trunc", r.Method[:32]), - zap.String("remote_addr", r.RemoteAddr), - ) + // set the Server header + h := w.Header() + h["Server"] = serverHeader + + // advertise HTTP/3, if enabled + if s.h3server != nil && r.ProtoMajor < 3 { + if err := s.h3server.SetQUICHeaders(h); err != nil { + if c := s.logger.Check(zapcore.ErrorLevel, "setting HTTP/3 Alt-Svc header"); c != nil { + c.Write(zap.Error(err)) } } - w.WriteHeader(http.StatusMethodNotAllowed) - return } + // prepare internals of the request for the handler pipeline repl := caddy.NewReplacer() r = PrepareRequest(r, repl, w, s) - // enable full-duplex for HTTP/1, ensuring the entire - // request body gets consumed before writing the response - if s.EnableFullDuplex && r.ProtoMajor == 1 { - //nolint:bodyclose - err := http.NewResponseController(w).EnableFullDuplex() - if err != nil { - if c := s.logger.Check(zapcore.WarnLevel, "failed to enable full duplex"); c != nil { - c.Write(zap.Error(err)) - } - } - } - - // clone the request for logging purposes before - // it enters any handler chain; this is necessary - // to capture the original request in case it gets - // modified during handling - // cloning the request and using .WithLazy is considerably faster - // than using .With, which will JSON encode the request immediately + // clone the request for logging purposes before it enters any handler chain; + // this is necessary to capture the original request in case it gets modified + // during handling (cloning the request and using .WithLazy is considerably + // faster than using .With, which will JSON-encode the request immediately) shouldLogCredentials := s.Logs != nil && s.Logs.ShouldLogCredentials loggableReq := zap.Object("request", LoggableHTTPRequest{ Request: r.Clone(r.Context()), @@ -352,36 +376,33 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { } // capture the original version of the request - accLog := s.accessLogger.With(loggableReq) + accLog := s.accessLogger.WithLazy(loggableReq) defer s.logRequest(accLog, r, wrec, &duration, repl, bodyReader, shouldLogCredentials) } - start := time.Now() - - // guarantee ACME HTTP challenges; handle them - // separately from any user-defined handlers + // guarantee ACME HTTP challenges; handle them separately from any user-defined handlers if s.tlsApp.HandleHTTPChallenge(w, r) { duration = time.Since(start) return } - // execute the primary handler chain - err := s.primaryHandlerChain.ServeHTTP(w, r) + err := s.serveHTTP(w, r) duration = time.Since(start) - // if no errors, we're done! if err == nil { return } // restore original request before invoking error handler chain (issue #3717) - // TODO: this does not restore original headers, if modified (for efficiency) - origReq := r.Context().Value(OriginalRequestCtxKey).(http.Request) - r.Method = origReq.Method - r.RemoteAddr = origReq.RemoteAddr - r.RequestURI = origReq.RequestURI - cloneURL(origReq.URL, r.URL) + // NOTE: this does not restore original headers if modified (for efficiency) + origReq, ok := r.Context().Value(OriginalRequestCtxKey).(http.Request) + if ok { + r.Method = origReq.Method + r.RemoteAddr = origReq.RemoteAddr + r.RequestURI = origReq.RequestURI + cloneURL(origReq.URL, r.URL) + } // prepare the error log errLog = errLog.With(zap.Duration("duration", duration)) @@ -399,10 +420,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { var fields []zapcore.Field if s.Errors != nil && len(s.Errors.Routes) > 0 { // execute user-defined error handling route - err2 := s.errorHandlerChain.ServeHTTP(w, r) - if err2 == nil { - // user's error route handled the error response - // successfully, so now just log the error + if err2 := s.errorHandlerChain.ServeHTTP(w, r); err2 == nil { + // user's error route handled the error response successfully, so now just log the error for _, logger := range errLoggers { if c := logger.Check(zapcore.DebugLevel, errMsg); c != nil { if fields == nil { @@ -450,6 +469,35 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } +func (s *Server) serveHTTP(w http.ResponseWriter, r *http.Request) error { + // reject very long methods; probably a mistake or an attack + if len(r.Method) > 32 { + if s.shouldLogRequest(r) { + if c := s.accessLogger.Check(zapcore.DebugLevel, "rejecting request with long method"); c != nil { + c.Write( + zap.String("method_trunc", r.Method[:32]), + zap.String("remote_addr", r.RemoteAddr), + ) + } + } + return HandlerError{StatusCode: http.StatusMethodNotAllowed} + } + + // RFC 9112 section 3.2: "A server MUST respond with a 400 (Bad Request) status + // code to any HTTP/1.1 request message that lacks a Host header field and to any + // request message that contains more than one Host header field line or a Host + // header field with an invalid field value." + if r.ProtoMajor == 1 && r.ProtoMinor == 1 && r.Host == "" { + return HandlerError{ + Err: errors.New("rfc9112 forbids empty Host"), + StatusCode: http.StatusBadRequest, + } + } + + // execute the primary handler chain + return s.primaryHandlerChain.ServeHTTP(w, r) +} + // wrapPrimaryRoute wraps stack (a compiled middleware handler chain) // in s.enforcementHandler which performs crucial security checks, etc. func (s *Server) wrapPrimaryRoute(stack Handler) Handler { @@ -533,15 +581,21 @@ func (s *Server) hasListenerAddress(fullAddr string) bool { // The second issue seems very similar to a discussion here: // https://github.com/nodejs/node/issues/9390 // - // This is very easy to reproduce by creating an HTTP server - // that listens to both addresses or just one with a host - // interface; or for a more confusing reproduction, try - // listening on "127.0.0.1:80" and ":443" and you'll see - // the error, if you take away the GOOS condition below. - // - // So, an address is equivalent if the port is in the port - // range, and if not on Linux, the host is the same... sigh. - if (runtime.GOOS == "linux" || thisAddrs.Host == laddrs.Host) && + // However, binding to *different specific* interfaces + // (e.g. 127.0.0.2:80 and 127.0.0.3:80) IS allowed on Linux. + // The conflict only happens when mixing specific IPs with + // wildcards (0.0.0.0 or ::). + + // Hosts match exactly (e.g. 127.0.0.2 == 127.0.0.2) -> Conflict. + hostMatch := thisAddrs.Host == laddrs.Host + + // On Linux, specific IP vs Wildcard fails to bind. + // So if we are on Linux AND either host is empty (wildcard), we treat + // it as a match (conflict). But if both are specific and different + // (127.0.0.2 vs 127.0.0.3), this remains false (no conflict). + linuxWildcardConflict := runtime.GOOS == "linux" && (thisAddrs.Host == "" || laddrs.Host == "") + + if (hostMatch || linuxWildcardConflict) && (laddrs.StartPort <= thisAddrs.EndPort) && (laddrs.StartPort >= thisAddrs.StartPort) { return true @@ -607,7 +661,7 @@ func (s *Server) serveHTTP3(addr caddy.NetworkAddress, tlsCfg *tls.Config) error return fmt.Errorf("starting HTTP/3 QUIC listener: %v", err) } addr.Network = h3net - h3ln, err := addr.ListenQUIC(s.ctx, 0, net.ListenConfig{}, tlsCfg) + h3ln, err := addr.ListenQUIC(s.ctx, 0, net.ListenConfig{}, tlsCfg, s.packetConnWrappers, s.Allow0RTT) if err != nil { return fmt.Errorf("starting HTTP/3 QUIC listener: %v", err) } @@ -620,12 +674,14 @@ func (s *Server) serveHTTP3(addr caddy.NetworkAddress, tlsCfg *tls.Config) error MaxHeaderBytes: s.MaxHeaderBytes, QUICConfig: &quic.Config{ Versions: []quic.Version{quic.Version1, quic.Version2}, - Tracer: qlog.DefaultConnectionTracer, + Tracer: h3qlog.DefaultConnectionTracer, }, IdleTimeout: time.Duration(s.IdleTimeout), } } + s.quicListeners = append(s.quicListeners, h3ln) + //nolint:errcheck go s.h3server.ServeListener(h3ln) @@ -743,9 +799,11 @@ func (s *Server) shouldLogRequest(r *http.Request) bool { hostWithoutPort = r.Host } - if _, ok := s.Logs.LoggerNames[hostWithoutPort]; ok { - // this host is mapped to a particular logger name - return true + for loggerName := range s.Logs.LoggerNames { + if certmagic.MatchWildcard(hostWithoutPort, loggerName) { + // this host is mapped to a particular logger name + return true + } } for _, dh := range s.Logs.SkipHosts { // logging for this particular host is disabled @@ -773,8 +831,10 @@ func (s *Server) logRequest( accLog *zap.Logger, r *http.Request, wrec ResponseRecorder, duration *time.Duration, repl *caddy.Replacer, bodyReader *lengthReader, shouldLogCredentials bool, ) { + ctx := r.Context() + // this request may be flagged as omitted from the logs - if skip, ok := GetVar(r.Context(), LogSkipVar).(bool); ok && skip { + if skip, ok := GetVar(ctx, LogSkipVar).(bool); ok && skip { return } @@ -792,7 +852,7 @@ func (s *Server) logRequest( } message := "handled request" - if nop, ok := GetVar(r.Context(), "unhandled").(bool); ok && nop { + if nop, ok := GetVar(ctx, "unhandled").(bool); ok && nop { message = "NOP" } @@ -816,7 +876,7 @@ func (s *Server) logRequest( reqBodyLength = bodyReader.Length } - extra := r.Context().Value(ExtraLogFieldsCtxKey).(*ExtraLogFields) + extra := ctx.Value(ExtraLogFieldsCtxKey).(*ExtraLogFields) fieldCount := 6 fields = make([]zapcore.Field, 0, fieldCount+len(extra.fields)) @@ -841,20 +901,56 @@ func (s *Server) logRequest( // protocol returns true if the protocol proto is configured/enabled. func (s *Server) protocol(proto string) bool { if s.ListenProtocols == nil { - if slices.Contains(s.Protocols, proto) { + return slices.Contains(s.protocolsWithDefaults(), proto) + } + + for _, lnProtocols := range s.ListenProtocols { + if slices.Contains(s.listenerProtocolsWithDefaults(lnProtocols), proto) { return true } - } else { - for _, lnProtocols := range s.ListenProtocols { - for _, lnProtocol := range lnProtocols { - if lnProtocol == "" && slices.Contains(s.Protocols, proto) || lnProtocol == proto { - return true - } + } + + return false +} + +func (s *Server) protocolsWithDefaults() []string { + if len(s.Protocols) == 0 { + return defaultProtocols + } + return s.Protocols +} + +func (s *Server) listenerProtocolsWithDefaults(lnProtocols []string) []string { + serverProtocols := s.protocolsWithDefaults() + if len(lnProtocols) == 0 { + return serverProtocols + } + + lnProtocolsDefault := false + lnProtocolsInclude := make([]string, 0, len(lnProtocols)+len(serverProtocols)) + srvProtocolsInclude := make(map[string]struct{}, len(serverProtocols)) + for _, srvProtocol := range serverProtocols { + srvProtocolsInclude[srvProtocol] = struct{}{} + } + + for _, lnProtocol := range lnProtocols { + if lnProtocol == "" { + lnProtocolsDefault = true + continue + } + lnProtocolsInclude = append(lnProtocolsInclude, lnProtocol) + delete(srvProtocolsInclude, lnProtocol) + } + + if lnProtocolsDefault { + for _, srvProtocol := range serverProtocols { + if _, ok := srvProtocolsInclude[srvProtocol]; ok { + lnProtocolsInclude = append(lnProtocolsInclude, srvProtocol) } } } - return false + return lnProtocolsInclude } // Listeners returns the server's listeners. These are active listeners, @@ -923,6 +1019,17 @@ func determineTrustedProxy(r *http.Request, s *Server) (bool, string) { return false, "" } + if s.TrustedProxiesUnix && r.RemoteAddr == "@" { + if s.TrustedProxiesStrict > 0 { + ipRanges := []netip.Prefix{} + if s.trustedProxies != nil { + ipRanges = s.trustedProxies.GetIPRanges(r) + } + return true, strictUntrustedClientIp(r, s.ClientIPHeaders, ipRanges, "@") + } else { + return true, trustedRealClientIP(r, s.ClientIPHeaders, "@") + } + } // Parse the remote IP, ignore the error as non-fatal, // but the remote IP is required to continue, so we // just return early. This should probably never happen @@ -970,6 +1077,7 @@ func isTrustedClientIP(ipAddr netip.Addr, trusted []netip.Prefix) bool { // then the first value from those headers is used. func trustedRealClientIP(r *http.Request, headers []string, clientIP string) string { // Read all the values of the configured client IP headers, in order + // nolint:prealloc var values []string for _, field := range headers { values = append(values, r.Header.Values(field)...) @@ -982,10 +1090,10 @@ func trustedRealClientIP(r *http.Request, headers []string, clientIP string) str // Since there can be many header values, we need to // join them together before splitting to get the full list - allValues := strings.Split(strings.Join(values, ","), ",") + allValues := strings.SplitSeq(strings.Join(values, ","), ",") // Get first valid left-most IP address - for _, part := range allValues { + for part := range allValues { // Some proxies may retain the port number, so split if possible host, _, err := net.SplitHostPort(part) if err != nil { @@ -1015,11 +1123,11 @@ func strictUntrustedClientIp(r *http.Request, headers []string, trusted []netip. for _, headerName := range headers { parts := strings.Split(strings.Join(r.Header.Values(headerName), ","), ",") - for i := len(parts) - 1; i >= 0; i-- { + for _, part := range slices.Backward(parts) { // Some proxies may retain the port number, so split if possible - host, _, err := net.SplitHostPort(parts[i]) + host, _, err := net.SplitHostPort(part) if err != nil { - host = parts[i] + host = part } // Remove any zone identifier from the IP address @@ -1079,9 +1187,14 @@ const ( // originally came into the server's entry handler OriginalRequestCtxKey caddy.CtxKey = "original_request" - // For referencing underlying net.Conn + // DEPRECATED: not used anymore. + // To refer to the underlying connection, implement a middleware plugin + // that RegisterConnContext during provisioning. ConnCtxKey caddy.CtxKey = "conn" + // used to get the tls connection state in the context, if available + tlsConnectionStateFuncCtxKey caddy.CtxKey = "tls_connection_state_func" + // For tracking whether the client is a trusted proxy TrustedProxyVarKey string = "trusted_proxy" diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/staticresp.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/staticresp.go index 1b93ede4b..439ba4f1f 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/staticresp.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/staticresp.go @@ -22,6 +22,7 @@ import ( "net/http" "net/textproto" "os" + "slices" "strconv" "strings" "text/template" @@ -78,7 +79,7 @@ Response headers may be added using the --header flag for each header field. cmd.Flags().StringP("body", "b", "", "The body of the HTTP response") cmd.Flags().BoolP("access-log", "", false, "Enable the access log") cmd.Flags().BoolP("debug", "v", false, "Enable more verbose debug-level logging") - cmd.Flags().StringSliceP("header", "H", []string{}, "Set a header on the response (format: \"Field: value\")") + cmd.Flags().StringArrayP("header", "H", []string{}, "Set a header on the response (format: \"Field: value\")") cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdRespond) }, }) @@ -245,7 +246,7 @@ func (s StaticResponse) ServeHTTP(w http.ResponseWriter, r *http.Request, next H // write response body if statusCode != http.StatusEarlyHints && body != "" { - fmt.Fprint(w, body) + fmt.Fprint(w, body) //nolint:gosec // no XSS unless you sabatoge your own config } // continue handling after Early Hints as they are not the final response @@ -256,7 +257,16 @@ func (s StaticResponse) ServeHTTP(w http.ResponseWriter, r *http.Request, next H return nil } -func buildHTTPServer(i int, port uint, addr string, statusCode int, hdr http.Header, body string, accessLog bool) (*Server, error) { +func buildHTTPServer( + i int, + port uint, + addr string, + statusCode int, + hdr http.Header, + body string, + accessLog bool, +) (*Server, error) { + // nolint:prealloc var handlers []json.RawMessage // response body supports a basic template; evaluate it @@ -323,13 +333,7 @@ func cmdRespond(fl caddycmd.Flags) (int, error) { // figure out if status code was explicitly specified; this lets // us set a non-zero value as the default but is a little hacky - var statusCodeFlagSpecified bool - for _, fl := range os.Args { - if fl == "--status" { - statusCodeFlagSpecified = true - break - } - } + statusCodeFlagSpecified := slices.Contains(os.Args, "--status") // try to determine what kind of parameter the unnamed argument is if arg != "" { @@ -364,7 +368,7 @@ func cmdRespond(fl caddycmd.Flags) (int, error) { } // build headers map - headers, err := fl.GetStringSlice("header") + headers, err := fl.GetStringArray("header") if err != nil { return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid header flag: %v", err) } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/vars.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/vars.go index 7ab891fc0..6c17fe9bb 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/vars.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddyhttp/vars.go @@ -28,6 +28,8 @@ import ( "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" ) +var stringSliceType = reflect.TypeFor[[]string]() + func init() { caddy.RegisterModule(VarsMiddleware{}) caddy.RegisterModule(VarsMatcher{}) @@ -179,8 +181,9 @@ func (m VarsMatcher) MatchWithError(r *http.Request) (bool, error) { vars := r.Context().Value(VarsCtxKey).(map[string]any) repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer) + var matcherValExpanded, varStr, v string + var varValue any for key, vals := range m { - var varValue any if strings.HasPrefix(key, "{") && strings.HasSuffix(key, "}") && strings.Count(key, "{") == 1 { @@ -189,22 +192,27 @@ func (m VarsMatcher) MatchWithError(r *http.Request) (bool, error) { varValue = vars[key] } + switch vv := varValue.(type) { + case string: + varStr = vv + case fmt.Stringer: + varStr = vv.String() + case error: + varStr = vv.Error() + case nil: + varStr = "" + default: + varStr = fmt.Sprintf("%v", vv) + } + + // Don't expand placeholders in values from literal variable names + // (e.g. map outputs) or other placeholders. These values are + // already final and must not be re-expanded, as that would allow + // user input like {env.SECRET} to be evaluated. + // see if any of the values given in the matcher match the actual value - for _, v := range vals { - matcherValExpanded := repl.ReplaceAll(v, "") - var varStr string - switch vv := varValue.(type) { - case string: - varStr = vv - case fmt.Stringer: - varStr = vv.String() - case error: - varStr = vv.Error() - case nil: - varStr = "" - default: - varStr = fmt.Sprintf("%v", vv) - } + for _, v = range vals { + matcherValExpanded = repl.ReplaceAll(v, "") if varStr == matcherValExpanded { return true, nil } @@ -308,8 +316,11 @@ func (m MatchVarsRE) Match(r *http.Request) bool { func (m MatchVarsRE) MatchWithError(r *http.Request) (bool, error) { vars := r.Context().Value(VarsCtxKey).(map[string]any) repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer) + + var match bool + var varStr string + var varValue any for key, val := range m { - var varValue any if strings.HasPrefix(key, "{") && strings.HasSuffix(key, "}") && strings.Count(key, "{") == 1 { @@ -318,7 +329,6 @@ func (m MatchVarsRE) MatchWithError(r *http.Request) (bool, error) { varValue = vars[key] } - var varStr string switch vv := varValue.(type) { case string: varStr = vv @@ -332,8 +342,12 @@ func (m MatchVarsRE) MatchWithError(r *http.Request) (bool, error) { varStr = fmt.Sprintf("%v", vv) } - valExpanded := repl.ReplaceAll(varStr, "") - if match := val.Match(valExpanded, repl); match { + // Don't expand placeholders in values from literal variable names + // (e.g. map outputs) or other placeholders. These values are + // already final and must not be re-expanded, as that would allow + // user input like {env.SECRET} to be evaluated. + + if match = val.Match(varStr, repl); match { return match, nil } } @@ -353,7 +367,7 @@ func (MatchVarsRE) CELLibrary(ctx caddy.Context) (cel.Library, error) { "vars_regexp_request_string_string", []*cel.Type{cel.StringType, cel.StringType}, func(data ref.Val) (RequestMatcherWithError, error) { - refStringList := reflect.TypeOf([]string{}) + refStringList := stringSliceType params, err := data.ConvertToNative(refStringList) if err != nil { return nil, err @@ -376,7 +390,7 @@ func (MatchVarsRE) CELLibrary(ctx caddy.Context) (cel.Library, error) { "vars_regexp_request_string_string_string", []*cel.Type{cel.StringType, cel.StringType, cel.StringType}, func(data ref.Val) (RequestMatcherWithError, error) { - refStringList := reflect.TypeOf([]string{}) + refStringList := stringSliceType params, err := data.ConvertToNative(refStringList) if err != nil { return nil, err diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/adminapi.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/adminapi.go index c454f6458..dcd3b5816 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/adminapi.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/adminapi.go @@ -163,9 +163,9 @@ func (a *adminAPI) handleCACerts(w http.ResponseWriter, r *http.Request) error { } w.Header().Set("Content-Type", "application/pem-certificate-chain") - _, err = w.Write(interCert) + _, err = w.Write(interCert) //nolint:gosec // false positive... no XSS in a PEM for cryin' out loud if err == nil { - _, _ = w.Write(rootCert) + _, _ = w.Write(rootCert) //nolint:gosec // false positive... no XSS in a PEM for cryin' out loud } return nil @@ -220,12 +220,17 @@ func (a *adminAPI) getCAFromAPIRequestPath(r *http.Request) (*CA, error) { func rootAndIntermediatePEM(ca *CA) (root, inter []byte, err error) { root, err = pemEncodeCert(ca.RootCertificate().Raw) if err != nil { - return + return root, inter, err } - inter, err = pemEncodeCert(ca.IntermediateCertificate().Raw) - if err != nil { - return + + for _, interCert := range ca.IntermediateCertificateChain() { + pemBytes, err := pemEncodeCert(interCert.Raw) + if err != nil { + return nil, nil, err + } + inter = append(inter, pemBytes...) } + return } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/ca.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/ca.go index 6c48da6f9..4b98244aa 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/ca.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/ca.go @@ -63,6 +63,15 @@ type CA struct { // The intermediate (signing) certificate; if null, one will be generated. Intermediate *KeyPair `json:"intermediate,omitempty"` + // How often to check if intermediate (and root, when applicable) certificates need renewal. + // Default: 10m. + MaintenanceInterval caddy.Duration `json:"maintenance_interval,omitempty"` + + // The fraction of certificate lifetime (0.0–1.0) after which renewal is attempted. + // For example, 0.2 means renew when 20% of the lifetime remains (e.g. ~73 days for a 1-year cert). + // Default: 0.2. + RenewalWindowRatio float64 `json:"renewal_window_ratio,omitempty"` + // Optionally configure a separate storage module associated with this // issuer, instead of using Caddy's global/default-configured storage. // This can be useful if you want to keep your signing keys in a @@ -75,10 +84,11 @@ type CA struct { // and module provisioning. ID string `json:"-"` - storage certmagic.Storage - root, inter *x509.Certificate - interKey any // TODO: should we just store these as crypto.Signer? - mu *sync.RWMutex + storage certmagic.Storage + root *x509.Certificate + interChain []*x509.Certificate + interKey crypto.Signer + mu *sync.RWMutex rootCertPath string // mainly used for logging purposes if trusting log *zap.Logger @@ -124,19 +134,25 @@ func (ca *CA) Provision(ctx caddy.Context, id string, log *zap.Logger) error { } if ca.IntermediateLifetime == 0 { ca.IntermediateLifetime = caddy.Duration(defaultIntermediateLifetime) - } else if time.Duration(ca.IntermediateLifetime) >= defaultRootLifetime { - return fmt.Errorf("intermediate certificate lifetime must be less than root certificate lifetime (%s)", defaultRootLifetime) + } + if ca.MaintenanceInterval == 0 { + ca.MaintenanceInterval = caddy.Duration(defaultMaintenanceInterval) + } + if ca.RenewalWindowRatio <= 0 || ca.RenewalWindowRatio > 1 { + ca.RenewalWindowRatio = defaultRenewalWindowRatio } // load the certs and key that will be used for signing - var rootCert, interCert *x509.Certificate + var rootCert *x509.Certificate + var rootCertChain, interCertChain []*x509.Certificate var rootKey, interKey crypto.Signer var err error if ca.Root != nil { if ca.Root.Format == "" || ca.Root.Format == "pem_file" { ca.rootCertPath = ca.Root.Certificate } - rootCert, rootKey, err = ca.Root.Load() + rootCertChain, rootKey, err = ca.Root.Load() + rootCert = rootCertChain[0] } else { ca.rootCertPath = "storage:" + ca.storageKeyRootCert() rootCert, rootKey, err = ca.loadOrGenRoot() @@ -144,17 +160,23 @@ func (ca *CA) Provision(ctx caddy.Context, id string, log *zap.Logger) error { if err != nil { return err } + if ca.Intermediate != nil { - interCert, interKey, err = ca.Intermediate.Load() + interCertChain, interKey, err = ca.Intermediate.Load() } else { - interCert, interKey, err = ca.loadOrGenIntermediate(rootCert, rootKey) + actualRootLifetime := time.Until(rootCert.NotAfter) + if time.Duration(ca.IntermediateLifetime) >= actualRootLifetime { + return fmt.Errorf("intermediate certificate lifetime must be less than actual root certificate lifetime (%s)", actualRootLifetime) + } + + interCertChain, interKey, err = ca.loadOrGenIntermediate(rootCert, rootKey) } if err != nil { return err } ca.mu.Lock() - ca.root, ca.inter, ca.interKey = rootCert, interCert, interKey + ca.root, ca.interChain, ca.interKey = rootCert, interCertChain, interKey ca.mu.Unlock() return nil @@ -170,21 +192,21 @@ func (ca CA) RootCertificate() *x509.Certificate { // RootKey returns the CA's root private key. Since the root key is // not cached in memory long-term, it needs to be loaded from storage, // which could yield an error. -func (ca CA) RootKey() (any, error) { +func (ca CA) RootKey() (crypto.Signer, error) { _, rootKey, err := ca.loadOrGenRoot() return rootKey, err } -// IntermediateCertificate returns the CA's intermediate -// certificate (public key). -func (ca CA) IntermediateCertificate() *x509.Certificate { +// IntermediateCertificateChain returns the CA's intermediate +// certificate chain. +func (ca CA) IntermediateCertificateChain() []*x509.Certificate { ca.mu.RLock() defer ca.mu.RUnlock() - return ca.inter + return ca.interChain } // IntermediateKey returns the CA's intermediate private key. -func (ca CA) IntermediateKey() any { +func (ca CA) IntermediateKey() crypto.Signer { ca.mu.RLock() defer ca.mu.RUnlock() return ca.interKey @@ -205,26 +227,27 @@ func (ca *CA) NewAuthority(authorityConfig AuthorityConfig) (*authority.Authorit // cert/key directly, since it's unlikely to expire // while Caddy is running (long lifetime) var issuerCert *x509.Certificate - var issuerKey any + var issuerKey crypto.Signer issuerCert = rootCert var err error issuerKey, err = ca.RootKey() if err != nil { return nil, fmt.Errorf("loading signing key: %v", err) } - signerOption = authority.WithX509Signer(issuerCert, issuerKey.(crypto.Signer)) + signerOption = authority.WithX509Signer(issuerCert, issuerKey) } else { // if we're signing with intermediate, we need to make // sure it's always fresh, because the intermediate may // renew while Caddy is running (medium lifetime) signerOption = authority.WithX509SignerFunc(func() ([]*x509.Certificate, crypto.Signer, error) { - issuerCert := ca.IntermediateCertificate() - issuerKey := ca.IntermediateKey().(crypto.Signer) + issuerChain := ca.IntermediateCertificateChain() + issuerCert := issuerChain[0] + issuerKey := ca.IntermediateKey() ca.log.Debug("using intermediate signer", zap.String("serial", issuerCert.SerialNumber.String()), zap.String("not_before", issuerCert.NotBefore.String()), zap.String("not_after", issuerCert.NotAfter.String())) - return []*x509.Certificate{issuerCert}, issuerKey, nil + return issuerChain, issuerKey, nil }) } @@ -250,7 +273,11 @@ func (ca *CA) NewAuthority(authorityConfig AuthorityConfig) (*authority.Authorit func (ca CA) loadOrGenRoot() (rootCert *x509.Certificate, rootKey crypto.Signer, err error) { if ca.Root != nil { - return ca.Root.Load() + rootChain, rootSigner, err := ca.Root.Load() + if err != nil { + return nil, nil, err + } + return rootChain[0], rootSigner, nil } rootCertPEM, err := ca.storage.Load(ca.ctx, ca.storageKeyRootCert()) if err != nil { @@ -266,7 +293,7 @@ func (ca CA) loadOrGenRoot() (rootCert *x509.Certificate, rootKey crypto.Signer, } if rootCert == nil { - rootCert, err = pemDecodeSingleCert(rootCertPEM) + rootCert, err = pemDecodeCertificate(rootCertPEM) if err != nil { return nil, nil, fmt.Errorf("parsing root certificate PEM: %v", err) } @@ -312,7 +339,8 @@ func (ca CA) genRoot() (rootCert *x509.Certificate, rootKey crypto.Signer, err e return rootCert, rootKey, nil } -func (ca CA) loadOrGenIntermediate(rootCert *x509.Certificate, rootKey crypto.Signer) (interCert *x509.Certificate, interKey crypto.Signer, err error) { +func (ca CA) loadOrGenIntermediate(rootCert *x509.Certificate, rootKey crypto.Signer) (interCertChain []*x509.Certificate, interKey crypto.Signer, err error) { + var interCert *x509.Certificate interCertPEM, err := ca.storage.Load(ca.ctx, ca.storageKeyIntermediateCert()) if err != nil { if !errors.Is(err, fs.ErrNotExist) { @@ -324,10 +352,12 @@ func (ca CA) loadOrGenIntermediate(rootCert *x509.Certificate, rootKey crypto.Si if err != nil { return nil, nil, fmt.Errorf("generating new intermediate cert: %v", err) } + + interCertChain = append(interCertChain, interCert) } - if interCert == nil { - interCert, err = pemDecodeSingleCert(interCertPEM) + if len(interCertChain) == 0 { + interCertChain, err = pemDecodeCertificateChain(interCertPEM) if err != nil { return nil, nil, fmt.Errorf("decoding intermediate certificate PEM: %v", err) } @@ -344,7 +374,7 @@ func (ca CA) loadOrGenIntermediate(rootCert *x509.Certificate, rootKey crypto.Si } } - return interCert, interKey, nil + return interCertChain, interKey, nil } func (ca CA) genIntermediate(rootCert *x509.Certificate, rootKey crypto.Signer) (interCert *x509.Certificate, interKey crypto.Signer, err error) { @@ -441,4 +471,6 @@ const ( defaultRootLifetime = 24 * time.Hour * 30 * 12 * 10 defaultIntermediateLifetime = 24 * time.Hour * 7 + defaultMaintenanceInterval = 10 * time.Minute + defaultRenewalWindowRatio = 0.2 ) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/crypto.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/crypto.go index 324a4fcfa..cfe46cd6d 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/crypto.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/crypto.go @@ -17,15 +17,20 @@ package caddypki import ( "bytes" "crypto" + "crypto/ecdsa" + "crypto/ed25519" + "crypto/rsa" "crypto/x509" "encoding/pem" + "errors" "fmt" "os" "github.com/caddyserver/certmagic" + "go.step.sm/crypto/pemutil" ) -func pemDecodeSingleCert(pemDER []byte) (*x509.Certificate, error) { +func pemDecodeCertificate(pemDER []byte) (*x509.Certificate, error) { pemBlock, remaining := pem.Decode(pemDER) if pemBlock == nil { return nil, fmt.Errorf("no PEM block found") @@ -39,6 +44,15 @@ func pemDecodeSingleCert(pemDER []byte) (*x509.Certificate, error) { return x509.ParseCertificate(pemBlock.Bytes) } +func pemDecodeCertificateChain(pemDER []byte) ([]*x509.Certificate, error) { + chain, err := pemutil.ParseCertificateBundle(pemDER) + if err != nil { + return nil, fmt.Errorf("failed parsing certificate chain: %w", err) + } + + return chain, nil +} + func pemEncodeCert(der []byte) ([]byte, error) { return pemEncode("CERTIFICATE", der) } @@ -63,22 +77,25 @@ type KeyPair struct { // The private key. By default, this should be the path to // a PEM file unless format is something else. - PrivateKey string `json:"private_key,omitempty"` + PrivateKey string `json:"private_key,omitempty"` //nolint:gosec // false positive: yes it's exported, since it needs to encode/decode as JSON; and is often just a filepath // The format in which the certificate and private // key are provided. Default: pem_file Format string `json:"format,omitempty"` } -// Load loads the certificate and key. -func (kp KeyPair) Load() (*x509.Certificate, crypto.Signer, error) { +// Load loads the certificate chain and (optional) private key from +// the corresponding files, using the configured format. If a +// private key is read, it will be verified to belong to the first +// certificate in the chain. +func (kp KeyPair) Load() ([]*x509.Certificate, crypto.Signer, error) { switch kp.Format { case "", "pem_file": certData, err := os.ReadFile(kp.Certificate) if err != nil { return nil, nil, err } - cert, err := pemDecodeSingleCert(certData) + chain, err := pemDecodeCertificateChain(certData) if err != nil { return nil, nil, err } @@ -93,11 +110,49 @@ func (kp KeyPair) Load() (*x509.Certificate, crypto.Signer, error) { if err != nil { return nil, nil, err } + if err := verifyKeysMatch(chain[0], key); err != nil { + return nil, nil, err + } } - return cert, key, nil + return chain, key, nil default: return nil, nil, fmt.Errorf("unsupported format: %s", kp.Format) } } + +// verifyKeysMatch verifies that the public key in the [x509.Certificate] matches +// the public key of the [crypto.Signer]. +func verifyKeysMatch(crt *x509.Certificate, signer crypto.Signer) error { + switch pub := crt.PublicKey.(type) { + case *rsa.PublicKey: + pk, ok := signer.Public().(*rsa.PublicKey) + if !ok { + return fmt.Errorf("private key type %T does not match issuer public key type %T", signer.Public(), pub) + } + if !pub.Equal(pk) { + return errors.New("private key does not match issuer public key") + } + case *ecdsa.PublicKey: + pk, ok := signer.Public().(*ecdsa.PublicKey) + if !ok { + return fmt.Errorf("private key type %T does not match issuer public key type %T", signer.Public(), pub) + } + if !pub.Equal(pk) { + return errors.New("private key does not match issuer public key") + } + case ed25519.PublicKey: + pk, ok := signer.Public().(ed25519.PublicKey) + if !ok { + return fmt.Errorf("private key type %T does not match issuer public key type %T", signer.Public(), pub) + } + if !pub.Equal(pk) { + return errors.New("private key does not match issuer public key") + } + default: + return fmt.Errorf("unsupported key type: %T", pub) + } + + return nil +} diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/maintain.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/maintain.go index 31e453ff9..31e4c6a8b 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/maintain.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/maintain.go @@ -24,20 +24,24 @@ import ( "go.uber.org/zap" ) -func (p *PKI) maintenance() { +func (p *PKI) maintenanceForCA(ca *CA) { defer func() { if err := recover(); err != nil { - log.Printf("[PANIC] PKI maintenance: %v\n%s", err, debug.Stack()) + log.Printf("[PANIC] PKI maintenance for CA %s: %v\n%s", ca.ID, err, debug.Stack()) } }() - ticker := time.NewTicker(10 * time.Minute) // TODO: make configurable + interval := time.Duration(ca.MaintenanceInterval) + if interval <= 0 { + interval = defaultMaintenanceInterval + } + ticker := time.NewTicker(interval) defer ticker.Stop() for { select { case <-ticker.C: - p.renewCerts() + _ = p.renewCertsForCA(ca) case <-p.ctx.Done(): return } @@ -63,19 +67,19 @@ func (p *PKI) renewCertsForCA(ca *CA) error { // only maintain the root if it's not manually provided in the config if ca.Root == nil { - if needsRenewal(ca.root) { + if ca.needsRenewal(ca.root) { // TODO: implement root renewal (use same key) log.Warn("root certificate expiring soon (FIXME: ROOT RENEWAL NOT YET IMPLEMENTED)", - zap.Duration("time_remaining", time.Until(ca.inter.NotAfter)), + zap.Duration("time_remaining", time.Until(ca.interChain[0].NotAfter)), ) } } // only maintain the intermediate if it's not manually provided in the config if ca.Intermediate == nil { - if needsRenewal(ca.inter) { + if ca.needsRenewal(ca.interChain[0]) { log.Info("intermediate expires soon; renewing", - zap.Duration("time_remaining", time.Until(ca.inter.NotAfter)), + zap.Duration("time_remaining", time.Until(ca.interChain[0].NotAfter)), ) rootCert, rootKey, err := ca.loadOrGenRoot() @@ -86,10 +90,10 @@ func (p *PKI) renewCertsForCA(ca *CA) error { if err != nil { return fmt.Errorf("generating new certificate: %v", err) } - ca.inter, ca.interKey = interCert, interKey + ca.interChain, ca.interKey = []*x509.Certificate{interCert}, interKey log.Info("renewed intermediate", - zap.Time("new_expiration", ca.inter.NotAfter), + zap.Time("new_expiration", ca.interChain[0].NotAfter), ) } } @@ -97,11 +101,15 @@ func (p *PKI) renewCertsForCA(ca *CA) error { return nil } -func needsRenewal(cert *x509.Certificate) bool { +// needsRenewal reports whether the certificate is within its renewal window +// (i.e. the fraction of lifetime remaining is less than or equal to RenewalWindowRatio). +func (ca *CA) needsRenewal(cert *x509.Certificate) bool { + ratio := ca.RenewalWindowRatio + if ratio <= 0 { + ratio = defaultRenewalWindowRatio + } lifetime := cert.NotAfter.Sub(cert.NotBefore) - renewalWindow := time.Duration(float64(lifetime) * renewalWindowRatio) + renewalWindow := time.Duration(float64(lifetime) * ratio) renewalWindowStart := cert.NotAfter.Add(-renewalWindow) return time.Now().After(renewalWindowStart) } - -const renewalWindowRatio = 0.2 // TODO: make configurable diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/pki.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/pki.go index 9f974a956..557df74fc 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/pki.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddypki/pki.go @@ -109,8 +109,10 @@ func (p *PKI) Start() error { // see if root/intermediates need renewal... p.renewCerts() - // ...and keep them renewed - go p.maintenance() + // ...and keep them renewed (one goroutine per CA with its own interval) + for _, ca := range p.CAs { + go p.maintenanceForCA(ca) + } return nil } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/acmeissuer.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/acmeissuer.go index bf2ebeacc..193c8bfc7 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/acmeissuer.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/acmeissuer.go @@ -140,6 +140,42 @@ func (iss *ACMEIssuer) Provision(ctx caddy.Context) error { iss.Email = email } + // expand CA endpoint, if non-empty + if iss.CA != "" { + ca, err := repl.ReplaceOrErr(iss.CA, true, true) + if err != nil { + return fmt.Errorf("expanding CA endpoint '%s': %v", iss.CA, err) + } + iss.CA = ca + } + + // expand TestCA endpoint, if non-empty + if iss.TestCA != "" { + testca, err := repl.ReplaceOrErr(iss.TestCA, true, true) + if err != nil { + return fmt.Errorf("expanding TestCA endpoint '%s': %v", iss.TestCA, err) + } + iss.TestCA = testca + } + + // expand EAB credentials, if non-empty + if iss.ExternalAccount != nil { + if iss.ExternalAccount.KeyID != "" { + keyID, err := repl.ReplaceOrErr(iss.ExternalAccount.KeyID, true, true) + if err != nil { + return fmt.Errorf("expanding EAB key ID '%s': %v", iss.ExternalAccount.KeyID, err) + } + iss.ExternalAccount.KeyID = keyID + } + if iss.ExternalAccount.MACKey != "" { + macKey, err := repl.ReplaceOrErr(iss.ExternalAccount.MACKey, true, true) + if err != nil { + return fmt.Errorf("expanding EAB MAC key (redacted): %v", err) + } + iss.ExternalAccount.MACKey = macKey + } + } + // expand account key, if non-empty if iss.AccountKey != "" { accountKey, err := repl.ReplaceOrErr(iss.AccountKey, true, true) @@ -149,6 +185,15 @@ func (iss *ACMEIssuer) Provision(ctx caddy.Context) error { iss.AccountKey = accountKey } + // expand DNS override domain, if non-empty + if iss.Challenges != nil && iss.Challenges.DNS != nil && iss.Challenges.DNS.OverrideDomain != "" { + overrideDomain, err := repl.ReplaceOrErr(iss.Challenges.DNS.OverrideDomain, true, true) + if err != nil { + return fmt.Errorf("expanding DNS override domain '%s': %v", iss.Challenges.DNS.OverrideDomain, err) + } + iss.Challenges.DNS.OverrideDomain = overrideDomain + } + // DNS challenge provider, if not already established if iss.Challenges != nil && iss.Challenges.DNS != nil && iss.Challenges.DNS.solver == nil { var prov certmagic.DNSProvider @@ -178,6 +223,7 @@ func (iss *ACMEIssuer) Provision(ctx caddy.Context) error { PropagationTimeout: time.Duration(iss.Challenges.DNS.PropagationTimeout), Resolvers: iss.Challenges.DNS.Resolvers, OverrideDomain: iss.Challenges.DNS.OverrideDomain, + Logger: iss.logger.Named("dns_manager"), }, } } @@ -220,7 +266,7 @@ func (iss *ACMEIssuer) makeIssuerTemplate(ctx caddy.Context) (certmagic.ACMEIssu } if len(iss.NetworkProxyRaw) != 0 { - proxyMod, err := ctx.LoadModule(iss, "ForwardProxyRaw") + proxyMod, err := ctx.LoadModule(iss, "NetworkProxyRaw") if err != nil { return template, fmt.Errorf("failed to load network_proxy module: %v", err) } @@ -244,6 +290,9 @@ func (iss *ACMEIssuer) makeIssuerTemplate(ctx caddy.Context) (certmagic.ACMEIssu template.DNS01Solver = iss.Challenges.DNS.solver } template.ListenHost = iss.Challenges.BindHost + if iss.Challenges.Distributed != nil { + template.DisableDistributedSolvers = !*iss.Challenges.Distributed + } } if iss.PreferredChains != nil { @@ -333,7 +382,7 @@ func (iss *ACMEIssuer) generateZeroSSLEABCredentials(ctx context.Context, acct a req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("User-Agent", certmagic.UserAgent) - resp, err := http.DefaultClient.Do(req) + resp, err := http.DefaultClient.Do(req) //nolint:gosec // no SSRF since URL is from trusted config if err != nil { return nil, acct, fmt.Errorf("performing EAB credentials request: %v", err) } @@ -480,6 +529,20 @@ func (iss *ACMEIssuer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { } iss.Challenges.TLSALPN.Disabled = true + case "distributed": + if !d.NextArg() { + return d.ArgErr() + } + if d.Val() != "false" { + return d.Errf("only accepted value is 'false'") + } + if iss.Challenges == nil { + iss.Challenges = new(ChallengesConfig) + } + if iss.Challenges.Distributed == nil { + iss.Challenges.Distributed = new(bool) + } + case "alt_http_port": if !d.NextArg() { return d.ArgErr() @@ -654,7 +717,7 @@ func ParseCaddyfilePreferredChainsOptions(d *caddyfile.Dispenser) (*ChainPrefere switch d.Val() { case "root_common_name": rootCommonNameOpt := d.RemainingArgs() - chainPref.RootCommonName = rootCommonNameOpt + chainPref.RootCommonName = append(chainPref.RootCommonName, rootCommonNameOpt...) if rootCommonNameOpt == nil { return nil, d.ArgErr() } @@ -664,7 +727,7 @@ func ParseCaddyfilePreferredChainsOptions(d *caddyfile.Dispenser) (*ChainPrefere case "any_common_name": anyCommonNameOpt := d.RemainingArgs() - chainPref.AnyCommonName = anyCommonNameOpt + chainPref.AnyCommonName = append(chainPref.AnyCommonName, anyCommonNameOpt...) if anyCommonNameOpt == nil { return nil, d.ArgErr() } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/automation.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/automation.go index 6f3b98a3e..5b7a4ed5d 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/automation.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/automation.go @@ -173,6 +173,9 @@ type AutomationPolicy struct { subjects []string magic *certmagic.Config storage certmagic.Storage + + // Whether this policy had explicit managers configured directly on it. + hadExplicitManagers bool } // Provision sets up ap and builds its underlying CertMagic config. @@ -209,9 +212,8 @@ func (ap *AutomationPolicy) Provision(tlsApp *TLS) error { // store them on the policy before putting it on the config // load and provision any cert manager modules - var hadExplicitManagers bool if ap.ManagersRaw != nil { - hadExplicitManagers = true + ap.hadExplicitManagers = true vals, err := tlsApp.ctx.LoadModule(ap, "ManagersRaw") if err != nil { return fmt.Errorf("loading external certificate manager modules: %v", err) @@ -233,7 +235,7 @@ func (ap *AutomationPolicy) Provision(tlsApp *TLS) error { } issuers := ap.Issuers - if len(issuers) == 0 { + if len(issuers) == 0 && !ap.implicitTailscaleManagersOnly() { var err error issuers, err = DefaultIssuersProvisioned(tlsApp.ctx) if err != nil { @@ -241,22 +243,49 @@ func (ap *AutomationPolicy) Provision(tlsApp *TLS) error { } } + // build certmagic.Config and attach it to the policy + storage := ap.storage + if storage == nil { + storage = tlsApp.ctx.Storage() + } + cfg, err := ap.makeCertMagicConfig(tlsApp, issuers, storage) + if err != nil { + return err + } + certCacheMu.RLock() + ap.magic = certmagic.New(certCache, cfg) + certCacheMu.RUnlock() + + // give issuers a chance to see the config pointer + for _, issuer := range ap.magic.Issuers { + if annoying, ok := issuer.(ConfigSetter); ok { + annoying.SetConfig(ap.magic) + } + } + + return nil +} + +// makeCertMagicConfig constructs a certmagic.Config for this policy using the +// provided issuers and storage. It encapsulates common logic shared between +// Provision and RebuildCertMagic so we don't duplicate code. +func (ap *AutomationPolicy) makeCertMagicConfig(tlsApp *TLS, issuers []certmagic.Issuer, storage certmagic.Storage) (certmagic.Config, error) { + // key source keyType := ap.KeyType if keyType != "" { var err error keyType, err = caddy.NewReplacer().ReplaceOrErr(ap.KeyType, true, true) if err != nil { - return fmt.Errorf("invalid key type %s: %s", ap.KeyType, err) + return certmagic.Config{}, fmt.Errorf("invalid key type %s: %s", ap.KeyType, err) } if _, ok := supportedCertKeyTypes[keyType]; !ok { - return fmt.Errorf("unrecognized key type: %s", keyType) + return certmagic.Config{}, fmt.Errorf("unrecognized key type: %s", keyType) } } keySource := certmagic.StandardKeyGenerator{ KeyType: supportedCertKeyTypes[keyType], } - storage := ap.storage if storage == nil { storage = tlsApp.ctx.Storage() } @@ -271,11 +300,11 @@ func (ap *AutomationPolicy) Provision(tlsApp *TLS) error { // prevent issuance from Issuers (when Managers don't provide a certificate) if there's no // permission module configured noProtections := ap.isWildcardOrDefault() && !ap.onlyInternalIssuer() && (tlsApp.Automation == nil || tlsApp.Automation.OnDemand == nil || tlsApp.Automation.OnDemand.permission == nil) - failClosed := noProtections && !hadExplicitManagers // don't allow on-demand issuance (other than implicit managers) if no managers have been explicitly configured + failClosed := noProtections && !ap.hadExplicitManagers // don't allow on-demand issuance (other than implicit managers) if no managers have been explicitly configured if noProtections { - if !hadExplicitManagers { + if !ap.hadExplicitManagers { // no managers, no explicitly-configured permission module, this is a config error - return fmt.Errorf("on-demand TLS cannot be enabled without a permission module to prevent abuse; please refer to documentation for details") + return certmagic.Config{}, fmt.Errorf("on-demand TLS cannot be enabled without a permission module to prevent abuse; please refer to documentation for details") } // allow on-demand to be enabled but only for the purpose of the Managers; issuance won't be allowed from Issuers tlsApp.logger.Warn("on-demand TLS can only get certificates from the configured external manager(s) because no ask endpoint / permission module is specified") @@ -332,7 +361,7 @@ func (ap *AutomationPolicy) Provision(tlsApp *TLS) error { } } - template := certmagic.Config{ + cfg := certmagic.Config{ MustStaple: ap.MustStaple, RenewalWindowRatio: ap.RenewalWindowRatio, KeySource: keySource, @@ -347,8 +376,31 @@ func (ap *AutomationPolicy) Provision(tlsApp *TLS) error { Issuers: issuers, Logger: tlsApp.logger, } + + return cfg, nil +} + +// IsProvisioned reports whether the automation policy has been +// provisioned. A provisioned policy has an initialized CertMagic +// instance (i.e. ap.magic != nil). +func (ap *AutomationPolicy) IsProvisioned() bool { return ap.magic != nil } + +// RebuildCertMagic rebuilds the policy's CertMagic configuration from the +// policy's already-populated fields (Issuers, Managers, storage, etc.) and +// replaces the internal CertMagic instance. This is a lightweight +// alternative to calling Provision because it does not re-provision +// modules or re-run module Provision; instead, it constructs a new +// certmagic.Config and calls SetConfig on issuers so they receive updated +// templates (for example, alternate HTTP/TLS ports supplied by the HTTP +// app). RebuildCertMagic should only be called when the policy's required +// fields are already populated. +func (ap *AutomationPolicy) RebuildCertMagic(tlsApp *TLS) error { + cfg, err := ap.makeCertMagicConfig(tlsApp, ap.Issuers, ap.storage) + if err != nil { + return err + } certCacheMu.RLock() - ap.magic = certmagic.New(certCache, template) + ap.magic = certmagic.New(certCache, cfg) certCacheMu.RUnlock() // sometimes issuers may need the parent certmagic.Config in @@ -377,6 +429,29 @@ func (ap *AutomationPolicy) AllInternalSubjects() bool { }) } +// implicitTailscaleManagersOnly returns true if this policy is configured to +// serve only Tailscale names from the Tailscale manager at handshake-time. +func (ap *AutomationPolicy) implicitTailscaleManagersOnly() bool { + if len(ap.subjects) == 0 { + return false + } + + for _, subject := range ap.subjects { + if !strings.HasSuffix(strings.ToLower(subject), tailscaleDomainAliasEnding) { + return false + } + } + + for _, manager := range ap.Managers { + switch manager.(type) { + case Tailscale, *Tailscale: + return true + } + } + + return false +} + func (ap *AutomationPolicy) onlyInternalIssuer() bool { if len(ap.Issuers) != 1 { return false @@ -388,10 +463,8 @@ func (ap *AutomationPolicy) onlyInternalIssuer() bool { // isWildcardOrDefault determines if the subjects include any wildcard domains, // or is the "default" policy (i.e. no subjects) which is unbounded. func (ap *AutomationPolicy) isWildcardOrDefault() bool { - isWildcardOrDefault := false - if len(ap.subjects) == 0 { - isWildcardOrDefault = true - } + isWildcardOrDefault := len(ap.subjects) == 0 + for _, sub := range ap.subjects { if strings.HasPrefix(sub, "*") { isWildcardOrDefault = true @@ -456,6 +529,22 @@ type ChallengesConfig struct { // Optionally customize the host to which a listener // is bound if required for solving a challenge. BindHost string `json:"bind_host,omitempty"` + + // Whether distributed solving is enabled. This is + // enabled by default, so this is only used to + // disable it, which should only need to be done if + // you cannot reliably or affordably use storage + // backend for writing/distributing challenge info. + // (Applies to HTTP and TLS-ALPN challenges.) + // If set to false, challenges can only be solved + // from the Caddy instance that initiated the + // challenge, with the exception of HTTP challenges + // initiated with the same ACME account that this + // config uses. (Caddy can still solve those challenges + // without explicitly writing the info to storage.) + // + // Default: true + Distributed *bool `json:"distributed,omitempty"` } // HTTPChallengeConfig configures the ACME HTTP challenge. diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/capools.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/capools.go index c73bc4832..c275f7d6f 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/capools.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/capools.go @@ -4,6 +4,7 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" + "encoding/pem" "errors" "fmt" "io" @@ -27,6 +28,8 @@ func init() { caddy.RegisterModule(PKIIntermediateCAPool{}) caddy.RegisterModule(StoragePool{}) caddy.RegisterModule(HTTPCertPool{}) + caddy.RegisterModule(SystemCAPool{}) + caddy.RegisterModule(CombinedCAPool{}) } // The interface to be implemented by all guest modules part of @@ -35,6 +38,12 @@ type CA interface { CertPool() *x509.CertPool } +// CertificateProvider is an optional interface that CA pool sources +// can implement to expose their underlying certificates for combining. +type CertificateProvider interface { + Certificates() []*x509.Certificate +} + // InlineCAPool is a certificate authority pool provider coming from // a DER-encoded certificates in the config type InlineCAPool struct { @@ -44,7 +53,8 @@ type InlineCAPool struct { // these CAs will be rejected. TrustedCACerts []string `json:"trusted_ca_certs,omitempty"` - pool *x509.CertPool + pool *x509.CertPool + certs []*x509.Certificate } // CaddyModule implements caddy.Module. @@ -60,14 +70,17 @@ func (icp InlineCAPool) CaddyModule() caddy.ModuleInfo { // Provision implements caddy.Provisioner. func (icp *InlineCAPool) Provision(ctx caddy.Context) error { caPool := x509.NewCertPool() + var certs []*x509.Certificate for i, clientCAString := range icp.TrustedCACerts { clientCA, err := decodeBase64DERCert(clientCAString) if err != nil { return fmt.Errorf("parsing certificate at index %d: %v", i, err) } caPool.AddCert(clientCA) + certs = append(certs, clientCA) } icp.pool = caPool + icp.certs = certs return nil } @@ -103,6 +116,11 @@ func (icp InlineCAPool) CertPool() *x509.CertPool { return icp.pool } +// Certificates implements CertificateProvider. +func (icp InlineCAPool) Certificates() []*x509.Certificate { + return icp.certs +} + // FileCAPool generates trusted root certificates pool from the designated DER and PEM file type FileCAPool struct { // TrustedCACertPEMFiles is a list of PEM file names @@ -111,7 +129,8 @@ type FileCAPool struct { // these CA certificates will be rejected. TrustedCACertPEMFiles []string `json:"pem_files,omitempty"` - pool *x509.CertPool + pool *x509.CertPool + certs []*x509.Certificate } // CaddyModule implements caddy.Module. @@ -127,14 +146,32 @@ func (FileCAPool) CaddyModule() caddy.ModuleInfo { // Loads and decodes the DER and pem files to generate the certificate pool func (f *FileCAPool) Provision(ctx caddy.Context) error { caPool := x509.NewCertPool() + var certs []*x509.Certificate for _, pemFile := range f.TrustedCACertPEMFiles { pemContents, err := os.ReadFile(pemFile) if err != nil { return fmt.Errorf("reading %s: %v", pemFile, err) } - caPool.AppendCertsFromPEM(pemContents) + // Parse PEM to extract certificates + for len(pemContents) > 0 { + var block *pem.Block + block, pemContents = pem.Decode(pemContents) + if block == nil { + break + } + if block.Type != "CERTIFICATE" { + continue + } + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return fmt.Errorf("parsing certificate in %s: %v", pemFile, err) + } + caPool.AddCert(cert) + certs = append(certs, cert) + } } f.pool = caPool + f.certs = certs return nil } @@ -166,13 +203,19 @@ func (f FileCAPool) CertPool() *x509.CertPool { return f.pool } +// Certificates implements CertificateProvider. +func (f FileCAPool) Certificates() []*x509.Certificate { + return f.certs +} + // PKIRootCAPool extracts the trusted root certificates from Caddy's native 'pki' app type PKIRootCAPool struct { // List of the Authority names that are configured in the `pki` app whose root certificates are trusted Authority []string `json:"authority,omitempty"` - ca []*caddypki.CA - pool *x509.CertPool + ca []*caddypki.CA + pool *x509.CertPool + certs []*x509.Certificate } // CaddyModule implements caddy.Module. @@ -201,10 +244,17 @@ func (p *PKIRootCAPool) Provision(ctx caddy.Context) error { } caPool := x509.NewCertPool() + var certs []*x509.Certificate for _, ca := range p.ca { - caPool.AddCert(ca.RootCertificate()) + rootCert := ca.RootCertificate() + if rootCert == nil { + return fmt.Errorf("CA %s has no root certificate", ca.ID) + } + caPool.AddCert(rootCert) + certs = append(certs, rootCert) } p.pool = caPool + p.certs = certs return nil } @@ -238,13 +288,19 @@ func (p PKIRootCAPool) CertPool() *x509.CertPool { return p.pool } +// Certificates implements CertificateProvider. +func (p PKIRootCAPool) Certificates() []*x509.Certificate { + return p.certs +} + // PKIIntermediateCAPool extracts the trusted intermediate certificates from Caddy's native 'pki' app type PKIIntermediateCAPool struct { // List of the Authority names that are configured in the `pki` app whose intermediate certificates are trusted Authority []string `json:"authority,omitempty"` - ca []*caddypki.CA - pool *x509.CertPool + ca []*caddypki.CA + pool *x509.CertPool + certs []*x509.Certificate } // CaddyModule implements caddy.Module. @@ -257,7 +313,7 @@ func (PKIIntermediateCAPool) CaddyModule() caddy.ModuleInfo { } } -// Loads the PKI app and load the intermediate certificates into the certificate pool +// Loads the PKI app and loads the intermediate certificates into the certificate pool func (p *PKIIntermediateCAPool) Provision(ctx caddy.Context) error { pkiApp, err := ctx.AppIfConfigured("pki") if err != nil { @@ -273,10 +329,18 @@ func (p *PKIIntermediateCAPool) Provision(ctx caddy.Context) error { } caPool := x509.NewCertPool() + var certs []*x509.Certificate for _, ca := range p.ca { - caPool.AddCert(ca.IntermediateCertificate()) + for _, c := range ca.IntermediateCertificateChain() { + if c == nil { + return fmt.Errorf("CA %s has a nil certificate in its intermediate chain", ca.ID) + } + caPool.AddCert(c) + certs = append(certs, c) + } } p.pool = caPool + p.certs = certs return nil } @@ -309,6 +373,11 @@ func (p PKIIntermediateCAPool) CertPool() *x509.CertPool { return p.pool } +// Certificates implements CertificateProvider. +func (p PKIIntermediateCAPool) Certificates() []*x509.Certificate { + return p.certs +} + // StoragePool extracts the trusted certificates root from Caddy storage type StoragePool struct { // The storage module where the trusted root certificates are stored. Absent @@ -320,6 +389,7 @@ type StoragePool struct { storage certmagic.Storage pool *x509.CertPool + certs []*x509.Certificate } // CaddyModule implements caddy.Module. @@ -352,16 +422,33 @@ func (ca *StoragePool) Provision(ctx caddy.Context) error { return fmt.Errorf("no PEM keys specified") } caPool := x509.NewCertPool() + var certs []*x509.Certificate for _, caID := range ca.PEMKeys { bs, err := ca.storage.Load(ctx, caID) if err != nil { return fmt.Errorf("error loading cert '%s' from storage: %s", caID, err) } - if !caPool.AppendCertsFromPEM(bs) { - return fmt.Errorf("failed to add certificate '%s' to pool", caID) + // Parse PEM to extract certificates + pemData := bs + for len(pemData) > 0 { + var block *pem.Block + block, pemData = pem.Decode(pemData) + if block == nil { + break + } + if block.Type != "CERTIFICATE" { + continue + } + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return fmt.Errorf("parsing certificate '%s': %v", caID, err) + } + caPool.AddCert(cert) + certs = append(certs, cert) } } ca.pool = caPool + ca.certs = certs return nil } @@ -411,9 +498,13 @@ func (p StoragePool) CertPool() *x509.CertPool { return p.pool } +// Certificates implements CertificateProvider. +func (p StoragePool) Certificates() []*x509.Certificate { + return p.certs +} + // TLSConfig holds configuration related to the TLS configuration for the // transport/client. -// copied from with minor modifications: modules/caddyhttp/reverseproxy/httptransport.go type TLSConfig struct { // Provides the guest module that provides the trusted certificate authority (CA) certificates CARaw json.RawMessage `json:"ca,omitempty" caddy:"namespace=tls.ca_pool.source inline_key=provider"` @@ -498,10 +589,9 @@ func (t *TLSConfig) unmarshalCaddyfile(d *caddyfile.Dispenser) error { // MakeTLSClientConfig returns a tls.Config usable by a client to a backend. // If there is no custom TLS configuration, a nil config may be returned. -// copied from with minor modifications: modules/caddyhttp/reverseproxy/httptransport.go func (t *TLSConfig) makeTLSClientConfig(ctx caddy.Context) (*tls.Config, error) { - repl := ctx.Value(caddy.ReplacerCtxKey).(*caddy.Replacer) - if repl == nil { + repl, ok := ctx.Value(caddy.ReplacerCtxKey).(*caddy.Replacer) + if !ok || repl == nil { repl = caddy.NewReplacer() } cfg := new(tls.Config) @@ -552,7 +642,8 @@ type HTTPCertPool struct { // Customize the TLS connection knobs to used during the HTTP call TLS *TLSConfig `json:"tls,omitempty"` - pool *x509.CertPool + pool *x509.CertPool + certs []*x509.Certificate } // CaddyModule implements caddy.Module. @@ -568,6 +659,7 @@ func (HTTPCertPool) CaddyModule() caddy.ModuleInfo { // Provision implements caddy.Provisioner. func (hcp *HTTPCertPool) Provision(ctx caddy.Context) error { caPool := x509.NewCertPool() + var certs []*x509.Certificate customTransport := http.DefaultTransport.(*http.Transport).Clone() if hcp.TLS != nil { @@ -586,7 +678,7 @@ func (hcp *HTTPCertPool) Provision(ctx caddy.Context) error { if err != nil { return err } - res, err := httpClient.Do(req) + res, err := httpClient.Do(req) //nolint:gosec // SSRF false positive... uri comes from config if err != nil { return err } @@ -595,11 +687,30 @@ func (hcp *HTTPCertPool) Provision(ctx caddy.Context) error { if err != nil { return err } - if !caPool.AppendCertsFromPEM(pembs) { - return fmt.Errorf("failed to add certs from URL: %s", uri) + if res.StatusCode < 200 || res.StatusCode >= 300 { + return fmt.Errorf("HTTP %d fetching CA certificate bundle from %s", res.StatusCode, uri) + } + // Parse PEM to extract certificates + pemData := pembs + for len(pemData) > 0 { + var block *pem.Block + block, pemData = pem.Decode(pemData) + if block == nil { + break + } + if block.Type != "CERTIFICATE" { + continue + } + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return fmt.Errorf("parsing certificate from URL %s: %v", uri, err) + } + caPool.AddCert(cert) + certs = append(certs, cert) } } hcp.pool = caPool + hcp.certs = certs return nil } @@ -663,6 +774,179 @@ func (hcp HTTPCertPool) CertPool() *x509.CertPool { return hcp.pool } +// Certificates implements CertificateProvider. +func (hcp HTTPCertPool) Certificates() []*x509.Certificate { + return hcp.certs +} + +// SystemCAPool obtains the trusted root certificates from the system's +// certificate pool using x509.SystemCertPool() +type SystemCAPool struct { + pool *x509.CertPool +} + +// CaddyModule implements caddy.Module. +func (SystemCAPool) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + ID: "tls.ca_pool.source.system", + New: func() caddy.Module { + return new(SystemCAPool) + }, + } +} + +// Provision implements caddy.Provisioner. +func (scp *SystemCAPool) Provision(ctx caddy.Context) error { + pool, err := x509.SystemCertPool() + if err != nil { + return fmt.Errorf("failed to load system cert pool: %v", err) + } + scp.pool = pool + return nil +} + +func (scp *SystemCAPool) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { + d.Next() // consume module name + if d.CountRemainingArgs() > 0 { + return d.ArgErr() + } + if d.NextBlock(0) { + return d.Err("system trust pool does not support any configuration") + } + return nil +} + +// CertPool implements CA. +func (scp SystemCAPool) CertPool() *x509.CertPool { + return scp.pool +} + +// The `combined` pool type merges multiple pools. The `sources` pools must implement the +// `CertificateProvider` interface, which allows them to export their certificate set. +// +// Note: SystemCAPool does not implement CertificateProvider because +// x509.SystemCertPool() doesn't expose its certificates, so it cannot +// be used as a source in CombinedCAPool. +type CombinedCAPool struct { + // The CA pool sources to combine. Each source is a CA pool provider module. + SourcesRaw []json.RawMessage `json:"sources,omitempty" caddy:"namespace=tls.ca_pool.source inline_key=provider"` + + sources []CA + pool *x509.CertPool + certs []*x509.Certificate +} + +// CaddyModule implements caddy.Module. +func (CombinedCAPool) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + ID: "tls.ca_pool.source.combined", + New: func() caddy.Module { + return new(CombinedCAPool) + }, + } +} + +// Provision implements caddy.Provisioner. +func (ccp *CombinedCAPool) Provision(ctx caddy.Context) error { + if len(ccp.SourcesRaw) == 0 { + return fmt.Errorf("no sources specified for combined CA pool") + } + + // Load all source modules + sources, err := ctx.LoadModule(ccp, "SourcesRaw") + if err != nil { + return fmt.Errorf("loading CA pool sources: %v", err) + } + + caPool := x509.NewCertPool() + var allCerts []*x509.Certificate + + for _, src := range sources.([]any) { + ca, ok := src.(CA) + if !ok { + return fmt.Errorf("source module is not a CA pool provider") + } + ccp.sources = append(ccp.sources, ca) + + certProvider, ok := ca.(CertificateProvider) + if !ok { + return fmt.Errorf("source %T does not implement CertificateProvider (required for combining)", ca) + } + + certs := certProvider.Certificates() + if certs == nil { + return fmt.Errorf("source %T returned nil certificates", ca) + } + for _, cert := range certs { + if cert == nil { + return fmt.Errorf("source %T returned a nil certificate", ca) + } + caPool.AddCert(cert) + allCerts = append(allCerts, cert) + } + } + + ccp.pool = caPool + ccp.certs = allCerts + + return nil +} + +// Syntax: +// +// trust_pool combined { +// source { +// +// } +// } +// +// The 'source' directive can be specified multiple times. Sources that +// don't implement CertificateProvider (like 'system') cannot be combined. +func (ccp *CombinedCAPool) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { + d.Next() // consume module name + if d.CountRemainingArgs() > 0 { + return d.ArgErr() + } + + for nesting := d.Nesting(); d.NextBlock(nesting); { + switch d.Val() { + case "source": + if !d.NextArg() { + return d.ArgErr() + } + modStem := d.Val() + modID := "tls.ca_pool.source." + modStem + unm, err := caddyfile.UnmarshalModule(d, modID) + if err != nil { + return err + } + ca, ok := unm.(CA) + if !ok { + return d.Errf("module %s is not a CA pool provider", modID) + } + ccp.SourcesRaw = append(ccp.SourcesRaw, caddyconfig.JSONModuleObject(ca, "provider", modStem, nil)) + default: + return d.Errf("unrecognized directive: %s", d.Val()) + } + } + + if len(ccp.SourcesRaw) == 0 { + return d.Err("no sources specified") + } + + return nil +} + +// CertPool implements CA. +func (ccp CombinedCAPool) CertPool() *x509.CertPool { + return ccp.pool +} + +// Certificates implements CertificateProvider. +func (ccp CombinedCAPool) Certificates() []*x509.Certificate { + return ccp.certs +} + var ( _ caddy.Module = (*InlineCAPool)(nil) _ caddy.Provisioner = (*InlineCAPool)(nil) @@ -694,4 +978,14 @@ var ( _ caddy.Validator = (*HTTPCertPool)(nil) _ CA = (*HTTPCertPool)(nil) _ caddyfile.Unmarshaler = (*HTTPCertPool)(nil) + + _ caddy.Module = (*SystemCAPool)(nil) + _ caddy.Provisioner = (*SystemCAPool)(nil) + _ CA = (*SystemCAPool)(nil) + _ caddyfile.Unmarshaler = (*SystemCAPool)(nil) + + _ caddy.Module = (*CombinedCAPool)(nil) + _ caddy.Provisioner = (*CombinedCAPool)(nil) + _ CA = (*CombinedCAPool)(nil) + _ caddyfile.Unmarshaler = (*CombinedCAPool)(nil) ) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/certmanagers.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/certmanagers.go index 7bc4c2c84..68014635e 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/certmanagers.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/certmanagers.go @@ -144,9 +144,9 @@ func (hcg HTTPCertGetter) GetCertificate(ctx context.Context, hello *tls.ClientH qs.Set("server_name", hello.ServerName) qs.Set("signature_schemes", strings.Join(sigs, ",")) qs.Set("cipher_suites", strings.Join(suites, ",")) - remoteIP, _, err := net.SplitHostPort(hello.Conn.RemoteAddr().String()) - if err == nil && remoteIP != "" { - qs.Set("remote_ip", remoteIP) + localIP, _, err := net.SplitHostPort(hello.Conn.LocalAddr().String()) + if err == nil && localIP != "" { + qs.Set("local_ip", localIP) } parsed.RawQuery = qs.Encode() @@ -155,7 +155,7 @@ func (hcg HTTPCertGetter) GetCertificate(ctx context.Context, hello *tls.ClientH return nil, err } - resp, err := http.DefaultClient.Do(req) + resp, err := http.DefaultClient.Do(req) //nolint:gosec // SSRF false positive... request URI comes from config if err != nil { return nil, err } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/certselection.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/certselection.go index a561e3a1d..ac210d3b6 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/certselection.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/certselection.go @@ -87,13 +87,7 @@ nextChoice: } if len(p.AnyTag) > 0 { - var found bool - for _, tag := range p.AnyTag { - if cert.HasTag(tag) { - found = true - break - } - } + found := slices.ContainsFunc(p.AnyTag, cert.HasTag) if !found { continue } diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/connpolicy.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/connpolicy.go index 7c8436bc9..9597af359 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/connpolicy.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/connpolicy.go @@ -25,6 +25,7 @@ import ( "io" "os" "reflect" + "slices" "strings" "github.com/mholt/acmez/v3" @@ -152,9 +153,9 @@ func (cp ConnectionPolicies) TLSConfig(ctx caddy.Context) *tls.Config { // in its config (remember, TLS connection policies are used by *other* apps to // run TLS servers) -- we skip names with placeholders if tlsApp.EncryptedClientHello.Publication == nil { - var echNames []string repl := caddy.NewReplacer() for _, p := range cp { + var echNames []string for _, m := range p.matchers { if sni, ok := m.(MatchServerName); ok { for _, name := range sni { @@ -163,25 +164,15 @@ func (cp ConnectionPolicies) TLSConfig(ctx caddy.Context) *tls.Config { } } } + tlsApp.RegisterServerNames(echNames, p.ALPN) } - tlsApp.RegisterServerNames(echNames) } - // TODO: Ideally, ECH keys should be rotated. However, as of Go 1.24, the std lib implementation - // does not support safely modifying the tls.Config's EncryptedClientHelloKeys field. - // So, we implement static ECH keys temporarily. See https://github.com/golang/go/issues/71920. - // Revisit this after Go 1.25 is released and implement key rotation. - var stdECHKeys []tls.EncryptedClientHelloKey - for _, echConfigs := range tlsApp.EncryptedClientHello.configs { - for _, c := range echConfigs { - stdECHKeys = append(stdECHKeys, tls.EncryptedClientHelloKey{ - Config: c.configBin, - PrivateKey: c.privKeyBin, - SendAsRetry: c.sendAsRetry, - }) - } + tlsCfg.GetEncryptedClientHelloKeys = func(chi *tls.ClientHelloInfo) ([]tls.EncryptedClientHelloKey, error) { + tlsApp.EncryptedClientHello.configsMu.RLock() + defer tlsApp.EncryptedClientHello.configsMu.RUnlock() + return tlsApp.EncryptedClientHello.stdlibReady, nil } - tlsCfg.EncryptedClientHelloKeys = stdECHKeys } } @@ -369,13 +360,7 @@ func (p *ConnectionPolicy) buildStandardTLSConfig(ctx caddy.Context) error { } // ensure ALPN includes the ACME TLS-ALPN protocol - var alpnFound bool - for _, a := range p.ALPN { - if a == acmez.ACMETLS1Protocol { - alpnFound = true - break - } - } + alpnFound := slices.Contains(p.ALPN, acmez.ACMETLS1Protocol) if !alpnFound && (cfg.NextProtos == nil || len(cfg.NextProtos) > 0) { cfg.NextProtos = append(cfg.NextProtos, acmez.ACMETLS1Protocol) } @@ -462,7 +447,7 @@ func (p ConnectionPolicy) SettingsEmpty() bool { p.InsecureSecretsLog == "" } -// SettingsEmpty returns true if p's settings (fields +// SettingsEqual returns true if p's settings (fields // except the matchers) are the same as q. func (p ConnectionPolicy) SettingsEqual(q ConnectionPolicy) bool { p.MatchersRaw = nil @@ -799,7 +784,7 @@ func (clientauth *ClientAuthentication) provision(ctx caddy.Context) error { for _, fpath := range clientauth.TrustedCACertPEMFiles { ders, err := convertPEMFilesToDER(fpath) if err != nil { - return nil + return err } clientauth.TrustedCACerts = append(clientauth.TrustedCACerts, ders...) } @@ -812,7 +797,7 @@ func (clientauth *ClientAuthentication) provision(ctx caddy.Context) error { } err := caPool.Provision(ctx) if err != nil { - return nil + return err } clientauth.ca = caPool } @@ -900,24 +885,29 @@ func (clientauth *ClientAuthentication) ConfigureTLSConfig(cfg *tls.Config) erro // if a custom verification function already exists, wrap it clientauth.existingVerifyPeerCert = cfg.VerifyPeerCertificate - cfg.VerifyPeerCertificate = clientauth.verifyPeerCertificate + cfg.VerifyConnection = clientauth.verifyConnection return nil } -// verifyPeerCertificate is for use as a tls.Config.VerifyPeerCertificate -// callback to do custom client certificate verification. It is intended -// for installation only by clientauth.ConfigureTLSConfig(). -func (clientauth *ClientAuthentication) verifyPeerCertificate(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { +// verifyConnection is for use as a tls.Config.VerifyConnection callback +// to do custom client certificate verification. It is intended for +// installation only by clientauth.ConfigureTLSConfig(). +// +// Unlike VerifyPeerCertificate, VerifyConnection is called on every +// connection including resumed sessions, preventing session-resumption bypass. +func (clientauth *ClientAuthentication) verifyConnection(cs tls.ConnectionState) error { // first use any pre-existing custom verification function if clientauth.existingVerifyPeerCert != nil { - err := clientauth.existingVerifyPeerCert(rawCerts, verifiedChains) - if err != nil { + rawCerts := make([][]byte, len(cs.PeerCertificates)) + for i, cert := range cs.PeerCertificates { + rawCerts[i] = cert.Raw + } + if err := clientauth.existingVerifyPeerCert(rawCerts, cs.VerifiedChains); err != nil { return err } } for _, verifier := range clientauth.verifiers { - err := verifier.VerifyClientCertificate(rawCerts, verifiedChains) - if err != nil { + if err := verifier.VerifyClientCertificate(nil, cs.VerifiedChains); err != nil { return err } } @@ -994,6 +984,48 @@ func (l *LeafCertClientAuth) Provision(ctx caddy.Context) error { return nil } +// UnmarshalCaddyfile implements caddyfile.Unmarshaler. +func (l *LeafCertClientAuth) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { + d.NextArg() + + // accommodate the use of one-liners + if d.CountRemainingArgs() > 1 { + d.NextArg() + modName := d.Val() + mod, err := caddyfile.UnmarshalModule(d, "tls.leaf_cert_loader."+modName) + if err != nil { + return d.WrapErr(err) + } + vMod, ok := mod.(LeafCertificateLoader) + if !ok { + return fmt.Errorf("leaf module '%s' is not a leaf certificate loader", vMod) + } + l.LeafCertificateLoadersRaw = append( + l.LeafCertificateLoadersRaw, + caddyconfig.JSONModuleObject(vMod, "loader", modName, nil), + ) + return nil + } + + // accommodate the use of nested blocks + for nesting := d.Nesting(); d.NextBlock(nesting); { + modName := d.Val() + mod, err := caddyfile.UnmarshalModule(d, "tls.leaf_cert_loader."+modName) + if err != nil { + return d.WrapErr(err) + } + vMod, ok := mod.(LeafCertificateLoader) + if !ok { + return fmt.Errorf("leaf module '%s' is not a leaf certificate loader", vMod) + } + l.LeafCertificateLoadersRaw = append( + l.LeafCertificateLoadersRaw, + caddyconfig.JSONModuleObject(vMod, "loader", modName, nil), + ) + } + return nil +} + func (l LeafCertClientAuth) VerifyClientCertificate(rawCerts [][]byte, _ [][]*x509.Certificate) error { if len(rawCerts) == 0 { return fmt.Errorf("no client certificate provided") @@ -1004,10 +1036,8 @@ func (l LeafCertClientAuth) VerifyClientCertificate(rawCerts [][]byte, _ [][]*x5 return fmt.Errorf("can't parse the given certificate: %s", err.Error()) } - for _, trustedLeafCert := range l.trustedLeafCerts { - if remoteLeafCert.Equal(trustedLeafCert) { - return nil - } + if slices.ContainsFunc(l.trustedLeafCerts, remoteLeafCert.Equal) { + return nil } return fmt.Errorf("client leaf certificate failed validation") @@ -1057,6 +1087,7 @@ var secretsLogPool = caddy.NewUsagePool() var ( _ caddyfile.Unmarshaler = (*ClientAuthentication)(nil) _ caddyfile.Unmarshaler = (*ConnectionPolicy)(nil) + _ caddyfile.Unmarshaler = (*LeafCertClientAuth)(nil) ) // ParseCaddyfileNestedMatcherSet parses the Caddyfile tokens for a nested diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/ech.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/ech.go index 7329bf1f2..4a48769d8 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/ech.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/ech.go @@ -2,6 +2,7 @@ package caddytls import ( "context" + "crypto/tls" "encoding/base64" "encoding/json" "errors" @@ -11,6 +12,7 @@ import ( "path" "strconv" "strings" + "sync" "time" "github.com/caddyserver/certmagic" @@ -48,12 +50,6 @@ func init() { // applied will automatically upgrade the minimum TLS version to 1.3, even if // configured to a lower version. // -// Note that, as of Caddy 2.10.0 (~March 2025), ECH keys are not automatically -// rotated due to a limitation in the Go standard library (see -// https://github.com/golang/go/issues/71920). This should be resolved when -// Go 1.25 is released (~Aug. 2025), and Caddy will be updated to automatically -// rotate ECH keys/configs at that point. -// // EXPERIMENTAL: Subject to change. type ECH struct { // The list of ECH configurations for which to automatically generate @@ -73,14 +69,17 @@ type ECH struct { // DNS RRs. (This also typically requires that they use DoH or DoT.) Publication []*ECHPublication `json:"publication,omitempty"` - // map of public_name to list of configs - configs map[string][]echConfig + configsMu *sync.RWMutex // protects both configs and the list of configs/keys the standard library uses + configs map[string][]echConfig // map of public_name to list of configs + stdlibReady []tls.EncryptedClientHelloKey // ECH configs+keys in a format the standard library can use } // Provision loads or creates ECH configs and returns outer names (for certificate // management), but does not publish any ECH configs. The DNS module is used as // a default for later publishing if needed. func (ech *ECH) Provision(ctx caddy.Context) ([]string, error) { + ech.configsMu = new(sync.RWMutex) + logger := ctx.Logger().Named("ech") // set up publication modules before we need to obtain a lock in storage, @@ -98,17 +97,60 @@ func (ech *ECH) Provision(ctx caddy.Context) ([]string, error) { // the rest of provisioning needs an exclusive lock so that instances aren't // stepping on each other when setting up ECH configs storage := ctx.Storage() - const echLockName = "ech_provision" - if err := storage.Lock(ctx, echLockName); err != nil { + if err := storage.Lock(ctx, echStorageLockName); err != nil { return nil, err } defer func() { - if err := storage.Unlock(ctx, echLockName); err != nil { + if err := storage.Unlock(ctx, echStorageLockName); err != nil { logger.Error("unable to unlock ECH provisioning in storage", zap.Error(err)) } }() - var outerNames []string //nolint:prealloc // (FALSE POSITIVE - see https://github.com/alexkohler/prealloc/issues/30) + ech.configsMu.Lock() + defer ech.configsMu.Unlock() + + outerNames, err := ech.setConfigsFromStorage(ctx, logger) + if err != nil { + return nil, fmt.Errorf("loading configs from storage: %w", err) + } + + // see if we need to make any new ones based on the input configuration + for _, cfg := range ech.Configs { + publicName := strings.ToLower(strings.TrimSpace(cfg.PublicName)) + + if list, ok := ech.configs[publicName]; !ok || len(list) == 0 { + // no config with this public name was loaded, so create one + echCfg, err := generateAndStoreECHConfig(ctx, publicName) + if err != nil { + return nil, err + } + logger.Debug("generated new ECH config", + zap.String("public_name", echCfg.RawPublicName), + zap.Uint8("id", echCfg.ConfigID)) + ech.configs[publicName] = append(ech.configs[publicName], echCfg) + outerNames = append(outerNames, publicName) + } + } + + // convert the configs into a structure ready for the std lib to use + ech.updateKeyList() + + // ensure any old keys are rotated out + if err = ech.rotateECHKeys(ctx, logger, true); err != nil { + return nil, fmt.Errorf("rotating ECH configs: %w", err) + } + + return outerNames, nil +} + +// setConfigsFromStorage sets the ECH configs in memory to those in storage. +// It must be called in a write lock on ech.configsMu. +func (ech *ECH) setConfigsFromStorage(ctx caddy.Context, logger *zap.Logger) ([]string, error) { + storage := ctx.Storage() + + ech.configs = make(map[string][]echConfig) + + var outerNames []string // start by loading all the existing configs (even the older ones on the way out, // since some clients may still be using them if they haven't yet picked up on the @@ -131,48 +173,145 @@ func (ech *ECH) Provision(ctx caddy.Context) ([]string, error) { logger.Debug("loaded ECH config", zap.String("public_name", cfg.RawPublicName), zap.Uint8("id", cfg.ConfigID)) + if _, seen := ech.configs[cfg.RawPublicName]; !seen { + outerNames = append(outerNames, cfg.RawPublicName) + } ech.configs[cfg.RawPublicName] = append(ech.configs[cfg.RawPublicName], cfg) - outerNames = append(outerNames, cfg.RawPublicName) } - // all existing configs are now loaded; see if we need to make any new ones - // based on the input configuration, and also mark the most recent one(s) as - // current/active, so they can be used for ECH retries - for _, cfg := range ech.Configs { - publicName := strings.ToLower(strings.TrimSpace(cfg.PublicName)) + return outerNames, nil +} - if list, ok := ech.configs[publicName]; ok && len(list) > 0 { - // at least one config with this public name was loaded, so find the - // most recent one and mark it as active to be used with retries - var mostRecentDate time.Time - var mostRecentIdx int - for i, c := range list { - if mostRecentDate.IsZero() || c.meta.Created.After(mostRecentDate) { - mostRecentDate = c.meta.Created - mostRecentIdx = i - } +// rotateECHKeys updates the ECH keys/configs that are outdated if rotation is needed. +// It should be called in a write lock on ech.configsMu. If a lock is already obtained +// in storage, then pass true for storageSynced. +// +// This function sets/updates the stdlib-ready key list only if a rotation occurs. +func (ech *ECH) rotateECHKeys(ctx caddy.Context, logger *zap.Logger, storageSynced bool) error { + storage := ctx.Storage() + + // all existing configs are now loaded; rotate keys "regularly" as recommended by the spec + // (also: "Rotating too frequently limits the client anonymity set." - but the more server + // names, the more frequently rotation can be done safely) + const ( + rotationInterval = 24 * time.Hour * 30 + deleteAfter = 24 * time.Hour * 90 + ) + + if !ech.rotationNeeded(rotationInterval, deleteAfter) { + return nil + } + + // sync this operation across cluster if not already + if !storageSynced { + if err := storage.Lock(ctx, echStorageLockName); err != nil { + return err + } + defer func() { + if err := storage.Unlock(ctx, echStorageLockName); err != nil { + logger.Error("unable to unlock ECH rotation in storage", zap.Error(err)) } - list[mostRecentIdx].sendAsRetry = true - } else { - // no config with this public name was loaded, so create one - echCfg, err := generateAndStoreECHConfig(ctx, publicName) - if err != nil { - return nil, err + }() + } + + // update what storage has, in case another instance already updated things + if _, err := ech.setConfigsFromStorage(ctx, logger); err != nil { + return fmt.Errorf("updating ECH keys from storage: %v", err) + } + + // iterate the updated list and do any updates as needed + for publicName := range ech.configs { + for i := 0; i < len(ech.configs[publicName]); i++ { + cfg := ech.configs[publicName][i] + if time.Since(cfg.meta.Created) >= rotationInterval && cfg.meta.Replaced.IsZero() { + // key is due for rotation and it hasn't been replaced yet; do that now + logger.Debug("ECH config is due for rotation", + zap.String("public_name", cfg.RawPublicName), + zap.Uint8("id", cfg.ConfigID), + zap.Time("created", cfg.meta.Created), + zap.Duration("age", time.Since(cfg.meta.Created)), + zap.Duration("rotation_interval", rotationInterval)) + + // start by generating and storing the replacement ECH config + newCfg, err := generateAndStoreECHConfig(ctx, publicName) + if err != nil { + return fmt.Errorf("generating and storing new replacement ECH config: %w", err) + } + + // mark the key as replaced so we don't rotate it again, and instead delete it later + ech.configs[publicName][i].meta.Replaced = time.Now() + + // persist the updated metadata + metaBytes, err := json.Marshal(ech.configs[publicName][i].meta) + if err != nil { + return fmt.Errorf("marshaling updated ECH config metadata: %v", err) + } + if err := storage.Store(ctx, echMetaKey(cfg.ConfigID), metaBytes); err != nil { + return fmt.Errorf("storing updated ECH config metadata: %v", err) + } + + ech.configs[publicName] = append(ech.configs[publicName], newCfg) + + logger.Debug("rotated ECH key", + zap.String("public_name", cfg.RawPublicName), + zap.Uint8("old_id", cfg.ConfigID), + zap.Uint8("new_id", newCfg.ConfigID)) + } else if time.Since(cfg.meta.Created) >= deleteAfter && !cfg.meta.Replaced.IsZero() { + // key has expired and is no longer supported; delete it from storage and memory + cfgIDKey := path.Join(echConfigsKey, strconv.Itoa(int(cfg.ConfigID))) + if err := storage.Delete(ctx, cfgIDKey); err != nil { + return fmt.Errorf("deleting expired ECH config: %v", err) + } + + ech.configs[publicName] = append(ech.configs[publicName][:i], ech.configs[publicName][i+1:]...) + i-- + + logger.Debug("deleted expired ECH key", + zap.String("public_name", cfg.RawPublicName), + zap.Uint8("id", cfg.ConfigID), + zap.Duration("age", time.Since(cfg.meta.Created))) } - logger.Debug("generated new ECH config", - zap.String("public_name", echCfg.RawPublicName), - zap.Uint8("id", echCfg.ConfigID)) - ech.configs[publicName] = append(ech.configs[publicName], echCfg) - outerNames = append(outerNames, publicName) } } - return outerNames, nil + ech.updateKeyList() + + return nil +} + +// rotationNeeded returns true if any ECH key needs to be replaced, or deleted. +// It must be called inside a read or write lock of ech.configsMu (probably a +// write lock, so that the rotation can occur correctly in the same lock).) +func (ech *ECH) rotationNeeded(rotationInterval, deleteAfter time.Duration) bool { + for publicName := range ech.configs { + for i := 0; i < len(ech.configs[publicName]); i++ { + cfg := ech.configs[publicName][i] + if (time.Since(cfg.meta.Created) >= rotationInterval && cfg.meta.Replaced.IsZero()) || + (time.Since(cfg.meta.Created) >= deleteAfter && !cfg.meta.Replaced.IsZero()) { + return true + } + } + } + return false } -func (t *TLS) publishECHConfigs() error { - logger := t.logger.Named("ech") +// updateKeyList updates the list of ECH keys the std lib uses to serve ECH. +// It must be called inside a write lock on ech.configsMu. +func (ech *ECH) updateKeyList() { + ech.stdlibReady = []tls.EncryptedClientHelloKey{} + for _, cfgs := range ech.configs { + for _, cfg := range cfgs { + ech.stdlibReady = append(ech.stdlibReady, tls.EncryptedClientHelloKey{ + Config: cfg.configBin, + PrivateKey: cfg.privKeyBin, + SendAsRetry: cfg.meta.Replaced.IsZero(), // only send during retries if key has not been rotated out + }) + } + } +} +// publishECHConfigs publishes any configs that are configured for publication and which haven't been published already. +func (t *TLS) publishECHConfigs(logger *zap.Logger) error { // make publication exclusive, since we don't need to repeat this unnecessarily storage := t.ctx.Storage() const echLockName = "ech_publish" @@ -197,7 +336,7 @@ func (t *TLS) publishECHConfigs() error { publishers: []ECHPublisher{ &ECHDNSPublisher{ provider: dnsProv, - logger: t.logger, + logger: logger, }, }, }, @@ -209,6 +348,7 @@ func (t *TLS) publishECHConfigs() error { // publish with it, and figure out which inner names to publish // to/for, then publish for _, publication := range publicationList { + t.EncryptedClientHello.configsMu.RLock() // this publication is either configured for specific ECH configs, // or we just use an implied default of all ECH configs var echCfgList echConfigList @@ -231,6 +371,7 @@ func (t *TLS) publishECHConfigs() error { } } } + t.EncryptedClientHello.configsMu.RUnlock() // marshal the ECH config list as binary for publication echCfgListBin, err := echCfgList.MarshalBinary() @@ -250,6 +391,10 @@ func (t *TLS) publishECHConfigs() error { if publication.Domains == nil { serverNamesSet = make(map[string]struct{}, len(t.serverNames)) for name := range t.serverNames { + // skip Tailscale names, a special case we also handle differently in our auto-HTTPS + if strings.HasSuffix(name, ".ts.net") { + continue + } serverNamesSet[name] = struct{}{} } } else { @@ -291,18 +436,58 @@ func (t *TLS) publishECHConfigs() error { } logger.Debug("publishing ECH config list", + zap.String("publisher", publisherKey), zap.Strings("domains", dnsNamesToPublish), zap.Uint8s("config_ids", configIDs)) + if dnsPublisher, ok := publisher.(*ECHDNSPublisher); ok { + dnsPublisher.alpnByDomain = t.alpnValuesForServerNames(dnsNamesToPublish) + } + // publish this ECH config list with this publisher pubTime := time.Now() err := publisher.PublishECHConfigList(t.ctx, dnsNamesToPublish, echCfgListBin) - if err == nil { - t.logger.Info("published ECH configuration list", + + var publishErrs PublishECHConfigListErrors + if errors.As(err, &publishErrs) { + // at least a partial failure, maybe a complete failure, but we can + // log each error by domain + for innerName, domainErr := range publishErrs { + logger.Error("failed to publish ECH configuration list", + zap.String("publisher", publisherKey), + zap.String("domain", innerName), + zap.Uint8s("config_ids", configIDs), + zap.Error(domainErr)) + } + } else if err != nil { + // generic error; assume the entire thing failed, I guess + logger.Error("failed publishing ECH configuration list", + zap.String("publisher", publisherKey), zap.Strings("domains", dnsNamesToPublish), zap.Uint8s("config_ids", configIDs), zap.Error(err)) - // update publication history, so that we don't unnecessarily republish every time + } + + if err == nil || (len(publishErrs) > 0 && len(publishErrs) < len(dnsNamesToPublish)) { + // if publication for at least some domains succeeded, we should update our publication + // state for those domains to avoid unnecessarily republishing every time + someAll := "all" + if len(publishErrs) > 0 { + someAll = "some" + } + // make a list of names that published successfully with this publisher + // so that we update only their state in storage, not the failed ones + var successNames []string + for _, name := range dnsNamesToPublish { + if _, ok := publishErrs[name]; !ok { + successNames = append(successNames, name) + } + } + logger.Info("successfully published ECH configuration list for "+someAll+" domains", + zap.String("publisher", publisherKey), + zap.Strings("domains", successNames), + zap.Uint8s("config_ids", configIDs)) + for _, cfg := range echCfgList { if cfg.meta.Publications == nil { cfg.meta.Publications = make(publicationHistory) @@ -310,23 +495,22 @@ func (t *TLS) publishECHConfigs() error { if _, ok := cfg.meta.Publications[publisherKey]; !ok { cfg.meta.Publications[publisherKey] = make(map[string]time.Time) } - for _, name := range dnsNamesToPublish { + for _, name := range successNames { cfg.meta.Publications[publisherKey][name] = pubTime } metaBytes, err := json.Marshal(cfg.meta) if err != nil { return fmt.Errorf("marshaling ECH config metadata: %v", err) } - metaKey := path.Join(echConfigsKey, strconv.Itoa(int(cfg.ConfigID)), "meta.json") - if err := t.ctx.Storage().Store(t.ctx, metaKey, metaBytes); err != nil { + if err := t.ctx.Storage().Store(t.ctx, echMetaKey(cfg.ConfigID), metaBytes); err != nil { return fmt.Errorf("storing updated ECH config metadata: %v", err) } } } else { - t.logger.Error("publishing ECH configuration list", - zap.Strings("domains", publication.Domains), - zap.Uint8s("config_ids", configIDs), - zap.Error(err)) + logger.Error("all domains failed to publish ECH configuration list (see earlier errors)", + zap.String("publisher", publisherKey), + zap.Strings("domains", dnsNamesToPublish), + zap.Uint8s("config_ids", configIDs)) } } } @@ -453,7 +637,7 @@ func generateAndStoreECHConfig(ctx caddy.Context, publicName string) (echConfig, echCfg := echConfig{ PublicKey: publicKey, - Version: draftTLSESNI22, + Version: draftTLSESNI25, ConfigID: configID, RawPublicName: publicName, KEMID: kemChoice, @@ -471,7 +655,6 @@ func generateAndStoreECHConfig(ctx caddy.Context, publicName string) (echConfig, AEADID: hpke.AEAD_ChaCha20Poly1305, }, }, - sendAsRetry: true, } meta := echConfigMeta{ Created: time.Now(), @@ -597,7 +780,8 @@ type ECHDNSPublisher struct { ProviderRaw json.RawMessage `json:"provider,omitempty" caddy:"namespace=dns.providers inline_key=name"` provider ECHDNSProvider - logger *zap.Logger + alpnByDomain map[string][]string + logger *zap.Logger } // CaddyModule returns the Caddy module information. @@ -631,17 +815,19 @@ func (dnsPub ECHDNSPublisher) PublisherKey() string { return string(dnsPub.provider.(caddy.Module).CaddyModule().ID) } -// PublishECHConfigList publishes the given ECH config list to the given DNS names. +// PublishECHConfigList publishes the given ECH config list (as binary) to the given DNS names. +// If there is an error, it may be of type PublishECHConfigListErrors, detailing +// potentially multiple errors keyed by associated innerName. func (dnsPub *ECHDNSPublisher) PublishECHConfigList(ctx context.Context, innerNames []string, configListBin []byte) error { nameservers := certmagic.RecursiveNameservers(nil) // TODO: we could make resolvers configurable + errs := make(PublishECHConfigListErrors) + nextName: for _, domain := range innerNames { zone, err := certmagic.FindZoneByFQDN(ctx, dnsPub.logger, domain, nameservers) if err != nil { - dnsPub.logger.Error("could not determine zone for domain", - zap.String("domain", domain), - zap.Error(err)) + errs[domain] = fmt.Errorf("could not determine zone for domain: %w (domain=%s nameservers=%v)", err, domain, nameservers) continue } @@ -653,9 +839,7 @@ nextName: // we can augment the ech SvcParamKey with any other existing SvcParams recs, err := dnsPub.provider.GetRecords(ctx, zone) if err != nil { - dnsPub.logger.Error("unable to get existing DNS records to publish ECH data to HTTPS DNS record", - zap.String("domain", domain), - zap.Error(err)) + errs[domain] = fmt.Errorf("unable to get existing DNS records to publish ECH data to HTTPS DNS record: %w", err) continue } var httpsRec libdns.ServiceBinding @@ -693,12 +877,7 @@ nextName: continue } params := httpsRec.Params - if params == nil { - params = make(libdns.SvcParams) - } - - // overwrite only the "ech" SvcParamKey - params["ech"] = []string{base64.StdEncoding.EncodeToString(configListBin)} + params = dnsPub.publishedSvcParams(domain, params, configListBin) // publish record _, err = dnsPub.provider.SetRecords(ctx, zone, []libdns.Record{ @@ -713,19 +892,36 @@ nextName: }, }) if err != nil { - // TODO: Maybe this should just stop and return the error... - dnsPub.logger.Error("unable to publish ECH data to HTTPS DNS record", - zap.String("domain", domain), - zap.String("zone", zone), - zap.String("dns_record_name", relName), - zap.Error(err)) + errs[domain] = fmt.Errorf("unable to publish ECH data to HTTPS DNS record: %w (zone=%s dns_record_name=%s)", err, zone, relName) continue } } + if len(errs) > 0 { + return errs + } return nil } +func (dnsPub *ECHDNSPublisher) publishedSvcParams(domain string, existing libdns.SvcParams, configListBin []byte) libdns.SvcParams { + params := make(libdns.SvcParams, len(existing)+2) + for key, values := range existing { + params[key] = append([]string(nil), values...) + } + + params["ech"] = []string{base64.StdEncoding.EncodeToString(configListBin)} + + if len(dnsPub.alpnByDomain) == 0 { + return params + } + + if alpn := dnsPub.alpnByDomain[strings.ToLower(domain)]; len(alpn) > 0 { + params["alpn"] = append([]string(nil), alpn...) + } + + return params +} + // echConfig represents an ECHConfig from the specification, // [draft-ietf-tls-esni-22](https://www.ietf.org/archive/id/draft-ietf-tls-esni-22.html). type echConfig struct { @@ -752,10 +948,9 @@ type echConfig struct { // these fields are not part of the spec, but are here for // our use when setting up TLS servers or maintenance - configBin []byte - privKeyBin []byte - meta echConfigMeta - sendAsRetry bool + configBin []byte + privKeyBin []byte + meta echConfigMeta } func (echCfg echConfig) MarshalBinary() ([]byte, error) { @@ -777,8 +972,8 @@ func (echCfg *echConfig) UnmarshalBinary(data []byte) error { if !b.ReadUint16(&echCfg.Version) { return errInvalidLen } - if echCfg.Version != draftTLSESNI22 { - return fmt.Errorf("supported version must be %d: got %d", draftTLSESNI22, echCfg.Version) + if echCfg.Version != draftTLSESNI25 { + return fmt.Errorf("supported version must be %d: got %d", draftTLSESNI25, echCfg.Version) } if !b.ReadUint16LengthPrefixed(&content) || !b.Empty() { @@ -956,28 +1151,59 @@ type ECHPublisher interface { // It is used to prevent duplicating publications. PublisherKey() string - // Publishes the ECH config list for the given innerNames. Some publishers - // may not need a list of inner/protected names, and can ignore the argument; - // most, however, will want to use it to know which inner names are to be - // associated with the given ECH config list. + // Publishes the ECH config list (as binary) for the given innerNames. Some + // publishers may not need a list of inner/protected names, and can ignore the + // argument; most, however, will want to use it to know which inner names are + // to be associated with the given ECH config list. + // + // Implementations should return an error of type PublishECHConfigListErrors + // when relevant to key errors to their associated innerName, but should never + // return a non-nil PublishECHConfigListErrors when its length is 0. PublishECHConfigList(ctx context.Context, innerNames []string, echConfigList []byte) error } +// PublishECHConfigListErrors is returned by ECHPublishers to describe one or more +// errors publishing an ECH config list from PublishECHConfigList. A non-nil, empty +// value of this type should never be returned. +// nolint:errname // The linter wants "Error" convention, but this is a multi-error type. +type PublishECHConfigListErrors map[string]error + +func (p PublishECHConfigListErrors) Error() string { + var sb strings.Builder + for innerName, err := range p { + if sb.Len() > 0 { + sb.WriteString("; ") + } + sb.WriteString(innerName) + sb.WriteString(": ") + sb.WriteString(err.Error()) + } + return sb.String() +} + type echConfigMeta struct { Created time.Time `json:"created"` + Replaced time.Time `json:"replaced,omitzero"` Publications publicationHistory `json:"publications"` } +func echMetaKey(configID uint8) string { + return path.Join(echConfigsKey, strconv.Itoa(int(configID)), "meta.json") +} + // publicationHistory is a map of publisher key to // map of inner name to timestamp type publicationHistory map[string]map[string]time.Time +// echStorageLockName is the name of the storage lock to sync ECH updates. +const echStorageLockName = "ech_rotation" + // The key prefix when putting ECH configs in storage. After this // comes the config ID. const echConfigsKey = "ech/configs" -// https://www.ietf.org/archive/id/draft-ietf-tls-esni-22.html -const draftTLSESNI22 = 0xfe0d +// https://www.ietf.org/archive/id/draft-ietf-tls-esni-25.html +const draftTLSESNI25 = 0xfe0d // Interface guard var _ ECHPublisher = (*ECHDNSPublisher)(nil) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/folderloader.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/folderloader.go index 2df6f4cee..b86d3b6ae 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/folderloader.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/folderloader.go @@ -19,6 +19,7 @@ import ( "crypto/tls" "encoding/pem" "fmt" + "io/fs" "os" "path/filepath" "strings" @@ -62,18 +63,27 @@ func (fl FolderLoader) Provision(ctx caddy.Context) error { func (fl FolderLoader) LoadCertificates() ([]Certificate, error) { var certs []Certificate for _, dir := range fl { - err := filepath.Walk(dir, func(fpath string, info os.FileInfo, err error) error { + root, err := os.OpenRoot(dir) + if err != nil { + return nil, fmt.Errorf("unable to open root directory %s: %w", dir, err) + } + err = filepath.WalkDir(dir, func(fpath string, d fs.DirEntry, err error) error { if err != nil { return fmt.Errorf("unable to traverse into path: %s", fpath) } - if info.IsDir() { + if d.IsDir() { return nil } - if !strings.HasSuffix(strings.ToLower(info.Name()), ".pem") { + if !strings.HasSuffix(strings.ToLower(d.Name()), ".pem") { return nil } - bundle, err := os.ReadFile(fpath) + rel, err := filepath.Rel(dir, fpath) + if err != nil { + return fmt.Errorf("unable to get relative path for %s: %w", fpath, err) + } + + bundle, err := root.ReadFile(rel) if err != nil { return err } @@ -83,11 +93,11 @@ func (fl FolderLoader) LoadCertificates() ([]Certificate, error) { } certs = append(certs, Certificate{Certificate: cert}) - return nil }) + _ = root.Close() if err != nil { - return nil, err + return nil, fmt.Errorf("walking certificates directory %s: %w", dir, err) } } return certs, nil diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/internalissuer.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/internalissuer.go index be779757a..cad19f063 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/internalissuer.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/internalissuer.go @@ -115,7 +115,8 @@ func (iss InternalIssuer) Issue(ctx context.Context, csr *x509.CertificateReques if iss.SignWithRoot { issuerCert = iss.ca.RootCertificate() } else { - issuerCert = iss.ca.IntermediateCertificate() + chain := iss.ca.IntermediateCertificateChain() + issuerCert = chain[0] } // ensure issued certificate does not expire later than its issuer diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/leaffileloader.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/leaffileloader.go index 1d3f3a3e5..c2177ab55 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/leaffileloader.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/leaffileloader.go @@ -21,6 +21,7 @@ import ( "os" "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" ) func init() { @@ -32,6 +33,14 @@ type LeafFileLoader struct { Files []string `json:"files,omitempty"` } +// CaddyModule returns the Caddy module information. +func (LeafFileLoader) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + ID: "tls.leaf_cert_loader.file", + New: func() caddy.Module { return new(LeafFileLoader) }, + } +} + // Provision implements caddy.Provisioner. func (fl *LeafFileLoader) Provision(ctx caddy.Context) error { repl, ok := ctx.Value(caddy.ReplacerCtxKey).(*caddy.Replacer) @@ -44,12 +53,11 @@ func (fl *LeafFileLoader) Provision(ctx caddy.Context) error { return nil } -// CaddyModule returns the Caddy module information. -func (LeafFileLoader) CaddyModule() caddy.ModuleInfo { - return caddy.ModuleInfo{ - ID: "tls.leaf_cert_loader.file", - New: func() caddy.Module { return new(LeafFileLoader) }, - } +// UnmarshalCaddyfile implements caddyfile.Unmarshaler. +func (fl *LeafFileLoader) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { + d.NextArg() + fl.Files = append(fl.Files, d.RemainingArgs()...) + return nil } // LoadLeafCertificates returns the certificates to be loaded by fl. @@ -96,4 +104,5 @@ func convertPEMFilesToDERBytes(filename string) ([]byte, error) { var ( _ LeafCertificateLoader = (*LeafFileLoader)(nil) _ caddy.Provisioner = (*LeafFileLoader)(nil) + _ caddyfile.Unmarshaler = (*LeafFileLoader)(nil) ) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/leaffolderloader.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/leaffolderloader.go index 5c7b06e76..fe5e9e244 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/leaffolderloader.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/leaffolderloader.go @@ -22,15 +22,16 @@ import ( "strings" "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" ) func init() { caddy.RegisterModule(LeafFolderLoader{}) } -// LeafFolderLoader loads certificates and their associated keys from disk +// LeafFolderLoader loads certificates from disk // by recursively walking the specified directories, looking for PEM -// files which contain both a certificate and a key. +// files which contain a certificate. type LeafFolderLoader struct { Folders []string `json:"folders,omitempty"` } @@ -55,6 +56,13 @@ func (fl *LeafFolderLoader) Provision(ctx caddy.Context) error { return nil } +// UnmarshalCaddyfile implements caddyfile.Unmarshaler. +func (fl *LeafFolderLoader) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { + d.NextArg() + fl.Folders = append(fl.Folders, d.RemainingArgs()...) + return nil +} + // LoadLeafCertificates loads all the leaf certificates in the directories // listed in fl from all files ending with .pem. func (fl LeafFolderLoader) LoadLeafCertificates() ([]*x509.Certificate, error) { @@ -94,4 +102,5 @@ func (fl LeafFolderLoader) LoadLeafCertificates() ([]*x509.Certificate, error) { var ( _ LeafCertificateLoader = (*LeafFolderLoader)(nil) _ caddy.Provisioner = (*LeafFolderLoader)(nil) + _ caddyfile.Unmarshaler = (*LeafFolderLoader)(nil) ) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/leafpemloader.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/leafpemloader.go index 28467ccf2..de24bcc9f 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/leafpemloader.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/leafpemloader.go @@ -19,6 +19,7 @@ import ( "fmt" "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" ) func init() { @@ -52,6 +53,13 @@ func (LeafPEMLoader) CaddyModule() caddy.ModuleInfo { } } +// UnmarshalCaddyfile implements caddyfile.Unmarshaler. +func (fl *LeafPEMLoader) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { + d.NextArg() + fl.Certificates = append(fl.Certificates, d.RemainingArgs()...) + return nil +} + // LoadLeafCertificates returns the certificates contained in pl. func (pl LeafPEMLoader) LoadLeafCertificates() ([]*x509.Certificate, error) { certs := make([]*x509.Certificate, 0, len(pl.Certificates)) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/tls.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/tls.go index 7b49c0208..928e109e6 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/tls.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/tls.go @@ -23,6 +23,7 @@ import ( "net" "net/http" "runtime/debug" + "slices" "strings" "sync" "time" @@ -123,8 +124,15 @@ type TLS struct { // // EXPERIMENTAL: Subject to change. DNSRaw json.RawMessage `json:"dns,omitempty" caddy:"namespace=dns.providers inline_key=name"` - dns any // technically, it should be any/all of the libdns interfaces (RecordSetter, RecordAppender, etc.) + // The default DNS resolvers to use for TLS-related DNS operations, specifically + // for ACME DNS challenges and ACME server DNS validations. + // If not specified, the system default resolvers will be used. + // + // EXPERIMENTAL: Subject to change. + Resolvers []string `json:"resolvers,omitempty"` + + dns any // technically, it should be any/all of the libdns interfaces (RecordSetter, RecordAppender, etc.) certificateLoaders []CertificateLoader automateNames map[string]struct{} ctx caddy.Context @@ -133,7 +141,7 @@ type TLS struct { logger *zap.Logger events *caddyevents.App - serverNames map[string]struct{} + serverNames map[string]serverNameRegistration serverNamesMu *sync.Mutex // set of subjects with managed certificates, @@ -161,7 +169,7 @@ func (t *TLS) Provision(ctx caddy.Context) error { t.logger = ctx.Logger() repl := caddy.NewReplacer() t.managing, t.loaded = make(map[string]string), make(map[string]string) - t.serverNames = make(map[string]struct{}) + t.serverNames = make(map[string]serverNameRegistration) t.serverNamesMu = new(sync.Mutex) // set up default DNS module, if any, and make sure it implements all the @@ -335,7 +343,6 @@ func (t *TLS) Provision(ctx caddy.Context) error { // ECH (Encrypted ClientHello) initialization if t.EncryptedClientHello != nil { - t.EncryptedClientHello.configs = make(map[string][]echConfig) outerNames, err := t.EncryptedClientHello.Provision(ctx) if err != nil { return fmt.Errorf("provisioning Encrypted ClientHello components: %v", err) @@ -411,12 +418,37 @@ func (t *TLS) Start() error { return fmt.Errorf("automate: managing %v: %v", t.automateNames, err) } - // publish ECH configs in the background; does not need to block - // server startup, as it could take a while if t.EncryptedClientHello != nil { + echLogger := t.logger.Named("ech") + + // publish ECH configs in the background; does not need to block + // server startup, as it could take a while; then keep keys rotated go func() { - if err := t.publishECHConfigs(); err != nil { - t.logger.Named("ech").Error("publication(s) failed", zap.Error(err)) + // publish immediately first + if err := t.publishECHConfigs(echLogger); err != nil { + echLogger.Error("publication(s) failed", zap.Error(err)) + } + + // then every so often, rotate and publish if needed + // (both of these functions only do something if needed) + for { + select { + case <-time.After(1 * time.Hour): + // ensure old keys are rotated out + t.EncryptedClientHello.configsMu.Lock() + err = t.EncryptedClientHello.rotateECHKeys(t.ctx, echLogger, false) + t.EncryptedClientHello.configsMu.Unlock() + if err != nil { + echLogger.Error("rotating ECH configs failed", zap.Error(err)) + return + } + err := t.publishECHConfigs(echLogger) + if err != nil { + echLogger.Error("publication(s) failed", zap.Error(err)) + } + case <-t.ctx.Done(): + return + } } }() } @@ -582,8 +614,8 @@ func (t *TLS) Manage(subjects map[string]struct{}) error { // managingWildcardFor returns true if the app is managing a certificate that covers that // subject name (including consideration of wildcards), either from its internal list of -// names that it IS managing certs for, or from the otherSubjsToManage which includes names -// that WILL be managed. +// names that it IS managing certs for, from the otherSubjsToManage which includes names +// that WILL be managed, or from names configured in the 'automate' loader. func (t *TLS) managingWildcardFor(subj string, otherSubjsToManage map[string]struct{}) bool { // TODO: we could also consider manually-loaded certs using t.HasCertificateForSubject(), // but that does not account for how manually-loaded certs may be restricted as to which @@ -598,7 +630,9 @@ func (t *TLS) managingWildcardFor(subj string, otherSubjsToManage map[string]str return managing } - // replace labels of the domain with wildcards until we get a match + // replace labels of the domain with wildcards until we get a match from names + // already being managed, those about to be managed in this batch, or those + // configured for automation labels := strings.Split(subj, ".") for i := range labels { if labels[i] == "*" { @@ -612,32 +646,117 @@ func (t *TLS) managingWildcardFor(subj string, otherSubjsToManage map[string]str if _, ok := otherSubjsToManage[candidate]; ok { return true } + if _, ok := t.automateNames[candidate]; ok { + return true + } } return false } -// RegisterServerNames registers the provided DNS names with the TLS app. -// This is currently used to auto-publish Encrypted ClientHello (ECH) -// configurations, if enabled. Use of this function by apps using the TLS -// app removes the need for the user to redundantly specify domain names -// in their configuration. This function separates hostname and port -// (keeping only the hotsname) and filters IP addresses, which can't be -// used with ECH. +// RegisterServerNames registers the provided DNS names with the TLS app and +// associates them with the given HTTPS RR ALPN values, if any. This is +// currently used to auto-publish Encrypted ClientHello (ECH) configurations, +// if enabled. Use of this function by apps using the TLS app removes the need +// for the user to redundantly specify domain names in their configuration. +// This function separates hostname and port, keeping only the hostname, and +// filters IP addresses which can't be used with ECH. // // EXPERIMENTAL: This function and its semantics/behavior are subject to change. -func (t *TLS) RegisterServerNames(dnsNames []string) { +func (t *TLS) RegisterServerNames(dnsNames, alpnValues []string) { + t.serverNamesMu.Lock() + defer t.serverNamesMu.Unlock() + + for _, name := range dnsNames { + host, _, err := net.SplitHostPort(name) + if err != nil { + host = name + } + host = strings.ToLower(strings.TrimSpace(host)) + if host == "" || certmagic.SubjectIsIP(host) { + continue + } + + registration := t.serverNames[host] + + if len(alpnValues) == 0 { + t.serverNames[host] = registration + continue + } + + if registration.alpnValues == nil { + registration.alpnValues = make(map[string]struct{}, len(alpnValues)) + } + for _, alpn := range alpnValues { + if alpn == "" { + continue + } + registration.alpnValues[alpn] = struct{}{} + } + t.serverNames[host] = registration + } +} + +func (t *TLS) alpnValuesForServerNames(dnsNames []string) map[string][]string { t.serverNamesMu.Lock() + defer t.serverNamesMu.Unlock() + + result := make(map[string][]string, len(dnsNames)) for _, name := range dnsNames { host, _, err := net.SplitHostPort(name) if err != nil { host = name } - if strings.TrimSpace(host) != "" && !certmagic.SubjectIsIP(host) { - t.serverNames[strings.ToLower(host)] = struct{}{} + host = strings.ToLower(strings.TrimSpace(host)) + if host == "" { + continue + } + + registration, ok := t.serverNames[host] + if !ok || len(registration.alpnValues) == 0 { + continue + } + result[host] = OrderedHTTPSRRALPN(registration.alpnValues) + } + + return result +} + +// OrderedHTTPSRRALPN returns the HTTPS RR ALPN values in preferred order. +func OrderedHTTPSRRALPN(alpnSet map[string]struct{}) []string { + if len(alpnSet) == 0 { + return nil + } + + knownOrder := append([]string{"h3"}, defaultALPN...) + ordered := make([]string, 0, len(alpnSet)) + seen := make(map[string]struct{}, len(alpnSet)) + + for _, alpn := range knownOrder { + if _, ok := alpnSet[alpn]; ok { + ordered = append(ordered, alpn) + seen[alpn] = struct{}{} + } + } + + if len(ordered) == len(alpnSet) { + return ordered + } + + var remaining []string + for alpn := range alpnSet { + if _, ok := seen[alpn]; ok { + continue } + remaining = append(remaining, alpn) } - t.serverNamesMu.Unlock() + slices.Sort(remaining) + + return append(ordered, remaining...) +} + +type serverNameRegistration struct { + alpnValues map[string]struct{} } // HandleHTTPChallenge ensures that the ACME HTTP challenge or ZeroSSL HTTP diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/zerosslissuer.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/zerosslissuer.go index b8727ab66..3421e816a 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/zerosslissuer.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/modules/caddytls/zerosslissuer.go @@ -40,7 +40,7 @@ func init() { type ZeroSSLIssuer struct { // The API key (or "access key") for using the ZeroSSL API. // REQUIRED. - APIKey string `json:"api_key,omitempty"` + APIKey string `json:"api_key,omitempty"` //nolint:gosec // false positive... yes this is exported, for JSON interop // How many days the certificate should be valid for. // Only certain values are accepted; see ZeroSSL docs. diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/notify/notify_windows.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/notify/notify_windows.go index 5666a4c22..33f947565 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/notify/notify_windows.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/notify/notify_windows.go @@ -14,16 +14,26 @@ package notify -import "golang.org/x/sys/windows/svc" +import ( + "log" + "strings" + + "golang.org/x/sys/windows/svc" +) // globalStatus store windows service status, it can be // use to notify caddy status. var globalStatus chan<- svc.Status +// SetGlobalStatus assigns the channel through which status updates +// will be sent to the SCM. This is typically provided by the service +// handler when the service starts. func SetGlobalStatus(status chan<- svc.Status) { globalStatus = status } +// Ready notifies the SCM that the service is fully running and ready +// to accept stop or shutdown control requests. func Ready() error { if globalStatus != nil { globalStatus <- svc.Status{ @@ -34,6 +44,8 @@ func Ready() error { return nil } +// Reloading notifies the SCM that the service is entering a transitional +// state. func Reloading() error { if globalStatus != nil { globalStatus <- svc.Status{State: svc.StartPending} @@ -41,6 +53,8 @@ func Reloading() error { return nil } +// Stopping notifies the SCM that the service is in the process of stopping. +// This allows Windows to track the shutdown transition properly. func Stopping() error { if globalStatus != nil { globalStatus <- svc.Status{State: svc.StopPending} @@ -48,8 +62,53 @@ func Stopping() error { return nil } -// TODO: not implemented -func Status(_ string) error { return nil } +// Status sends an arbitrary service state to the SCM based on a string +// identifier of [svc.State]. +// The unknown states will be logged. +func Status(name string) error { + if globalStatus == nil { + return nil + } + + var state svc.State + var accepts svc.Accepted + accepts = 0 + + switch strings.ToLower(name) { + case "stopped": + state = svc.Stopped + case "start_pending": + state = svc.StartPending + case "stop_pending": + state = svc.StopPending + case "running": + state = svc.Running + accepts = svc.AcceptStop | svc.AcceptShutdown + case "continue_pending": + state = svc.ContinuePending + case "pause_pending": + state = svc.PausePending + case "paused": + state = svc.Paused + accepts = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue + default: + log.Printf("unknown state: %s", name) + return nil + } + + globalStatus <- svc.Status{State: state, Accepts: accepts} + return nil +} -// TODO: not implemented -func Error(_ error, _ int) error { return nil } +// Error notifies the SCM that the service is stopping due to a failure, +// including a service-specific exit code. +func Error(err error, code int) error { + if globalStatus != nil { + globalStatus <- svc.Status{ + State: svc.StopPending, + ServiceSpecificExitCode: uint32(code), + } + } + + return nil +} diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/replacer.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/replacer.go index 297dd935c..2ab02b602 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/replacer.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/replacer.go @@ -121,6 +121,18 @@ func (r *Replacer) Delete(variable string) { r.mapMutex.Unlock() } +// DeleteByPrefix removes all static variables with +// keys starting with the given prefix +func (r *Replacer) DeleteByPrefix(prefix string) { + r.mapMutex.Lock() + for key := range r.static { + if strings.HasPrefix(key, prefix) { + delete(r.static, key) + } + } + r.mapMutex.Unlock() +} + // fromStatic provides values from r.static. func (r *Replacer) fromStatic(key string) (any, bool) { r.mapMutex.RLock() @@ -335,7 +347,7 @@ type replacementProvider interface { replace(key string) (any, bool) } -// fileReplacementsProvider handles {file.*} replacements, +// fileReplacementProvider handles {file.*} replacements, // reading a file from disk and replacing with its contents. type fileReplacementProvider struct{} @@ -360,7 +372,7 @@ func (f fileReplacementProvider) replace(key string) (any, bool) { return string(body), true } -// globalDefaultReplacementsProvider handles replacements +// globalDefaultReplacementProvider handles replacements // that can be used in any context, such as system variables, // time, or environment variables. type globalDefaultReplacementProvider struct{} diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/sigtrap_posix.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/sigtrap_posix.go index 2c6306121..018a81165 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/sigtrap_posix.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/sigtrap_posix.go @@ -18,6 +18,7 @@ package caddy import ( "context" + "errors" "os" "os/signal" "syscall" @@ -48,7 +49,31 @@ func trapSignalsPosix() { exitProcessFromSignal("SIGTERM") case syscall.SIGUSR1: - Log().Info("not implemented", zap.String("signal", "SIGUSR1")) + logger := Log().With(zap.String("signal", "SIGUSR1")) + // If we know the last source config file/adapter (set when starting + // via `caddy run --config --adapter `), attempt + // to reload from that source. Otherwise, ignore the signal. + file, adapter, reloadCallback := getLastConfig() + if file == "" { + logger.Info("last config unknown, ignored SIGUSR1") + break + } + logger = logger.With( + zap.String("file", file), + zap.String("adapter", adapter)) + if reloadCallback == nil { + logger.Warn("no reload helper available, ignored SIGUSR1") + break + } + logger.Info("reloading config from last-known source") + if err := reloadCallback(file, adapter); errors.Is(err, errReloadFromSourceUnavailable) { + // No reload helper available (likely not started via caddy run). + logger.Warn("reload from source unavailable in this process; ignored SIGUSR1") + } else if err != nil { + logger.Error("failed to reload config from file", zap.Error(err)) + } else { + logger.Info("successfully reloaded config from file") + } case syscall.SIGUSR2: Log().Info("not implemented", zap.String("signal", "SIGUSR2")) diff --git a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/usagepool.go b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/usagepool.go index e011be961..6b7a3c25e 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/usagepool.go +++ b/plugins/traefik/vendor/github.com/caddyserver/caddy/v2/usagepool.go @@ -79,14 +79,15 @@ func (up *UsagePool) LoadOrNew(key any, construct Constructor) (value any, loade up.Lock() upv, loaded = up.pool[key] if loaded { - atomic.AddInt32(&upv.refs, 1) + upv.refs.Add(1) up.Unlock() upv.RLock() value = upv.value err = upv.err upv.RUnlock() } else { - upv = &usagePoolVal{refs: 1} + upv = &usagePoolVal{} + upv.refs.Store(1) upv.Lock() up.pool[key] = upv up.Unlock() @@ -106,7 +107,7 @@ func (up *UsagePool) LoadOrNew(key any, construct Constructor) (value any, loade } upv.Unlock() } - return + return value, loaded, err } // LoadOrStore loads the value associated with key from the pool if it @@ -118,7 +119,7 @@ func (up *UsagePool) LoadOrStore(key, val any) (value any, loaded bool) { up.Lock() upv, loaded = up.pool[key] if loaded { - atomic.AddInt32(&upv.refs, 1) + upv.refs.Add(1) up.Unlock() upv.Lock() if upv.err == nil { @@ -129,12 +130,13 @@ func (up *UsagePool) LoadOrStore(key, val any) (value any, loaded bool) { } upv.Unlock() } else { - upv = &usagePoolVal{refs: 1, value: val} + upv = &usagePoolVal{value: val} + upv.refs.Store(1) up.pool[key] = upv up.Unlock() value = val } - return + return value, loaded } // Range iterates the pool similarly to how sync.Map.Range() does: @@ -173,7 +175,7 @@ func (up *UsagePool) Delete(key any) (deleted bool, err error) { up.Unlock() return false, nil } - refs := atomic.AddInt32(&upv.refs, -1) + refs := upv.refs.Add(-1) if refs == 0 { delete(up.pool, key) up.Unlock() @@ -188,10 +190,10 @@ func (up *UsagePool) Delete(key any) (deleted bool, err error) { up.Unlock() if refs < 0 { panic(fmt.Sprintf("deleted more than stored: %#v (usage: %d)", - upv.value, upv.refs)) + upv.value, upv.refs.Load())) } } - return + return deleted, err } // References returns the number of references (count of usages) to a @@ -203,7 +205,7 @@ func (up *UsagePool) References(key any) (int, bool) { if loaded { // I wonder if it'd be safer to read this value during // our lock on the UsagePool... guess we'll see... - refs := atomic.LoadInt32(&upv.refs) + refs := upv.refs.Load() return int(refs), true } return 0, false @@ -220,7 +222,7 @@ type Destructor interface { } type usagePoolVal struct { - refs int32 // accessed atomically; must be 64-bit aligned for 32-bit systems + refs atomic.Int32 value any err error sync.RWMutex diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/README.md b/plugins/traefik/vendor/github.com/caddyserver/certmagic/README.md index 62f0c8985..513f781a5 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/README.md +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/README.md @@ -1,5 +1,10 @@

- CertMagic + + + + CertMagic + +

Easy and Powerful TLS Automation

The same library used by the Caddy Web Server

@@ -113,7 +118,7 @@ CertMagic - Automatic HTTPS using Let's Encrypt - Cross-platform support! Mac, Windows, Linux, BSD, Android... - Scales to hundreds of thousands of names/certificates per instance - Use in conjunction with your own certificates -- Full support for [draft-ietf-acme-ari](https://datatracker.ietf.org/doc/draft-ietf-acme-ari/) (ACME Renewal Information; ARI) extension +- Full support for [RFC 9773](https://datatracker.ietf.org/doc/html/rfc9773) (ACME Renewal Information; ARI) extension ## Requirements diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/account.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/account.go index 7b8efa050..3e7d0cc4a 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/account.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/account.go @@ -36,9 +36,27 @@ import ( "go.uber.org/zap" ) -// getAccount either loads or creates a new account, depending on if +// getAccountToUse will either load or create an account based on the configuration of the issuer. +// It will try to get one from storage if one exists, and if not, it will create one, all the while +// honoring the configured account key PEM (if any) to restrict which account is used. +func (iss *ACMEIssuer) getAccountToUse(ctx context.Context, directory string) (acme.Account, error) { + var account acme.Account + var err error + if iss.AccountKeyPEM != "" { + iss.Logger.Info("using configured ACME account") + account, err = iss.GetAccount(ctx, []byte(iss.AccountKeyPEM)) + } else { + account, err = iss.loadOrCreateAccount(ctx, directory, iss.getEmail()) + } + if err != nil { + return acme.Account{}, fmt.Errorf("getting ACME account: %v", err) + } + return account, nil +} + +// loadOrCreateAccount either loads or creates a new account, depending on if // an account can be found in storage for the given CA + email combo. -func (am *ACMEIssuer) getAccount(ctx context.Context, ca, email string) (acme.Account, error) { +func (am *ACMEIssuer) loadOrCreateAccount(ctx context.Context, ca, email string) (acme.Account, error) { acct, err := am.loadAccount(ctx, ca, email) if errors.Is(err, fs.ErrNotExist) { am.Logger.Info("creating new account because no account for configured email is known to us", @@ -407,7 +425,7 @@ func (am *ACMEIssuer) mostRecentAccountEmail(ctx context.Context, caURL string) return "", false } - account, err := am.getAccount(ctx, caURL, path.Base(accountList[0])) + account, err := am.loadOrCreateAccount(ctx, caURL, path.Base(accountList[0])) if err != nil { return "", false } diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/acmeclient.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/acmeclient.go index 6e1f1f7f2..08e1a53dd 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/acmeclient.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/acmeclient.go @@ -55,23 +55,7 @@ func (iss *ACMEIssuer) newACMEClientWithAccount(ctx context.Context, useTestCA, // we try loading the account from storage before a potential // lock, and after obtaining the lock as well, to ensure we don't // repeat work done by another instance or goroutine - getAccount := func() (acme.Account, error) { - // look up or create the ACME account - var account acme.Account - if iss.AccountKeyPEM != "" { - iss.Logger.Info("using configured ACME account") - account, err = iss.GetAccount(ctx, []byte(iss.AccountKeyPEM)) - } else { - account, err = iss.getAccount(ctx, client.Directory, iss.getEmail()) - } - if err != nil { - return acme.Account{}, fmt.Errorf("getting ACME account: %v", err) - } - return account, nil - } - - // first try getting the account - account, err := getAccount() + account, err := iss.getAccountToUse(ctx, client.Directory) if err != nil { return nil, err } @@ -95,7 +79,7 @@ func (iss *ACMEIssuer) newACMEClientWithAccount(ctx context.Context, useTestCA, }() // if we're not the only one waiting for this account, then by this point it should already be registered and in storage; reload it - account, err = getAccount() + account, err = iss.getAccountToUse(ctx, client.Directory) if err != nil { return nil, err } @@ -207,26 +191,34 @@ func (iss *ACMEIssuer) newACMEClient(useTestCA bool) (*acmez.Client, error) { if iss.DNS01Solver == nil { // enable HTTP-01 challenge if !iss.DisableHTTPChallenge { - client.ChallengeSolvers[acme.ChallengeTypeHTTP01] = distributedSolver{ - storage: iss.config.Storage, - storageKeyIssuerPrefix: iss.storageKeyCAPrefix(client.Directory), - solver: &httpSolver{ - handler: iss.HTTPChallengeHandler(http.NewServeMux()), - address: net.JoinHostPort(iss.ListenHost, strconv.Itoa(iss.getHTTPPort())), - }, + var solver acmez.Solver = &httpSolver{ + handler: iss.HTTPChallengeHandler(http.NewServeMux()), + address: net.JoinHostPort(iss.ListenHost, strconv.Itoa(iss.getHTTPPort())), + } + if !iss.DisableDistributedSolvers { + solver = distributedSolver{ + storage: iss.config.Storage, + storageKeyIssuerPrefix: iss.storageKeyCAPrefix(client.Directory), + solver: solver, + } } + client.ChallengeSolvers[acme.ChallengeTypeHTTP01] = solver } // enable TLS-ALPN-01 challenge if !iss.DisableTLSALPNChallenge { - client.ChallengeSolvers[acme.ChallengeTypeTLSALPN01] = distributedSolver{ - storage: iss.config.Storage, - storageKeyIssuerPrefix: iss.storageKeyCAPrefix(client.Directory), - solver: &tlsALPNSolver{ - config: iss.config, - address: net.JoinHostPort(iss.ListenHost, strconv.Itoa(iss.getTLSALPNPort())), - }, + var solver acmez.Solver = &tlsALPNSolver{ + config: iss.config, + address: net.JoinHostPort(iss.ListenHost, strconv.Itoa(iss.getTLSALPNPort())), + } + if !iss.DisableDistributedSolvers { + solver = distributedSolver{ + storage: iss.config.Storage, + storageKeyIssuerPrefix: iss.storageKeyCAPrefix(client.Directory), + solver: solver, + } } + client.ChallengeSolvers[acme.ChallengeTypeTLSALPN01] = solver } } else { // use DNS challenge exclusively @@ -278,7 +270,13 @@ func (iss *ACMEIssuer) newBasicACMEClient() (*acmez.Client, error) { Directory: caURL, UserAgent: buildUAString(), HTTPClient: iss.httpClient, - Logger: slog.New(zapslog.NewHandler(iss.Logger.Named("acme_client").Core())), + Logger: slog.New(zapslog.NewHandler( + iss.Logger.Core(), + zapslog.WithName(iss.Logger.Name()+".acme_client"), + // the default enables traces at ERROR level, this disables + // them by setting it to a level higher than any other level + zapslog.AddStacktraceAt(slog.Level(127)), + )), }, }, nil } diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/acmeissuer.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/acmeissuer.go index 170156ea0..0b41e1b16 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/acmeissuer.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/acmeissuer.go @@ -93,6 +93,15 @@ type ACMEIssuer struct { // Disable all TLS-ALPN challenges DisableTLSALPNChallenge bool + // Disable distributed solving; avoids writing + // challenge info to storage backend and will + // only use data in memory to solve the HTTP and + // TLS-ALPN challenges; will still attempt to + // solve distributed HTTP challenges blindly by + // using available account and challenge token + // as read from request URI + DisableDistributedSolvers bool + // The host (ONLY the host, not port) to listen // on if necessary to start a listener to solve // an ACME challenge @@ -340,7 +349,7 @@ func (iss *ACMEIssuer) isAgreed() bool { // IP certificates via ACME are defined in RFC 8738. func (am *ACMEIssuer) PreCheck(ctx context.Context, names []string, interactive bool) error { publicCAsAndIPCerts := map[string]bool{ // map of public CAs to whether they support IP certificates (last updated: Q1 2024) - "api.letsencrypt.org": false, // https://community.letsencrypt.org/t/certificate-for-static-ip/84/2?u=mholt + "api.letsencrypt.org": true, // https://letsencrypt.org/2025/07/01/issuing-our-first-ip-address-certificate/ "acme.zerossl.com": false, // only supported via their API, not ACME endpoint "api.pki.goog": true, // https://pki.goog/faq/#faq-IPCerts "api.buypass.com": false, // https://community.buypass.com/t/h7hm76w/buypass-support-for-rfc-8738 @@ -481,7 +490,7 @@ func (am *ACMEIssuer) doIssue(ctx context.Context, csr *x509.CertificateRequest, // do this in a loop because there's an error case that may necessitate a retry, but not more than once var certChains []acme.Certificate - for i := 0; i < 2; i++ { + for range 2 { am.Logger.Info("using ACME account", zap.String("account_id", params.Account.Location), zap.Strings("account_contact", params.Account.Contact)) @@ -514,11 +523,11 @@ func (am *ACMEIssuer) doIssue(ctx context.Context, csr *x509.CertificateRequest, } return nil, usingTestCA, fmt.Errorf("%v %w (ca=%s)", nameSet, err, client.acmeClient.Directory) } - if len(certChains) == 0 { - return nil, usingTestCA, fmt.Errorf("no certificate chains") - } break } + if len(certChains) == 0 { + return nil, usingTestCA, fmt.Errorf("no certificate chains") + } preferredChain := am.selectPreferredChain(certChains) diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/cache.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/cache.go index ae48d25ac..8f3255767 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/cache.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/cache.go @@ -16,7 +16,7 @@ package certmagic import ( "fmt" - weakrand "math/rand" + weakrand "math/rand/v2" "strings" "sync" "time" @@ -244,10 +244,10 @@ func (certCache *Cache) unsyncedCacheCertificate(cert Certificate) { // map with less code, that is a heavily skewed eviction // strategy; generating random numbers is cheap and // ensures a much better distribution. - rnd := weakrand.Intn(cacheSize) + rnd := weakrand.IntN(cacheSize) i := 0 for _, randomCert := range certCache.cache { - if i == rnd { + if i >= rnd && randomCert.managed { // don't evict manually-loaded certs certCache.logger.Debug("cache full; evicting random certificate", zap.Strings("removing_subjects", randomCert.Names), zap.String("removing_hash", randomCert.hash), @@ -365,6 +365,10 @@ func (certCache *Cache) getConfig(cert Certificate) (*Config, error) { if err != nil { return nil, err } + if cfg == nil { + // this is bad if this happens, probably a programmer error (oops) + return nil, fmt.Errorf("no configuration associated with certificate: %v;", cert.Names) + } if cfg.certCache == nil { return nil, fmt.Errorf("config returned for certificate %v has nil cache; expected %p (this one)", cert.Names, certCache) diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/certificates.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/certificates.go index 05b101409..e7cfa5fe9 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/certificates.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/certificates.go @@ -19,8 +19,9 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" + "errors" "fmt" - "math/rand" + "math/rand/v2" "net" "os" "strings" @@ -127,7 +128,7 @@ func (cfg *Config) certNeedsRenewal(leaf *x509.Certificate, ari acme.RenewalInfo if selectedTime.IsZero() && (!ari.SuggestedWindow.Start.IsZero() && !ari.SuggestedWindow.End.IsZero()) { start, end := ari.SuggestedWindow.Start.Unix()+1, ari.SuggestedWindow.End.Unix() - selectedTime = time.Unix(rand.Int63n(end-start)+start, 0).UTC() + selectedTime = time.Unix(rand.Int64N(end-start)+start, 0).UTC() logger.Warn("no renewal time had been selected with ARI; chose an ephemeral one for now", zap.Time("ephemeral_selected_time", selectedTime)) } @@ -344,9 +345,15 @@ func (cfg *Config) CacheUnmanagedTLSCertificate(ctx context.Context, tlsCert tls zap.Time("not_after", cert.Leaf.NotAfter), zap.Strings("sans", cert.Names)) } - err = stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, nil) - if err != nil { - cfg.Logger.Warn("stapling OCSP", zap.Error(err)) + if !cfg.OCSP.DisableStapling { + err = stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, nil) + if err != nil { + if errors.Is(err, ErrNoOCSPServerSpecified) { + cfg.Logger.Debug("stapling OCSP", zap.Error(err)) + } else { + cfg.Logger.Warn("stapling OCSP", zap.Error(err)) + } + } } cfg.emit(ctx, "cached_unmanaged_cert", map[string]any{"sans": cert.Names}) cert.Tags = tags @@ -370,6 +377,37 @@ func (cfg *Config) CacheUnmanagedCertificatePEMBytes(ctx context.Context, certBy return cert.hash, nil } +// CacheUnmanagedCertificatePEMBytesAsReplacement is the same as CacheUnmanagedCertificatePEMBytes, +// but it also removes any other loaded certificates for the SANs on the certificate being cached. +// This has the effect of using this certificate exclusively and immediately for its SANs. The SANs +// for which the certificate should apply may optionally be passed in as well. By default, a cert +// is used for any of its SANs. +// +// This method is safe for concurrent use. +// +// EXPERIMENTAL: Subject to change/removal. +func (cfg *Config) CacheUnmanagedCertificatePEMBytesAsReplacement(ctx context.Context, certBytes, keyBytes []byte, tags, sans []string) (string, error) { + cert, err := cfg.makeCertificateWithOCSP(ctx, certBytes, keyBytes) + if err != nil { + return "", err + } + cert.Tags = tags + if len(sans) > 0 { + cert.Names = sans + } + cfg.certCache.mu.Lock() + for _, san := range cert.Names { + existingCerts := cfg.certCache.getAllMatchingCerts(san) + for _, existingCert := range existingCerts { + cfg.certCache.removeCertificate(existingCert) + } + } + cfg.certCache.unsyncedCacheCertificate(cert) + cfg.certCache.mu.Unlock() + cfg.emit(ctx, "cached_unmanaged_cert", map[string]any{"sans": cert.Names, "replacement": true}) + return cert.hash, nil +} + // makeCertificateFromDiskWithOCSP makes a Certificate by loading the // certificate and key files. It fills out all the fields in // the certificate except for the Managed and OnDemand flags. @@ -393,9 +431,13 @@ func (cfg Config) makeCertificateWithOCSP(ctx context.Context, certPEMBlock, key if err != nil { return cert, err } - err = stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, certPEMBlock) - if err != nil { - cfg.Logger.Warn("stapling OCSP", zap.Error(err), zap.Strings("identifiers", cert.Names)) + if !cfg.OCSP.DisableStapling { + err = stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, certPEMBlock) + if errors.Is(err, ErrNoOCSPServerSpecified) { + cfg.Logger.Debug("stapling OCSP", zap.Error(err), zap.Strings("identifiers", cert.Names)) + } else if err != nil { + cfg.Logger.Warn("stapling OCSP", zap.Error(err), zap.Strings("identifiers", cert.Names)) + } } return cert, nil } @@ -609,6 +651,11 @@ func isInternalIP(addr string) bool { func hostOnly(hostport string) string { host, _, err := net.SplitHostPort(hostport) if err != nil { + // May be a bare IPv6 address in brackets without a port (e.g. "[::1]"). + // net.SplitHostPort requires a port when brackets are present, so strip them. + if len(hostport) > 1 && hostport[0] == '[' && hostport[len(hostport)-1] == ']' { + return hostport[1 : len(hostport)-1] + } return hostport // OK; probably had no port to begin with } return host @@ -623,6 +670,8 @@ func hostOnly(hostport string) string { // It uses DNS wildcard matching logic and is case-insensitive. // https://tools.ietf.org/html/rfc2818#section-3.1 func MatchWildcard(subject, wildcard string) bool { + // Strip brackets from IPv6 addresses (e.g. "[::1]" from HTTP Host headers). + subject = hostOnly(subject) subject, wildcard = strings.ToLower(subject), strings.ToLower(wildcard) if subject == wildcard { return true diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/config.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/config.go index 1e1e840ee..27c39cd82 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/config.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/config.go @@ -28,7 +28,7 @@ import ( "errors" "fmt" "io/fs" - weakrand "math/rand" + weakrand "math/rand/v2" "net" "net/http" "net/url" @@ -382,11 +382,23 @@ func (cfg *Config) manageAll(ctx context.Context, domainNames []string, async bo continue } - // TODO: consider doing this in a goroutine if async, to utilize multiple cores while loading certs // otherwise, begin management immediately - err := cfg.manageOne(ctx, domainName, async) - if err != nil { - return err + if async { + // don't block loading, since stapling OCSP uses the network and could block all other certs + // from being managed... (kind of tricky to make it truly async any lower-level than this) + go func(subject string) { + err := cfg.manageOne(ctx, subject, async) + if err != nil { + cfg.Logger.Error("initiating certificate management", + zap.String("subject", subject), + zap.Error(err)) + } + }(domainName) + } else { + err := cfg.manageOne(ctx, domainName, async) + if err != nil { + return err + } } } @@ -490,6 +502,33 @@ func (cfg *Config) manageOne(ctx context.Context, domainName string, async bool) return renew() } +// renewLockLease extends the lease duration on an existing lock if the storage +// backend supports it. The lease duration is calculated based on the retry attempt +// number and includes the certificate obtain timeout. This prevents locks from +// expiring during long-running certificate operations with retries. +func (cfg *Config) renewLockLease(ctx context.Context, storage Storage, lockKey string, attempt int) error { + l, ok := storage.(LockLeaseRenewer) + if !ok { + return nil + } + + leaseDuration := maxRetryDuration + if attempt < len(retryIntervals) && attempt >= 0 { + leaseDuration = retryIntervals[attempt] + } + leaseDuration = leaseDuration + DefaultACME.CertObtainTimeout + log := cfg.Logger.Named("renewLockLease") + log.Debug("renewing lock lease", zap.String("lockKey", lockKey), zap.Int("attempt", attempt)) + + err := l.RenewLockLease(ctx, lockKey, leaseDuration) + if err == nil { + locksMu.Lock() + locks[lockKey] = storage + locksMu.Unlock() + } + return err +} + // ObtainCertSync generates a new private key and obtains a certificate for // name using cfg in the foreground; i.e. interactively and without retries. // It stows the renewed certificate and its assets in storage if successful. @@ -546,6 +585,15 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool log.Info("lock acquired", zap.String("identifier", name)) f := func(ctx context.Context) error { + // renew lease on the lock if the certificate store supports it + attempt, ok := ctx.Value(AttemptsCtxKey).(*int) + if ok { + err = cfg.renewLockLease(ctx, cfg.Storage, lockKey, *attempt) + if err != nil { + return fmt.Errorf("unable to renew lock lease '%s': %v", lockKey, err) + } + } + // check if obtain is still needed -- might have been obtained during lock if cfg.storageHasCertResourcesAnyIssuer(ctx, name) { log.Info("certificate already exists in storage", zap.String("identifier", name)) @@ -805,6 +853,16 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv log.Info("lock acquired", zap.String("identifier", name)) f := func(ctx context.Context) error { + // renew lease on the certificate store lock if the store implementation supports it; + // prevents the lock from being acquired by another process/instance while we're renewing + attempt, ok := ctx.Value(AttemptsCtxKey).(*int) + if ok { + err = cfg.renewLockLease(ctx, cfg.Storage, lockKey, *attempt) + if err != nil { + return fmt.Errorf("unable to renew lock lease '%s': %v", lockKey, err) + } + } + // prepare for renewal (load PEM cert, key, and meta) certRes, err := cfg.loadCertResourceAnyIssuer(ctx, name) if err != nil { @@ -1073,10 +1131,10 @@ func (cfg *Config) RevokeCert(ctx context.Context, domain string, reason int, in return nil } -// TLSConfig is an opinionated method that returns a recommended, modern -// TLS configuration that can be used to configure TLS listeners. Aside -// from safe, modern defaults, this method sets two critical fields on the -// TLS config which are required to enable automatic certificate +// TLSConfig returns a recommended, modern TLS configuration that can be used +// to configure TLS listeners. Aside from using the safe, modern defaults +// implemented by the Go standard library, this method sets two critical fields +// on the TLS config which are required to enable automatic certificate // management: GetCertificate and NextProtos. // // The GetCertificate field is necessary to get certificates from memory @@ -1100,32 +1158,32 @@ func (cfg *Config) TLSConfig() *tls.Config { // these two fields necessary for TLS-ALPN challenge GetCertificate: cfg.GetCertificate, NextProtos: []string{acmez.ACMETLS1Protocol}, - - // the rest recommended for modern TLS servers - MinVersion: tls.VersionTLS12, - CurvePreferences: []tls.CurveID{ - tls.X25519, - tls.CurveP256, - }, - CipherSuites: preferredDefaultCipherSuites(), - PreferServerCipherSuites: true, } } -// getChallengeInfo loads the challenge info from either the internal challenge memory +// getACMEChallengeInfo loads the challenge info from either the internal challenge memory // or the external storage (implying distributed solving). The second return value // indicates whether challenge info was loaded from external storage. If true, the // challenge is being solved in a distributed fashion; if false, from internal memory. // If no matching challenge information can be found, an error is returned. -func (cfg *Config) getChallengeInfo(ctx context.Context, identifier string) (Challenge, bool, error) { +func (cfg *Config) getACMEChallengeInfo(ctx context.Context, identifier string, allowDistributed bool) (Challenge, bool, error) { // first, check if our process initiated this challenge; if so, just return it chalData, ok := GetACMEChallenge(identifier) if ok { return chalData, false, nil } + // if distributed solving is disabled, and we don't have it in memory, return an error + if !allowDistributed { + return Challenge{}, false, fmt.Errorf("distributed solving disabled and no challenge information found internally for identifier: %s", identifier) + } + // otherwise, perhaps another instance in the cluster initiated it; check - // the configured storage to retrieve challenge data + // the configured storage to retrieve challenge data (requires storage) + + if cfg.Storage == nil { + return Challenge{}, false, errors.New("challenge was not initiated internally and no storage is configured for distributed solving") + } var chalInfo acme.Challenge var chalInfoBytes []byte @@ -1181,11 +1239,20 @@ func (cfg *Config) checkStorage(ctx context.Context) error { } key := fmt.Sprintf("rw_test_%d", weakrand.Int()) contents := make([]byte, 1024*10) // size sufficient for one or two ACME resources - _, err := weakrand.Read(contents) - if err != nil { - return err + // This is how ChaCha8.Read works, without handling the case where the slice length is not a multiple of 8. + // This also avoids the use of a mutex and an import. + for i := 0; i < len(contents); i += 8 { + v := weakrand.Uint64() + contents[i] = byte(v) + contents[i+1] = byte(v >> 8) + contents[i+2] = byte(v >> 16) + contents[i+3] = byte(v >> 24) + contents[i+4] = byte(v >> 32) + contents[i+5] = byte(v >> 40) + contents[i+6] = byte(v >> 48) + contents[i+7] = byte(v >> 56) } - err = cfg.Storage.Store(ctx, key, contents) + err := cfg.Storage.Store(ctx, key, contents) if err != nil { return err } diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/filestorage.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/filestorage.go index d3df9cf75..77158c1cb 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/filestorage.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/filestorage.go @@ -21,7 +21,6 @@ import ( "fmt" "io" "io/fs" - "log" "os" "path" "path/filepath" @@ -169,9 +168,10 @@ func (s *FileStorage) Filename(key string) string { return filepath.Join(s.Path, filepath.FromSlash(key)) } -// Lock obtains a lock named by the given name. It blocks -// until the lock can be obtained or an error is returned. -func (s *FileStorage) Lock(ctx context.Context, name string) error { +// obtainLock will attempt to obtain a lock for the given name up to the +// number of attempts given. +// if attempts is negative then it will try forever. +func (s *FileStorage) obtainLock(ctx context.Context, name string, attempts int) (bool, error) { filename := s.lockFilename(name) // sometimes the lockfiles read as empty (size 0) - this is either a stale lock or it @@ -180,14 +180,26 @@ func (s *FileStorage) Lock(ctx context.Context, name string) error { var emptyCount int for { + // if attempts is negative then we should allow the loop + // to retry until the context is done, otherwise we decrement + // the remaining attempts if there are any here to ensure we + // don't miss it due to continue statements throughout the loop + switch { + case attempts == 0: + return false, nil + + case attempts > 0: + attempts-- + } + err := createLockfile(filename) if err == nil { // got the lock, yay - return nil + return true, nil } if !os.IsExist(err) { // unexpected error - return fmt.Errorf("creating lock file: %v", err) + return false, fmt.Errorf("creating lock file: %v", err) } // lock file already exists @@ -205,7 +217,7 @@ func (s *FileStorage) Lock(ctx context.Context, name string) error { select { case <-time.After(250 * time.Millisecond): case <-ctx.Done(): - return ctx.Err() + return false, ctx.Err() } continue } else { @@ -213,10 +225,10 @@ func (s *FileStorage) Lock(ctx context.Context, name string) error { // the previous acquirer either crashed or had some sort of failure that // caused them to be unable to fully acquire or retain the lock, therefore // we should treat it as if the lockfile did not exist - log.Printf("[INFO][%s] %s: Empty lockfile (%v) - likely previous process crashed or storage medium failure; treating as stale", s, filename, err2) + defaultLogger.Sugar().Infof("[%s] %s: Empty lockfile (%v) - likely previous process crashed or storage medium failure; treating as stale", s, filename, err2) } } else if err2 != nil { - return fmt.Errorf("decoding lockfile contents: %w", err2) + return false, fmt.Errorf("decoding lockfile contents: %w", err2) } } @@ -227,7 +239,7 @@ func (s *FileStorage) Lock(ctx context.Context, name string) error { case err != nil: // unexpected error - return fmt.Errorf("accessing lock file: %v", err) + return false, fmt.Errorf("accessing lock file: %v", err) case fileLockIsStale(meta): // lock file is stale - delete it and try again to obtain lock @@ -235,11 +247,10 @@ func (s *FileStorage) Lock(ctx context.Context, name string) error { // either have potential to cause infinite loops, as in caddyserver/caddy#4448, // or must give up on perfect mutual exclusivity; however, these cases are rare, // so we prefer the simpler solution that avoids infinite loops) - log.Printf("[INFO][%s] Lock for '%s' is stale (created: %s, last update: %s); removing then retrying: %s", - s, name, meta.Created, meta.Updated, filename) + defaultLogger.Sugar().Infof("[%s] Lock for '%s' is stale (created: %s, last update: %s); removing then retrying: %s", s, name, meta.Created, meta.Updated, filename) if err = os.Remove(filename); err != nil { // hopefully we can replace the lock file quickly! if !errors.Is(err, fs.ErrNotExist) { - return fmt.Errorf("unable to delete stale lockfile; deadlocked: %w", err) + return false, fmt.Errorf("unable to delete stale lockfile; deadlocked: %w", err) } } continue @@ -251,12 +262,30 @@ func (s *FileStorage) Lock(ctx context.Context, name string) error { select { case <-time.After(fileLockPollInterval): case <-ctx.Done(): - return ctx.Err() + return false, ctx.Err() } } } } +// Lock obtains a lock named by the given name. It blocks +// until the lock can be obtained or an error is returned. +func (s *FileStorage) Lock(ctx context.Context, name string) error { + ok, err := s.obtainLock(ctx, name, -1) + if !ok && err == nil { + return errors.New("unable to obtain lock") + } + + return err +} + +// TryLock attempts to obtain a lock named by the given name. +// If the lock was obtained it will return true, otherwise it will +// return false along with any errors that may have occurred. +func (s *FileStorage) TryLock(ctx context.Context, name string) (bool, error) { + return s.obtainLock(ctx, name, 2) +} + // Unlock releases the lock for name. func (s *FileStorage) Unlock(_ context.Context, name string) error { return os.Remove(s.lockFilename(name)) @@ -311,7 +340,7 @@ func keepLockfileFresh(filename string) { if err := recover(); err != nil { buf := make([]byte, stackTraceBufferSize) buf = buf[:runtime.Stack(buf, false)] - log.Printf("panic: active locking: %v\n%s", err, buf) + defaultLogger.Sugar().Errorf("active locking: %v\n%s", err, buf) } }() @@ -319,7 +348,7 @@ func keepLockfileFresh(filename string) { time.Sleep(lockFreshnessInterval) done, err := updateLockfileFreshness(filename) if err != nil { - log.Printf("[ERROR] Keeping lock file fresh: %v - terminating lock maintenance (lockfile: %s)", err, filename) + defaultLogger.Sugar().Errorf("Keeping lock file fresh: %v - terminating lock maintenance (lockfile: %s)", err, filename) return } if done { diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/handshake.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/handshake.go index c8418446a..a227015b1 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/handshake.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/handshake.go @@ -298,9 +298,9 @@ func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.Client // domain, avoid pounding manager or storage thousands of times simultaneously. We use a similar sync // strategy for obtaining certificate during handshake. certLoadWaitChansMu.Lock() - wait, ok := certLoadWaitChans[name] + waiter, ok := certLoadWaitChans[name] if ok { - // another goroutine is already loading the cert; just wait and we'll get it from the in-memory cache + // another goroutine is already loading the cert; just wait certLoadWaitChansMu.Unlock() timeout := time.NewTimer(2 * time.Minute) @@ -310,33 +310,44 @@ func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.Client case <-ctx.Done(): timeout.Stop() return Certificate{}, ctx.Err() - case <-wait: + case <-waiter.done: timeout.Stop() } - return cfg.getCertDuringHandshake(ctx, hello, false) - } else { - // no other goroutine is currently trying to load this cert - wait = make(chan struct{}) - certLoadWaitChans[name] = wait - certLoadWaitChansMu.Unlock() + // If the leader got a result from an external cert manager, use it + // directly — these certs are not added to the cache, so a recursive + // cache lookup would miss. For cached certs (on-demand, managed), + // the waiter result will be empty and we fall through to the + // original recursive lookup. + if !waiter.cert.Empty() || waiter.err != nil { + return waiter.cert, waiter.err + } - // unblock others and clean up when we're done - defer func() { - certLoadWaitChansMu.Lock() - close(wait) - delete(certLoadWaitChans, name) - certLoadWaitChansMu.Unlock() - }() + return cfg.getCertDuringHandshake(ctx, hello, false) } + // no other goroutine is currently trying to load this cert + waiter = &certLoadWaiter{done: make(chan struct{})} + certLoadWaitChans[name] = waiter + certLoadWaitChansMu.Unlock() + + // unblock others and clean up when we're done + defer func() { + certLoadWaitChansMu.Lock() + close(waiter.done) + delete(certLoadWaitChans, name) + certLoadWaitChansMu.Unlock() + }() + // If an external Manager is configured, try to get it from them. // Only continue to use our own logic if it returns empty+nil. externalCert, err := cfg.getCertFromAnyCertManager(ctx, hello, logger) if err != nil { + waiter.err = err return Certificate{}, err } if !externalCert.Empty() { + waiter.cert = externalCert return externalCert, nil } @@ -599,7 +610,11 @@ func (cfg *Config) handshakeMaintenance(ctx context.Context, hello *tls.ClientHe if err != nil { // An error with OCSP stapling is not the end of the world, and in fact, is // quite common considering not all certs have issuer URLs that support it. - logger.Warn("stapling OCSP", zap.Error(err)) + if errors.Is(err, ErrNoOCSPServerSpecified) { + logger.Debug("stapling OCSP", zap.Error(err)) + } else { + logger.Warn("stapling OCSP", zap.Error(err)) + } } else { logger.Debug("successfully stapled new OCSP response", zap.Int("ocsp_status", cert.ocsp.Status), @@ -849,7 +864,7 @@ func (cfg *Config) getCertFromAnyCertManager(ctx context.Context, hello *tls.Cli // solving). True is returned if the challenge is being solved distributed (there // is no semantic difference with distributed solving; it is mainly for logging). func (cfg *Config) getTLSALPNChallengeCert(clientHello *tls.ClientHelloInfo) (*tls.Certificate, bool, error) { - chalData, distributed, err := cfg.getChallengeInfo(clientHello.Context(), clientHello.ServerName) + chalData, distributed, err := cfg.getACMEChallengeInfo(clientHello.Context(), clientHello.ServerName, true) if err != nil { return nil, distributed, err } @@ -942,9 +957,19 @@ var ( obtainCertWaitChansMu sync.Mutex ) +// certLoadWaiter coordinates concurrent certificate loading for the same name. +// The leader populates the result and closes the channel; waiters read the result +// after the channel is closed. This allows externally-managed certificates (which +// are not cached) to be shared directly with waiting goroutines. +type certLoadWaiter struct { + done chan struct{} + cert Certificate + err error +} + // TODO: this lockset should probably be per-cache var ( - certLoadWaitChans = make(map[string]chan struct{}) + certLoadWaitChans = make(map[string]*certLoadWaiter) certLoadWaitChansMu sync.Mutex ) diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/httphandlers.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/httphandlers.go index ffbda8341..0e04fa480 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/httphandlers.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/httphandlers.go @@ -15,6 +15,7 @@ package certmagic import ( + "fmt" "net/http" "net/url" "strings" @@ -72,18 +73,104 @@ func (am *ACMEIssuer) distributedHTTPChallengeSolver(w http.ResponseWriter, r *h return false } host := hostOnly(r.Host) - chalInfo, distributed, err := am.config.getChallengeInfo(r.Context(), host) + chalInfo, distributed, err := am.config.getACMEChallengeInfo(r.Context(), host, !am.DisableDistributedSolvers) if err != nil { + if am.DisableDistributedSolvers { + // Distributed solvers are disabled, so the only way an error can be returned is if + // this instance didn't initiate the challenge (or if the process exited after, but + // either way, we don't have the challenge info). Assuming this is a legitimate + // challenge request, we may still be able to solve it if we can present the correct + // account thumbprint with the token, since the token is given to us in the URL path. + // + // NOTE: About doing this, RFC 8555 section 8.3 says: + // + // Note that because the token appears both in the request sent by the + // ACME server and in the key authorization in the response, it is + // possible to build clients that copy the token from request to + // response. Clients should avoid this behavior because it can lead to + // cross-site scripting vulnerabilities; instead, clients should be + // explicitly configured on a per-challenge basis. A client that does + // copy tokens from requests to responses MUST validate that the token + // in the request matches the token syntax above (e.g., that it includes + // only characters from the base64url alphabet). + // + // Also, since we're just blindly solving a challenge, we're unable to mitigate DNS + // rebinding attacks, because we don't know what host to expect in the URL. So this + // is not ideal, but we do at least validate the copied token is in the base64url set. + if strings.HasPrefix(r.URL.Path, acmeHTTPChallengeBasePath) && + strings.Count(r.URL.Path, "/") == 3 && + r.Method == http.MethodGet { + tokenStart := strings.LastIndex(r.URL.Path, "/") + 1 + token := r.URL.Path[tokenStart:] + if allBase64URL(token) { + if err := am.solveHTTPChallengeBlindly(w, r); err != nil { + am.Logger.Error("solving http-01 challenge blindly", + zap.String("identifier", host), + zap.Error(err)) + } + return true + } + } + } + + // couldn't get challenge info even with distributed solver am.Logger.Warn("looking up info for HTTP challenge", - zap.String("host", host), + zap.String("uri", r.RequestURI), + zap.String("identifier", host), zap.String("remote_addr", r.RemoteAddr), zap.String("user_agent", r.Header.Get("User-Agent")), zap.Error(err)) return false } + return solveHTTPChallenge(am.Logger, w, r, chalInfo.Challenge, distributed) } +// solveHTTPChallengeBlindly will try to respond correctly with an http-01 challenge response. +// The request must be an http-01 challenge request. We cannot know for sure the ACME CA that +// is requesting this, so we have to guess as we load the account to use for a thumbprint as +// part of the response body. It is a no-op if the last component of the URL path contains +// characters outside of the base64url alphabet. +func (am *ACMEIssuer) solveHTTPChallengeBlindly(w http.ResponseWriter, r *http.Request) error { + tokenStart := strings.LastIndex(r.URL.Path, "/") + 1 + token := r.URL.Path[tokenStart:] + if allBase64URL(token) { + acct, err := am.getAccountToUse(r.Context(), am.CA) // assume production CA, I guess + if err != nil { + return fmt.Errorf("getting an account to use: %v", err) + } + thumbprint, err := acct.Thumbprint() + if err != nil { + return fmt.Errorf("could not encode account thumbprint: %v", err) + } + w.Header().Add("Content-Type", "text/plain") + _, _ = w.Write([]byte(token + "." + thumbprint)) + r.Close = true + am.Logger.Info("served key authentication", + zap.String("identifier", hostOnly(r.Host)), + zap.String("challenge", "http-01"), + zap.String("remote", r.RemoteAddr), + zap.Bool("distributed", false), + zap.Bool("blind", true), + zap.String("ca", am.CA)) + } + return nil +} + +// allBase64URL returns true if all characters of s are in the base64url alphabet. +func allBase64URL(s string) bool { + for _, c := range s { + if (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || + c == '-' || c == '_' { + continue + } + return false + } + return true +} + // solveHTTPChallenge solves the HTTP challenge using the given challenge information. // If the challenge is being solved in a distributed fahsion, set distributed to true for logging purposes. // It returns true the properties of the request check out in relation to the HTTP challenge. diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/maintain.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/maintain.go index ed32ec099..bda4a93ff 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/maintain.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/maintain.go @@ -111,7 +111,7 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error { } // the list of names on this cert should never be empty... programmer error? - if cert.Names == nil || len(cert.Names) == 0 { + if len(cert.Names) == 0 { log.Warn("certificate has no names; removing from cache", zap.String("cert_key", certKey)) deleteQueue = append(deleteQueue, cert) continue @@ -125,12 +125,6 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error { zap.Error(err)) continue } - if cfg == nil { - // this is bad if this happens, probably a programmer error (oops) - log.Error("no configuration associated with certificate; unable to manage", - zap.Strings("identifiers", cert.Names)) - continue - } if cfg.OnDemand != nil { continue } @@ -474,7 +468,16 @@ func (cfg *Config) updateARI(ctx context.Context, cert Certificate, logger *zap. // synchronize ARI fetching; see #297 lockName := "ari_" + cert.ari.UniqueIdentifier - if err := acquireLock(ctx, cfg.Storage, lockName); err != nil { + if _, ok := cfg.Storage.(TryLocker); ok { + ok, err := tryAcquireLock(ctx, cfg.Storage, lockName) + if err != nil { + return cert, false, fmt.Errorf("unable to obtain ARI lock: %v", err) + } + if !ok { + logger.Debug("attempted to obtain ARI lock but it was already taken") + return cert, false, nil + } + } else if err := acquireLock(ctx, cfg.Storage, lockName); err != nil { return cert, false, fmt.Errorf("unable to obtain ARI lock: %v", err) } defer func() { diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/ocsp.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/ocsp.go index c87a560fc..82b91dc0d 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/ocsp.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/ocsp.go @@ -53,7 +53,7 @@ func stapleOCSP(ctx context.Context, ocspConfig OCSPConfig, storage Storage, cer // we need a PEM encoding only for some function calls below bundle := new(bytes.Buffer) for _, derBytes := range cert.Certificate.Certificate { - pem.Encode(bundle, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) + _ = pem.Encode(bundle, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) } pemBundle = bundle.Bytes() } @@ -235,6 +235,10 @@ func getOCSPForCert(ocspConfig OCSPConfig, bundle []byte) ([]byte, *ocsp.Respons return nil, nil, fmt.Errorf("parsing OCSP response: %v", err) } + if err := validateOCSPResponder(ocspRes, issuerCert); err != nil { + return nil, nil, fmt.Errorf("OCSP responder authorization check failed: %v", err) + } + return ocspResBytes, ocspRes, nil } @@ -253,3 +257,26 @@ func freshOCSP(resp *ocsp.Response) bool { refreshTime := resp.ThisUpdate.Add(nextUpdate.Sub(resp.ThisUpdate) / 2) return time.Now().Before(refreshTime) } + +// validateOCSPResponder enforces RFC 6960 §4.2.2.2: "Systems or applications that +// rely on OCSP responses MUST be capable of detecting and enforcing the use of the +// id-kp-OCSPSigning value." An issuer-signed response (where the embedded Certificate +// field is nil, meaning the issuer signed directly) is always acceptable. +func validateOCSPResponder(ocspResp *ocsp.Response, issuerCert *x509.Certificate) error { + respCert := ocspResp.Certificate + + // if response was signed directly by the issuer, or embedded responder cert IS the issuer, accept + if respCert == nil || respCert.Equal(issuerCert) { + // Response was signed directly by the issuer — always valid. + return nil + } + + // RFC 6960 §4.2.2.2 requires id-kp-OCSPSigning for delegated responders + for _, eku := range respCert.ExtKeyUsage { + if eku == x509.ExtKeyUsageOCSPSigning { + return nil + } + } + + return fmt.Errorf("OCSP responder certificate (subject: %s) is not the issuer and does not carry id-kp-OCSPSigning", respCert.Subject) +} diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/solvers.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/solvers.go index 677fad3f3..b48013039 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/solvers.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/solvers.go @@ -768,6 +768,8 @@ func dialTCPSocket(addr string) error { // GetACMEChallenge returns an active ACME challenge for the given identifier, // or false if no active challenge for that identifier is known. func GetACMEChallenge(identifier string) (Challenge, bool) { + // Strip brackets from IPv6 addresses (e.g. "[::1]" from HTTP Host headers). + identifier = hostOnly(identifier) activeChallengesMu.Lock() chalData, ok := activeChallenges[identifier] activeChallengesMu.Unlock() diff --git a/plugins/traefik/vendor/github.com/caddyserver/certmagic/storage.go b/plugins/traefik/vendor/github.com/caddyserver/certmagic/storage.go index faf731530..a4ae1fc67 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/certmagic/storage.go +++ b/plugins/traefik/vendor/github.com/caddyserver/certmagic/storage.go @@ -16,6 +16,7 @@ package certmagic import ( "context" + "fmt" "path" "regexp" "strings" @@ -149,6 +150,32 @@ type Locker interface { Unlock(ctx context.Context, name string) error } +type TryLocker interface { + // TryLock attempts to acquire the lock for name, and returns a + // boolean that reports whether the lock was successfully aquired + // or not along with any errors that may have occurred. + // + // Implementations should honor context cancellation. + TryLock(ctx context.Context, name string) (bool, error) + + // Unlock releases named lock. This method must ONLY be called + // after a successful call to TryLock, and only after the critical + // section is finished, even if it errored or timed out. Unlock + // cleans up any resources allocated during TryLock. Unlock should + // only return an error if the lock was unable to be released. + Unlock(ctx context.Context, name string) error +} + +// LockLeaseRenewer is an optional interface that can be implemented by a Storage +// implementation to support renewing the lease on a lock. This is useful for +// long-running operations that need to be synchronized across a cluster. +type LockLeaseRenewer interface { + // RenewLockLease renews the lease on the lock for the given lockKey for the + // given leaseDuration. This is used to prevent the lock from being acquired + // by another process. + RenewLockLease(ctx context.Context, lockKey string, leaseDuration time.Duration) error +} + // KeyInfo holds information about a key in storage. // Key and IsTerminal are required; Modified and Size // are optional if the storage implementation is not @@ -288,6 +315,21 @@ func acquireLock(ctx context.Context, storage Storage, lockKey string) error { return err } +func tryAcquireLock(ctx context.Context, storage Storage, lockKey string) (bool, error) { + locker, ok := storage.(TryLocker) + if !ok { + return false, fmt.Errorf("%T does not implement TryLocker", storage) + } + + ok, err := locker.TryLock(ctx, lockKey) + if ok && err == nil { + locksMu.Lock() + locks[lockKey] = storage + locksMu.Unlock() + } + return ok, err +} + func releaseLock(ctx context.Context, storage Storage, lockKey string) error { err := storage.Unlock(context.WithoutCancel(ctx), lockKey) if err == nil { diff --git a/plugins/traefik/vendor/github.com/caddyserver/zerossl/client.go b/plugins/traefik/vendor/github.com/caddyserver/zerossl/client.go index 75a3de776..0761e1681 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/zerossl/client.go +++ b/plugins/traefik/vendor/github.com/caddyserver/zerossl/client.go @@ -56,55 +56,49 @@ func (c Client) httpRequest(ctx context.Context, method, reqURL string, reqBody if err != nil { return err } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck // because the ZeroSSL API doesn't use HTTP status codes to indicate an error, // nor does each response body have a consistent way of detecting success/error, - // we have to implement a hack: download the entire response body and try - // decoding it as JSON in a way that errors if there's any unknown fields - // (such as "success"), because if there is an unkown field, either our model - // is outdated, or there was an error payload in the response instead of the - // expected structure, so we then try again to decode to an error struct - respBytes, err := io.ReadAll(io.LimitReader(resp.Body, 1024*1024*2)) + // we have to work around this by buffering the entire response body and then + // checking it for expected value(s) to determine if there's an error + respBytes, err := io.ReadAll(io.LimitReader(resp.Body, 1024*1024*5)) if err != nil { return fmt.Errorf("failed reading response body: %v", err) } - // assume success first by trying to decode payload into output target - dec := json.NewDecoder(bytes.NewReader(respBytes)) - dec.DisallowUnknownFields() // important hacky hack so we can detect an error payload - originalDecodeErr := dec.Decode(&target) - if originalDecodeErr == nil { - return nil - } - - // could have gotten any kind of error, really; but assuming valid JSON, - // most likely it is an error payload + // assume error first, since the ZeroSSL API does not use status codes for errors + // (see https://github.com/caddyserver/zerossl/issues/3) var apiError APIError if err := json.NewDecoder(bytes.NewReader(respBytes)).Decode(&apiError); err != nil { - return fmt.Errorf("request succeeded, but decoding JSON response failed: %v (raw=%s)", err, respBytes) + return fmt.Errorf("decoding JSON error body failed: %v (raw=%s)", err, respBytes) } - - // successfully got an error! or did we? - if apiError.Success { - return apiError // ummm... why are we getting an error if it was successful ??? is this not really an error? + if apiError.Success != nil && !*apiError.Success { + // remove access_key from URL so it doesn't leak into logs + u, err := url.Parse(reqURL) + if err != nil { + reqURL = fmt.Sprintf("", err) + } + if u != nil { + q, err := url.ParseQuery(u.RawQuery) + if err == nil { + q.Set(accessKeyParam, "redacted") + u.RawQuery = q.Encode() + reqURL = u.String() + } + } + apiError.URL = reqURL + return apiError } - // remove access_key from URL so it doesn't leak into logs - u, err := url.Parse(reqURL) - if err != nil { - reqURL = fmt.Sprintf("", err) - } - if u != nil { - q, err := url.ParseQuery(u.RawQuery) - if err == nil { - q.Set(accessKeyParam, "redacted") - u.RawQuery = q.Encode() - reqURL = u.String() + // if there was no error, decode into target payload + if target != nil { + if err = json.NewDecoder(bytes.NewReader(respBytes)).Decode(target); err != nil { + return fmt.Errorf("request succeeded, but decoding JSON response body failed: %v (raw=%s)", err, respBytes) } } - return fmt.Errorf("%s %s: HTTP %d: %v (raw=%s decode_error=%v)", method, reqURL, resp.StatusCode, apiError, respBytes, originalDecodeErr) + return nil } func (c Client) url(endpoint string, qs url.Values) string { diff --git a/plugins/traefik/vendor/github.com/caddyserver/zerossl/endpoints.go b/plugins/traefik/vendor/github.com/caddyserver/zerossl/endpoints.go index 3fabd44a4..1b98db6cf 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/zerossl/endpoints.go +++ b/plugins/traefik/vendor/github.com/caddyserver/zerossl/endpoints.go @@ -79,7 +79,7 @@ func (c Client) DownloadCertificateFile(ctx context.Context, certificateID strin if err != nil { return err } - defer resp.Body.Close() + defer resp.Body.Close() //nolint:errcheck if resp.StatusCode != http.StatusOK { return fmt.Errorf("unexpected status code: HTTP %d", resp.StatusCode) } @@ -201,7 +201,7 @@ func (c Client) RevokeCertificate(ctx context.Context, certificateID string, rea var result struct { Success anyBool `json:"success"` } - if err := c.httpGet(ctx, endpoint, qs, &result); err != nil { + if err := c.httpPost(ctx, endpoint, qs, nil, &result); err != nil { return err } @@ -255,7 +255,6 @@ func (c Client) ValidateCSR(ctx context.Context, csrASN1DER []byte) error { func (c Client) GenerateEABCredentials(ctx context.Context) (keyID, hmacKey string, err error) { var result struct { - APIError EABKID string `json:"eab_kid"` EABHMACKey string `json:"eab_hmac_key"` } @@ -263,8 +262,5 @@ func (c Client) GenerateEABCredentials(ctx context.Context) (keyID, hmacKey stri if err != nil { return } - if !result.Success { - err = fmt.Errorf("failed to create EAB credentials: %v", result.APIError) - } return result.EABKID, result.EABHMACKey, err } diff --git a/plugins/traefik/vendor/github.com/caddyserver/zerossl/models.go b/plugins/traefik/vendor/github.com/caddyserver/zerossl/models.go index 80475f0eb..3d0b99de3 100644 --- a/plugins/traefik/vendor/github.com/caddyserver/zerossl/models.go +++ b/plugins/traefik/vendor/github.com/caddyserver/zerossl/models.go @@ -3,7 +3,7 @@ package zerossl import "fmt" type APIError struct { - Success anyBool `json:"success"` + Success *anyBool `json:"success,omitempty"` ErrorInfo struct { Code int `json:"code"` Type string `json:"type"` @@ -13,14 +13,18 @@ type APIError struct { // for HTTP validation Details map[string]map[string]ValidationError `json:"details"` } `json:"error"` + + // added after decoding so we can make a more descriptive error message, + // but only after stripping credentials from it + URL string `json:"-"` } func (ae APIError) Error() string { if ae.ErrorInfo.Code == 0 && ae.ErrorInfo.Type == "" && len(ae.ErrorInfo.Details) == 0 { return "" } - return fmt.Sprintf("API error %d: %s (details=%v)", - ae.ErrorInfo.Code, ae.ErrorInfo.Type, ae.ErrorInfo.Details) + return fmt.Sprintf("API error %d (%s): %s (details=%v)", + ae.ErrorInfo.Code, ae.ErrorInfo.Type, ae.URL, ae.ErrorInfo.Details) } type ValidationError struct { @@ -60,6 +64,7 @@ type CertificateObject struct { EmailValidation map[string][]string `json:"email_validation,omitempty"` OtherMethods map[string]ValidationObject `json:"other_methods,omitempty"` } `json:"validation,omitempty"` + SignatureAlgorithmProperties any `json:"signature_algorithm_properties,omitempty"` // unsure what this is, but fixes #3 } type ValidationObject struct { diff --git a/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.editorconfig b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.editorconfig new file mode 100644 index 000000000..f32456b1d --- /dev/null +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.editorconfig @@ -0,0 +1,25 @@ +# More information about this file +# https://editorconfig.org +root = true + +[*] +charset = utf-8 +end_of_line = lf + +[*.md] +tab_width = 2 +trim_trailing_whitespace = false # can be used for indentation with double spaces +# Not enforced, markdownlint already reports it +#insert_final_newline = true + +[*.{yml,yaml}] +tab_width = 2 +trim_trailing_whitespace = true +# Not enforced, markdownlint already reports it +#insert_final_newline = true + +[*.toml,.ini] +tab_width = 2 +trim_trailing_whitespace = true +insert_final_newline = true + diff --git a/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.gitattributes b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.gitattributes new file mode 100644 index 000000000..a681ce365 --- /dev/null +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.gitattributes @@ -0,0 +1,4 @@ +# ensure that line endings for Windows builds are properly formatted +# see https://github.com/golangci/golangci-lint-action?tab=readme-ov-file#how-to-use +# at "Multiple OS Example" section +*.go text eol=lf diff --git a/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.golangci.yml b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.golangci.yml new file mode 100644 index 000000000..1c2d26df1 --- /dev/null +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.golangci.yml @@ -0,0 +1,190 @@ +--- +# golangci-lint configuration file made by @ccoVeille +# Source: https://github.com/ccoVeille/golangci-lint-config-examples/ +# Author: @ccoVeille +# License: MIT +# Variant: 03-safe +# Version: v2.0.0 +# +version: "2" + +formatters: + enable: + # format the code + - gofmt + # format the block of imports + - gci + + settings: + # format the code with Go standard library + gofmt: + # simplify the code + # https://pkg.go.dev/cmd/gofmt#hdr-The_simplify_command + simplify: true + rewrite-rules: + # replace `interface{}` with `any` in the code on format + - pattern: 'interface{}' + replacement: 'any' + + # make sure imports are always in a deterministic order + # https://github.com/daixiang0/gci/ + gci: # define the section orders for imports + sections: + # Standard section: captures all standard packages. + - standard + # Default section: catchall that is not standard or custom + - default + # linters that related to local tool, so they should be separated + - localmodule + +linters: + enable: + # Errcheck is a program for checking for unchecked errors in Go code. + - errcheck + + # Vet examines Go source code and reports suspicious constructs. + - govet + + # Detects when assignments to existing variables are not used. + - ineffassign + + # It's a set of rules from staticcheck. See https://staticcheck.io/ + - staticcheck + + # Checks Go code for unused constants, variables, functions and types. + - unused + + # Fast, configurable, extensible, flexible, and beautiful linter for Go. + # Drop-in replacement of golint. + - revive + + # make sure to use t.Helper() when needed + - thelper + + # checks if package imports are in a list of acceptable packages. + - depguard + + # mirror suggests rewrites to avoid unnecessary []byte/string conversion + - mirror + + # detect the possibility to use variables/constants from the Go standard library. + - usestdlibvars + + # Finds commonly misspelled English words. + - misspell + + # Checks for duplicate words in the source code. + - dupword + + # gosec is a security linter for Go code. + - gosec + + # Reports uses of functions with replacement inside the testing package. + - usetesting + + + settings: + + depguard: + rules: + # enforce the library has no dependencies except the standard library + code: + files: + - '!$test' + allow: + - $gostd + # enforce the test files have no dependencies except the standard library and the library itself + test: + files: + - $test + allow: + - $gostd + - github.com/ccoveille/go-safecast + + revive: + rules: + # Blank import should be only in a main or test package, or have a comment justifying it. + - name: blank-imports + + # context.Context() should be the first parameter of a function when provided as argument. + - name: context-as-argument + arguments: + - allowTypesBefore: "*testing.T" + + # Basic types should not be used as a key in `context.WithValue` + - name: context-keys-type + + # Importing with `.` makes the programs much harder to understand + - name: dot-imports + + # Empty blocks make code less readable and could be a symptom of a bug or unfinished refactoring. + - name: empty-block + + # for better readability, variables of type `error` must be named with the prefix `err`. + - name: error-naming + + # for better readability, the errors should be last in the list of returned values by a function. + - name: error-return + + # for better readability, error messages should not be capitalized or end with punctuation or a newline. + - name: error-strings + + # report when replacing `errors.New(fmt.Sprintf())` with `fmt.Errorf()` is possible + - name: errorf + + # exported functions, structs, and methods should have comments. + - name: exported + arguments: + # make error messages clearer + - "sayRepetitiveInsteadOfStutters" + + # enforces conventions on source file names. + - name: filename-format + + # incrementing an integer variable by 1 is recommended to be done using the `++` operator + - name: increment-decrement + + # highlights redundant else-blocks that can be eliminated from the code + - name: indent-error-flow + + # This rule suggests a shorter way of writing ranges that do not use the second value. + - name: range + + # receiver names in a method should reflect the struct name (p for Person, for example) + - name: receiver-naming + + # redefining built in names (true, false, append, make) can lead to bugs very difficult to detect. + - name: redefines-builtin-id + + # redundant else-blocks that can be eliminated from the code. + - name: superfluous-else + + # prevent confusing name for variables when using `time` package + - name: time-naming + + # warns when an exported function or method returns a value of an un-exported type. + - name: unexported-return + + # spots and proposes to remove unreachable code. also helps to spot errors + - name: unreachable-code + + # Functions or methods with unused parameters can be a symptom of an unfinished refactoring or a bug. + - name: unused-parameter + + # report when a variable declaration can be simplified + - name: var-declaration + + # warns when initialism, variable or package naming conventions are not followed. + - name: var-naming + + misspell: + # Correct spellings using locale preferences for US or UK. + # Setting locale to US will correct the British spelling of 'colour' to 'color'. + # Default ("") is to use a neutral variety of English. + locale: US + +output: + sort-order: + - linter + - severity + - file # filepath, line, and column. diff --git a/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.ls-lint.yml b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.ls-lint.yml new file mode 100644 index 000000000..9e34b8a8b --- /dev/null +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.ls-lint.yml @@ -0,0 +1,17 @@ +--- +# ls-lint configuration file. More information on the file format can be found on https://ls-lint.org/ +ls: + .md: screamingsnakecase # README.md or CODE_OF_CONDUCT.md + + # DEACTIVATED: Go files should are linted via golangci-lint revive filename-format rule + # .go: snakecase + +ignore: + # .git folder cannot be linted + - .git + # .github folder contains configuration files with specific name, and should not be linted + - .github + # dot files are usually configuration files with specific name + - .ls-lint.yml + - .markdownlint.yml + - .yamllint.yml diff --git a/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.markdownlint.yml b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.markdownlint.yml new file mode 100644 index 000000000..fe687e0ca --- /dev/null +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.markdownlint.yml @@ -0,0 +1,14 @@ +--- + +# Default state for all rules +default: true + +MD013: + # Overload the default value (120) + line_length: 200 + +MD033: + allowed_elements: + #
are useful for spoilers + - summary + - details diff --git a/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.yamllint.yml b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.yamllint.yml new file mode 100644 index 000000000..f67627c99 --- /dev/null +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/.yamllint.yml @@ -0,0 +1,14 @@ +--- +extends: default +ignore: + # These files are imported by vale from an external repository + .vale/styles/RedHat/ +rules: + line-length: + max: 200 + allow-non-breakable-words: true + allow-non-breakable-inline-mappings: true + truthy: + # the node "on:" present in each GitHub Actions workflow file + ignore: | + .github/ diff --git a/plugins/traefik/vendor/github.com/go-kit/log/LICENSE b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/LICENSE similarity index 97% rename from plugins/traefik/vendor/github.com/go-kit/log/LICENSE rename to plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/LICENSE index bb5bdb9cb..7f8b751c2 100644 --- a/plugins/traefik/vendor/github.com/go-kit/log/LICENSE +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Go kit +Copyright (c) 2024 ccoVeille Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/README.md b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/README.md new file mode 100644 index 000000000..46715c34e --- /dev/null +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/README.md @@ -0,0 +1,163 @@ +# 🪄 go-safecast: safe numbers conversion + +[![Go Report Card](https://goreportcard.com/badge/github.com/ccoveille/go-safecast)](https://goreportcard.com/report/github.com/ccoveille/go-safecast) +[![GoDoc](https://godoc.org/github.com/ccoVeille/go-safecast?status.svg)](https://godoc.org/github.com/ccoVeille/go-safecast/v2) +[![codecov](https://codecov.io/gh/ccoVeille/go-safecast/graph/badge.svg?token=VW0VO503U6)](https://codecov.io/gh/ccoVeille/go-safecast) +[![Go Imports](https://img.shields.io/github/search?query=%22%5C%22github.com%2Fccoveille%2Fgo-safecast%5C%22%22%20language%3Ago%20%20-is%3Afork%20-is%3Aarchived%20&label=Go%20imports)](https://github.com/search?q=%22%5C%22github.com%2Fccoveille%2Fgo-safecast%5C%22%22+language%3Ago++-is%3Afork+-is%3Aarchived+&type=code) +![GitHub Repo stars](https://img.shields.io/github/stars/ccoveille/go-safecast) + +go-safecast solves the type conversion issues in Go + +In Go, integer type conversion can lead to a silent and unexpected behavior and errors if not handled carefully. + +This package helps to convert any number to another, and report an error when if there would be a [loss or overflow in the conversion](#conversion-issues) + +## Usage + +```go +package main + +import ( + "fmt" + "math" + + "github.com/ccoveille/go-safecast/v2" +) + +func main() { + var a int64 + + a = 42 + b, err := safecast.Convert[int16](a) // everything is fine because 42 fits in int16 + if err != nil { + fmt.Println(err) + } + fmt.Println(b) + + a = 255 + 1 + _, err = safecast.Convert[uint8](a) // 256 is greater than uint8 maximum value + if err != nil { + // Output: conversion issue: 256 (int64) is greater than 255 (uint8): maximum value for this type exceeded + fmt.Println(err) + } + + a = -1 + _, err = safecast.Convert[uint64](a) // -1 cannot fit in uint64 + if err != nil { + // Output: conversion issue: -1 (int64) is less than 0 (uint64): minimum value for this type exceeded + fmt.Println(err) + } + + str := "\x99" // ASCII code 153 for Trademark symbol + e := str[0] // e is a rune (uint8) + _, err = safecast.Convert[int8](e) + if err != nil { + // Output: conversion issue: 153 (uint8) is greater than 127 (int8): maximum value for this type exceeded + fmt.Println(err) + } +} +``` + +[Go Playground](https://go.dev/play/p/OC9ueLHY0D2) + +## Conversion issues + +Issues can happen when converting between signed and unsigned integers, or when converting to a smaller integer type. + +```go +package main + +import "fmt" + +func main() { + var a int64 + a = 42 + b := uint8(a) + fmt.Println(b) // 42 + + a = 255 // this is the math.MaxUint8 + b = uint8(a) + fmt.Println(b) // 255 + + a = 255 + 1 + b = uint8(a) + fmt.Println(b) // 0 conversion overflow + + a = -1 + b = uint8(a) + fmt.Println(b) // 255 conversion overflow +} +``` + +[Go Playground](https://go.dev/play/p/DHfNUcZBvVn) + +So you need to adapt your code to write something like this. + +```go +package main + +import "fmt" + +func main() { + var a int64 + a = 42 + if a < 0 || a > math.MaxUint8 { + log.Println("overflow") // Output: overflow + } + fmt.Println(b) // 42 + + a = 255 // this is the math.MaxUint8 + b = uint8(a) + fmt.Println(b) // 255 + + a = 255 + 1 + b = uint8(a) + if a < 0 || a > math.MaxUint8 { + log.Println("overflow") // Output: overflow + } + fmt.Println(b) // Output: 0 + + a = -1 + b = uint8(a) + if a < 0 || a > math.MaxUint8 { + log.Println("overflow") // Output: overflow + } + fmt.Println(b) // Output:255 +} +``` + +[Go Playground](https://go.dev/play/p/qAHGyy4NCLP) + +`go-safecast` is there to avoid boilerplate copy pasta. + +## Motivation + +The gosec project raised this to my attention when the gosec [G115 rule was added](https://github.com/securego/gosec/pull/1149) + +> G115: Potential overflow when converting between integer types. + +This issue was way more complex than expected, and required multiple fixes. + +[CWE-190](https://cwe.mitre.org/data/definitions/190.html) explains in detail. + +But to sum it up, you can face: + +- infinite loop +- access to wrong resource by id +- grant access to someone who exhausted their quota + +The gosec G115 will now report issues in a lot of project. + +## Alternatives + +Some libraries existed, but they were not able to cover all the use cases. + +- [github.com/rung/go-safecast](https://github.com/rung/go-safecast): + Unmaintained, not architecture agnostic, do not support `uint` -> `int` conversion + +- [github.com/cybergarage/go-safecast](https://github.com/cybergarage/go-safecast) + Work with pointer like `json.Marshall` + +## Stargazers over time + +[![Stargazers over time](https://starchart.cc/ccoVeille/go-safecast.svg?variant=adaptive)](https://starchart.cc/ccoVeille/go-safecast) diff --git a/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/conversion.go b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/conversion.go new file mode 100644 index 000000000..4925c84fe --- /dev/null +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/conversion.go @@ -0,0 +1,163 @@ +package safecast + +import ( + "math" +) + +// MustConvert calls [Convert] to convert the value to the desired type, and panics if the conversion fails. +func MustConvert[NumOut Number, NumIn Number](orig NumIn) NumOut { + converted, err := Convert[NumOut](orig) + if err != nil { + panic(err) + } + return converted +} + +// TestingT is an interface wrapper used by [RequireConvert] that we need for testing purposes. +// +// Only the methods used by [RequireConvert] are expected to be implemented. +// +// [*testing.T], [*testing.B], or [*testing.F] types satisfy this interface. +type TestingT interface { + Helper() + Fatal(args ...any) +} + +// RequireConvert is a test helper that calls [Convert] that converts the value to the desired type, +// and fails the test if the conversion fails. +func RequireConvert[NumOut Number, NumIn Number](t TestingT, orig NumIn) (converted NumOut) { + t.Helper() + + converted, err := Convert[NumOut](orig) + if err != nil { + t.Fatal(err) + } + return converted +} + +// Convert attempts to convert any [Number] to the desired [Number] type. +// +// # Behavior +// +// - If the conversion is possible, the converted value is returned. +// +// # Errors when conversion exceeds range of the desired type, the following errors are wrapped in the returned error: +// +// - [ErrRangeOverflow] when the value is outside the range of the desired type. (example: 1000 or -1 to uint8). +// - [ErrExceedMaximumValue] when the value exceeds the maximum value of the desired type (example: 1000 to uint8). +// - [ErrExceedMinimumValue] when the value is less than the minimum value of the desired type (example: -1 to uint16). +// +// # Errors when conversion is not possible, the following errors are wrapped in the returned error: +// +// - [ErrorUnsupportedConversion] when the conversion is not possible for the desired type (example: NaN to int). +// - [ErrStringConversion] when the conversion from string fails (example: "abc" to int). +// +// # General errors wrapped on conversion failure: +// +// - [ErrConversionIssue] is always wrapped in the returned error when [Convert] fails (example "abc", -1, or 1000 to uint8). +func Convert[NumOut Number, NumIn Number](orig NumIn, opts ...ConvertOption) (NumOut, error) { + converted := NumOut(orig) + if isFloat64[NumIn]() { + floatOrig := float64(orig) + if math.IsInf(floatOrig, 1) || math.IsInf(floatOrig, -1) { + return converted, getRangeError[NumOut](orig) + } + if math.IsNaN(floatOrig) { + return converted, errorHelper[NumOut]{ + value: orig, + err: ErrUnsupportedConversion, + } + } + } + + config := newConvertOptions(opts...) + + if isFloat64[NumOut]() { + // float64 cannot overflow, so we don't have to worry about it + return converted, nil + } + + if isFloat32[NumOut]() { + // check boundary + if math.Abs(float64(orig)) < math.MaxFloat32 { + // the value is within float32 range, there is no overflow + return converted, nil + } + + // TODO: check for numbers close to math.MaxFloat32 + + return converted, getRangeError[NumOut](orig) + } + + if !sameSign(orig, converted) { + return converted, getRangeError[NumOut](orig) + } + + // and compare + base := orig + if isFloat[NumIn]() { + base = NumIn(math.Trunc(float64(orig))) + } + + // convert back to the original type + cast := NumIn(converted) + if cast != base { + return converted, getRangeError[NumOut](orig) + } + + if config.reportDecimalLoss && isFloat[NumIn]() && !isFloat[NumOut]() { + if orig != cast { + return converted, errorHelper[NumOut]{ + value: orig, + err: ErrDecimalLoss, + } + } + } + + return converted, nil +} + +func getRangeError[NumOut Number, NumIn Number](value NumIn) error { + err := ErrExceedMaximumValue + if value < 0 { + err = ErrExceedMinimumValue + } + + return errorHelper[NumOut]{ + value: value, + err: err, + } +} + +type convertConfig struct { + reportDecimalLoss bool +} + +// ConvertOption is a function type used to set options for the [Convert] function. +type ConvertOption func(*convertConfig) + +func newConvertOptions(opts ...ConvertOption) *convertConfig { + po := &convertConfig{ + reportDecimalLoss: false, + } + + for _, opt := range opts { + opt(po) + } + return po +} + +// WithDecimalLossReport is a [ConvertOption] that enables reporting of decimal loss +// when converting from a floating-point type to an integer type. +// +// When this option is used, if the conversion results in loss of decimal information, +// the returned error will wrap [ErrDecimalLoss]. +// +// Example: +// +// value, err := Convert[int](3.14, WithDecimalLossReport()) +func WithDecimalLossReport() ConvertOption { + return func(cfg *convertConfig) { + cfg.reportDecimalLoss = true + } +} diff --git a/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/doc.go b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/doc.go new file mode 100644 index 000000000..b236245c0 --- /dev/null +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/doc.go @@ -0,0 +1,5 @@ +// Package safecast solves the type conversion issues in Go +// +// In Go, integer type conversion can lead to unexpected behavior and errors if not handled carefully. +// Issues can happen when converting between signed and unsigned integers, or when converting to a smaller integer type. +package safecast diff --git a/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/errors.go b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/errors.go new file mode 100644 index 000000000..fd4b204eb --- /dev/null +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/errors.go @@ -0,0 +1,105 @@ +package safecast + +import ( + "errors" + "fmt" +) + +// ErrConversionIssue is a generic error for type conversion issues +// +// This error is wrapped in all errors reported by this package +var ErrConversionIssue = errors.New("conversion issue") + +// ErrRangeOverflow is an error for when the value is outside the range of the desired type +// +// Examples include converting 1000 or -1 to uint8. +// +// This is error is wrapped by [ErrExceedMaximumValue] and [ErrExceedMinimumValue] +// It can be used to check for range overflow issues in a generic way. +// +// [ErrConversionIssue] is also wrapped when this error is returned. +var ErrRangeOverflow = errors.New("range overflow") + +// ErrExceedMaximumValue is an error for when the value is greater than the maximum value of the desired type. +// +// Examples include converting 1000 to uint8. +// +// [ErrRangeOverflow] and [ErrConversionIssue] are also wrapped when this error is returned. +var ErrExceedMaximumValue = errors.New("maximum value for this type exceeded") + +// ErrExceedMinimumValue is an error for when the value is less than the minimum value of the desired type. +// +// Examples include converting -1 to uint16. +// +// [ErrRangeOverflow] and [ErrConversionIssue] are also wrapped when this error is returned. +var ErrExceedMinimumValue = errors.New("minimum value for this type exceeded") + +// ErrUnsupportedConversion is an error for when the conversion is not supported from the provided type. +// +// Examples include converting [math.NaN] to int. +// +// [ErrConversionIssue] is also wrapped when this error is returned. +var ErrUnsupportedConversion = errors.New("unsupported type") + +// ErrStringConversion is an error for when the conversion fails from string. +// +// Examples include converting "abc" to int. +// +// [ErrConversionIssue] is also wrapped when this error is returned. +var ErrStringConversion = errors.New("cannot convert from string") + +// ErrDecimalLoss is an error for when decimal loss occurs during conversion. +// +// Examples include converting 3.14 to int. +// +// [ErrConversionIssue] is also wrapped when this error is returned. +var ErrDecimalLoss = errors.New("decimal loss during conversion") + +// errorHelper is a helper struct for error messages +// It is used to wrap other errors, and provides additional information +type errorHelper[NumOut Number] struct { + numberBase numberBase // base for number conversion, if applicable + value any + err error +} + +func (e errorHelper[NumOut]) Error() string { + errMessage := ErrConversionIssue.Error() + + switch { + case errors.Is(e.err, ErrExceedMaximumValue): + boundary := maxOf[NumOut]() + errMessage = fmt.Sprintf("%s: %v (%T) is greater than %v (%T)", errMessage, e.value, e.value, boundary, boundary) + case errors.Is(e.err, ErrExceedMinimumValue): + boundary := minOf[NumOut]() + errMessage = fmt.Sprintf("%s: %v (%T) is less than %v (%T)", errMessage, e.value, e.value, boundary, boundary) + case errors.Is(e.err, ErrUnsupportedConversion): + errMessage = fmt.Sprintf("%s: %v (%T) is not supported", errMessage, e.value, e.value) + case errors.Is(e.err, ErrStringConversion): + baseInfoSuffix := e.numberBase.String() + if baseInfoSuffix != "" { + baseInfoSuffix = " (base " + baseInfoSuffix + ")" + } + targetType := NumOut(0) + return fmt.Sprintf("%s: cannot convert from %#q to %T%s", errMessage, e.value, targetType, baseInfoSuffix) + } + + if e.err != nil { + errMessage = fmt.Sprintf("%s: %s", errMessage, e.err.Error()) + } + return errMessage +} + +func (e errorHelper[NumOut]) Unwrap() []error { + errs := []error{ErrConversionIssue} + if e.err != nil { + switch { + case + errors.Is(e.err, ErrExceedMaximumValue), + errors.Is(e.err, ErrExceedMinimumValue): + errs = append(errs, ErrRangeOverflow) + } + errs = append(errs, e.err) + } + return errs +} diff --git a/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/parse.go b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/parse.go new file mode 100644 index 000000000..4d27ce5db --- /dev/null +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/parse.go @@ -0,0 +1,223 @@ +package safecast + +import ( + "errors" + "strconv" + "strings" +) + +// Parse attempts to convert any string to the desired [Number] type. +// +// # Concept +// +// Parse is a convenient wrapper around [strconv.ParseInt], [strconv.ParseUint], and [strconv.ParseFloat]. +// +// # Behavior +// +// If the conversion is possible, the converted value is returned. +// +// # Errors when conversion exceeds range of the desired type, the following errors are wrapped in the returned error: +// +// - [ErrRangeOverflow] when the value is outside the range of the desired type. (example: "1000" or "-1" to uint8). +// - [ErrExceedMaximumValue] when the value exceeds the maximum value of the desired type (example: "1000" to uint8). +// - [ErrExceedMinimumValue] when the value is less than the minimum value of the desired type (example: "-1" to uint16). +// +// # General errors wrapped on parsing and conversion failure: +// +// - [ErrStringConversion] and [ErrConversionIssue] are wrapped when the conversion from string fails (example: "abc" to int). +// +// # Options +// +// The behavior of the parsing can be modified using [ParseOption]s. +// By default, the number base is set to decimal (base 10). +// +// Use one of the provided option functions to set the desired behavior. +// See [WithBaseDecimal], [WithBaseHexadecimal], [WithBaseOctal], [WithBaseBinary], and [WithBaseAutoDetection]. +func Parse[NumOut Number](s string, opts ...ParseOption) (converted NumOut, err error) { + options := newParseOptions(opts...) + numberBase := options.numberBase + + // naive auto-detection of the sign + isNegative := strings.HasPrefix(s, "-") + + // naive auto-detection of float + if strings.Contains(s, ".") { + o, err := strconv.ParseFloat(s, 64) + if err != nil { + errParseFloat := ErrStringConversion + if errors.Is(err, strconv.ErrRange) { + errParseFloat = ErrExceedMaximumValue + if isNegative { + errParseFloat = ErrExceedMinimumValue + } + } + + // If the error is a range error, wrap it in an errorHelper + return 0, errorHelper[NumOut]{ + numberBase: numberBase, + value: s, + err: errParseFloat, + } + } + return Convert[NumOut](o) + } + + if isNegative { + o, err := strconv.ParseInt(s, int(options.numberBase), 64) + if err != nil { + errParseInt := ErrStringConversion + if errors.Is(err, strconv.ErrRange) { + errParseInt = ErrExceedMinimumValue + if isNegative { + errParseInt = ErrExceedMinimumValue + } + } + return 0, errorHelper[NumOut]{ + numberBase: numberBase, + value: s, + err: errParseInt, + } + } + + return Convert[NumOut](o) + } + + o, err := strconv.ParseUint(s, int(options.numberBase), 64) + if err != nil { + errParseUint := ErrStringConversion + if errors.Is(err, strconv.ErrRange) { + errParseUint = ErrExceedMaximumValue + } + return 0, errorHelper[NumOut]{ + numberBase: numberBase, + value: s, + err: errParseUint, + } + } + return Convert[NumOut](o) +} + +// MustParse calls [Parse] to convert the value to the desired type, and panics if the conversion fails. +func MustParse[NumOut Number](orig string, opts ...ParseOption) NumOut { + converted, err := Parse[NumOut](orig, opts...) + if err != nil { + panic(err) + } + return converted +} + +// RequireParse is a test helper that calls [Parse] that converts the value to the desired type, +// and fails the test if the conversion fails. +func RequireParse[NumOut Number](t TestingT, orig string, opts ...ParseOption) (converted NumOut) { + t.Helper() + + converted, err := Parse[NumOut](orig, opts...) + if err != nil { + t.Fatal(err) + } + return converted +} + +// ParseOption defines options for the [Parse] function. +// +// Use one of the provided option functions to set the desired behavior. +// See [WithBaseDecimal], [WithBaseHexadecimal], [WithBaseOctal], [WithBaseBinary], and [WithBaseAutoDetection]. +type ParseOption func(*parseConfig) + +func newParseOptions(opts ...ParseOption) *parseConfig { + po := &parseConfig{ + numberBase: baseDecimal, // default to base 10 + } + + for _, opt := range opts { + opt(po) + } + return po +} + +type numberBase int + +const ( + baseAuto numberBase = 0 + baseHexadecimal numberBase = 16 + baseDecimal numberBase = 10 + baseOctal numberBase = 8 + baseBinary numberBase = 2 +) + +func (nb numberBase) String() string { + switch nb { + case baseAuto: + return "auto-detection" + case baseHexadecimal: + return "hexadecimal" + case baseOctal: + return "octal" + case baseBinary: + return "binary" + default: + return "" // decimal is the default, so we return empty string + } +} + +type parseConfig struct { + numberBase numberBase +} + +// WithBaseDecimal sets the number base to decimal (base 10) when used with [Parse]. +// +// This is the default behavior of [Parse]. +func WithBaseDecimal() ParseOption { + return func(pc *parseConfig) { + pc.numberBase = baseDecimal + } +} + +// WithBaseHexadecimal sets the number base to hexadecimal (base 16) when used with [Parse]. +// +// Note that the string to parse must not have the "0x" prefix; use [WithBaseAutoDetection] for that. +func WithBaseHexadecimal() ParseOption { + return func(pc *parseConfig) { + pc.numberBase = baseHexadecimal + } +} + +// WithBaseOctal sets the number base to octal (base 8) when used with [Parse]. +// +// Note that the string to parse must not have the "0o" prefix; use [WithBaseAutoDetection] for that. +func WithBaseOctal() ParseOption { + return func(pc *parseConfig) { + pc.numberBase = baseOctal + } +} + +// WithBaseBinary sets the number base to binary (base 2) when used with [Parse]. +// +// Note that the string to parse must not have the "0b" prefix; use [WithBaseAutoDetection] for that. +func WithBaseBinary() ParseOption { + return func(pc *parseConfig) { + pc.numberBase = baseBinary + } +} + +// WithBaseAutoDetection sets the number base to auto-detection when used with [Parse]. +// +// The base is implied by the string's prefix following the sign (if present): 2 for "0b", 8 for "0" or "0o", +// 16 for "0x", and 10 otherwise. +// +// Also, underscore characters are permitted as defined by the Go syntax for [integer literals]. +// +// For more details on how auto-detection works, see the documentation of [strconv.ParseInt] or [strconv.ParseUint]. +// +// # ⚠️ Warning: this option comes with some caveats that come from Go [strconv] package and Go [integer literals]. +// +// A string starting with "0" (and not "0x" or "0b") is interpreted as octal, which can lead to unexpected results. +// - "010" is interpreted as 8 in decimal, not 10. +// - "07" is interpreted as 7 in decimal, but "08" or "09" will fail to parse because 8 and 9 are not valid octal digits. +// +// [integer literals]: https://go.dev/ref/spec#Integer_literals +func WithBaseAutoDetection() ParseOption { + return func(pc *parseConfig) { + pc.numberBase = baseAuto + } +} diff --git a/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/types.go b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/types.go new file mode 100644 index 000000000..ca5898ec1 --- /dev/null +++ b/plugins/traefik/vendor/github.com/ccoveille/go-safecast/v2/types.go @@ -0,0 +1,82 @@ +package safecast + +import ( + "math" +) + +// Number is a constraint for all integers and floats +type Number interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~float32 | ~float64 | ~uintptr + + // TODO(ccoVeille): consider using complex, but not sure if there is a need +} + +func isNegative[T Number](t T) bool { + return t < 0 +} + +func sameSign[T1, T2 Number](a T1, b T2) bool { + return isNegative(a) == isNegative(b) +} + +func isUnsigned[T Number]() bool { + v := -1 + return T(v) >= 0 +} +func isFloat[T Number]() bool { + v := 0.1 + return T(v) != 0 +} + +func isFloat32[T Number]() bool { + if !isFloat[T]() { + return false + } + v := math.SmallestNonzeroFloat64 + return T(v*0.9) == 0 +} + +func isFloat64[T Number]() bool { + return isFloat[T]() && !isFloat32[T]() +} + +func sizeOf[T Number]() uint64 { + if isFloat32[T]() { + return 4 + } + + x := uint16(1 << 8) + y := uint32(2 << 16) + z := uint64(4 << 32) + + return 1 + uint64(T(x))>>8 + uint64(T(y))>>16 + uint64(T(z))>>32 +} + +func minOf[T Number]() any { + switch { + case isFloat64[T](): + return float64(-math.MaxFloat64) + case isFloat32[T](): + return float32(-math.MaxFloat32) + case isUnsigned[T](): + return T(0) + } + v := int64(1) << (8*sizeOf[T]() - 1) + return T(v) +} + +func maxOf[T Number]() any { + switch { + case isFloat64[T](): + return float64(math.MaxFloat64) + // there is no case for float64, as nothing can overflow it + case isFloat32[T](): + return float32(math.MaxFloat32) + } + v := uint64(1)<<(8*sizeOf[T]()-1) - 1 + if isUnsigned[T]() { + v = v*2 + 1 + } + + return T(v) +} diff --git a/plugins/traefik/vendor/github.com/jackc/pgx/v4/.gitignore b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/.gitignore similarity index 94% rename from plugins/traefik/vendor/github.com/jackc/pgx/v4/.gitignore rename to plugins/traefik/vendor/github.com/cenkalti/backoff/v5/.gitignore index 39175a965..50d95c548 100644 --- a/plugins/traefik/vendor/github.com/jackc/pgx/v4/.gitignore +++ b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/.gitignore @@ -21,4 +21,5 @@ _testmain.go *.exe -.envrc +# IDEs +.idea/ diff --git a/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/CHANGELOG.md b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/CHANGELOG.md new file mode 100644 index 000000000..658c37436 --- /dev/null +++ b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/CHANGELOG.md @@ -0,0 +1,29 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [5.0.0] - 2024-12-19 + +### Added + +- RetryAfterError can be returned from an operation to indicate how long to wait before the next retry. + +### Changed + +- Retry function now accepts additional options for specifying max number of tries and max elapsed time. +- Retry function now accepts a context.Context. +- Operation function signature changed to return result (any type) and error. + +### Removed + +- RetryNotify* and RetryWithData functions. Only single Retry function remains. +- Optional arguments from ExponentialBackoff constructor. +- Clock and Timer interfaces. + +### Fixed + +- The original error is returned from Retry if there's a PermanentError. (#144) +- The Retry function respects the wrapped PermanentError. (#140) diff --git a/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/LICENSE b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/LICENSE new file mode 100644 index 000000000..89b817996 --- /dev/null +++ b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Cenk Altı + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/README.md b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/README.md new file mode 100644 index 000000000..4611b1d17 --- /dev/null +++ b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/README.md @@ -0,0 +1,31 @@ +# Exponential Backoff [![GoDoc][godoc image]][godoc] + +This is a Go port of the exponential backoff algorithm from [Google's HTTP Client Library for Java][google-http-java-client]. + +[Exponential backoff][exponential backoff wiki] +is an algorithm that uses feedback to multiplicatively decrease the rate of some process, +in order to gradually find an acceptable rate. +The retries exponentially increase and stop increasing when a certain threshold is met. + +## Usage + +Import path is `github.com/cenkalti/backoff/v5`. Please note the version part at the end. + +For most cases, use `Retry` function. See [example_test.go][example] for an example. + +If you have specific needs, copy `Retry` function (from [retry.go][retry-src]) into your code and modify it as needed. + +## Contributing + +* I would like to keep this library as small as possible. +* Please don't send a PR without opening an issue and discussing it first. +* If proposed change is not a common use case, I will probably not accept it. + +[godoc]: https://pkg.go.dev/github.com/cenkalti/backoff/v5 +[godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png + +[google-http-java-client]: https://github.com/google/google-http-java-client/blob/da1aa993e90285ec18579f1553339b00e19b3ab5/google-http-client/src/main/java/com/google/api/client/util/ExponentialBackOff.java +[exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff + +[retry-src]: https://github.com/cenkalti/backoff/blob/v5/retry.go +[example]: https://github.com/cenkalti/backoff/blob/v5/example_test.go diff --git a/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/backoff.go b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/backoff.go new file mode 100644 index 000000000..dd2b24ca7 --- /dev/null +++ b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/backoff.go @@ -0,0 +1,66 @@ +// Package backoff implements backoff algorithms for retrying operations. +// +// Use Retry function for retrying operations that may fail. +// If Retry does not meet your needs, +// copy/paste the function into your project and modify as you wish. +// +// There is also Ticker type similar to time.Ticker. +// You can use it if you need to work with channels. +// +// See Examples section below for usage examples. +package backoff + +import "time" + +// BackOff is a backoff policy for retrying an operation. +type BackOff interface { + // NextBackOff returns the duration to wait before retrying the operation, + // backoff.Stop to indicate that no more retries should be made. + // + // Example usage: + // + // duration := backoff.NextBackOff() + // if duration == backoff.Stop { + // // Do not retry operation. + // } else { + // // Sleep for duration and retry operation. + // } + // + NextBackOff() time.Duration + + // Reset to initial state. + Reset() +} + +// Stop indicates that no more retries should be made for use in NextBackOff(). +const Stop time.Duration = -1 + +// ZeroBackOff is a fixed backoff policy whose backoff time is always zero, +// meaning that the operation is retried immediately without waiting, indefinitely. +type ZeroBackOff struct{} + +func (b *ZeroBackOff) Reset() {} + +func (b *ZeroBackOff) NextBackOff() time.Duration { return 0 } + +// StopBackOff is a fixed backoff policy that always returns backoff.Stop for +// NextBackOff(), meaning that the operation should never be retried. +type StopBackOff struct{} + +func (b *StopBackOff) Reset() {} + +func (b *StopBackOff) NextBackOff() time.Duration { return Stop } + +// ConstantBackOff is a backoff policy that always returns the same backoff delay. +// This is in contrast to an exponential backoff policy, +// which returns a delay that grows longer as you call NextBackOff() over and over again. +type ConstantBackOff struct { + Interval time.Duration +} + +func (b *ConstantBackOff) Reset() {} +func (b *ConstantBackOff) NextBackOff() time.Duration { return b.Interval } + +func NewConstantBackOff(d time.Duration) *ConstantBackOff { + return &ConstantBackOff{Interval: d} +} diff --git a/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/error.go b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/error.go new file mode 100644 index 000000000..beb2b38a2 --- /dev/null +++ b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/error.go @@ -0,0 +1,46 @@ +package backoff + +import ( + "fmt" + "time" +) + +// PermanentError signals that the operation should not be retried. +type PermanentError struct { + Err error +} + +// Permanent wraps the given err in a *PermanentError. +func Permanent(err error) error { + if err == nil { + return nil + } + return &PermanentError{ + Err: err, + } +} + +// Error returns a string representation of the Permanent error. +func (e *PermanentError) Error() string { + return e.Err.Error() +} + +// Unwrap returns the wrapped error. +func (e *PermanentError) Unwrap() error { + return e.Err +} + +// RetryAfterError signals that the operation should be retried after the given duration. +type RetryAfterError struct { + Duration time.Duration +} + +// RetryAfter returns a RetryAfter error that specifies how long to wait before retrying. +func RetryAfter(seconds int) error { + return &RetryAfterError{Duration: time.Duration(seconds) * time.Second} +} + +// Error returns a string representation of the RetryAfter error. +func (e *RetryAfterError) Error() string { + return fmt.Sprintf("retry after %s", e.Duration) +} diff --git a/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/exponential.go b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/exponential.go new file mode 100644 index 000000000..79d425e87 --- /dev/null +++ b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/exponential.go @@ -0,0 +1,118 @@ +package backoff + +import ( + "math/rand/v2" + "time" +) + +/* +ExponentialBackOff is a backoff implementation that increases the backoff +period for each retry attempt using a randomization function that grows exponentially. + +NextBackOff() is calculated using the following formula: + + randomized interval = + RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor]) + +In other words NextBackOff() will range between the randomization factor +percentage below and above the retry interval. + +For example, given the following parameters: + + RetryInterval = 2 + RandomizationFactor = 0.5 + Multiplier = 2 + +the actual backoff period used in the next retry attempt will range between 1 and 3 seconds, +multiplied by the exponential, that is, between 2 and 6 seconds. + +Note: MaxInterval caps the RetryInterval and not the randomized interval. + +Example: Given the following default arguments, for 9 tries the sequence will be: + + Request # RetryInterval (seconds) Randomized Interval (seconds) + + 1 0.5 [0.25, 0.75] + 2 0.75 [0.375, 1.125] + 3 1.125 [0.562, 1.687] + 4 1.687 [0.8435, 2.53] + 5 2.53 [1.265, 3.795] + 6 3.795 [1.897, 5.692] + 7 5.692 [2.846, 8.538] + 8 8.538 [4.269, 12.807] + 9 12.807 [6.403, 19.210] + +Note: Implementation is not thread-safe. +*/ +type ExponentialBackOff struct { + InitialInterval time.Duration + RandomizationFactor float64 + Multiplier float64 + MaxInterval time.Duration + + currentInterval time.Duration +} + +// Default values for ExponentialBackOff. +const ( + DefaultInitialInterval = 500 * time.Millisecond + DefaultRandomizationFactor = 0.5 + DefaultMultiplier = 1.5 + DefaultMaxInterval = 60 * time.Second +) + +// NewExponentialBackOff creates an instance of ExponentialBackOff using default values. +func NewExponentialBackOff() *ExponentialBackOff { + return &ExponentialBackOff{ + InitialInterval: DefaultInitialInterval, + RandomizationFactor: DefaultRandomizationFactor, + Multiplier: DefaultMultiplier, + MaxInterval: DefaultMaxInterval, + } +} + +// Reset the interval back to the initial retry interval and restarts the timer. +// Reset must be called before using b. +func (b *ExponentialBackOff) Reset() { + b.currentInterval = b.InitialInterval +} + +// NextBackOff calculates the next backoff interval using the formula: +// +// Randomized interval = RetryInterval * (1 ± RandomizationFactor) +func (b *ExponentialBackOff) NextBackOff() time.Duration { + if b.currentInterval == 0 { + b.currentInterval = b.InitialInterval + } + + next := getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval) + b.incrementCurrentInterval() + return next +} + +// Increments the current interval by multiplying it with the multiplier. +func (b *ExponentialBackOff) incrementCurrentInterval() { + // Check for overflow, if overflow is detected set the current interval to the max interval. + if float64(b.currentInterval) >= float64(b.MaxInterval)/b.Multiplier { + b.currentInterval = b.MaxInterval + } else { + b.currentInterval = time.Duration(float64(b.currentInterval) * b.Multiplier) + } +} + +// Returns a random value from the following interval: +// +// [currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval]. +func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration { + if randomizationFactor == 0 { + return currentInterval // make sure no randomness is used when randomizationFactor is 0. + } + var delta = randomizationFactor * float64(currentInterval) + var minInterval = float64(currentInterval) - delta + var maxInterval = float64(currentInterval) + delta + + // Get a random value from the range [minInterval, maxInterval]. + // The formula used below has a +1 because if the minInterval is 1 and the maxInterval is 3 then + // we want a 33% chance for selecting either 1, 2 or 3. + return time.Duration(minInterval + (random * (maxInterval - minInterval + 1))) +} diff --git a/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/retry.go b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/retry.go new file mode 100644 index 000000000..32a7f9883 --- /dev/null +++ b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/retry.go @@ -0,0 +1,139 @@ +package backoff + +import ( + "context" + "errors" + "time" +) + +// DefaultMaxElapsedTime sets a default limit for the total retry duration. +const DefaultMaxElapsedTime = 15 * time.Minute + +// Operation is a function that attempts an operation and may be retried. +type Operation[T any] func() (T, error) + +// Notify is a function called on operation error with the error and backoff duration. +type Notify func(error, time.Duration) + +// retryOptions holds configuration settings for the retry mechanism. +type retryOptions struct { + BackOff BackOff // Strategy for calculating backoff periods. + Timer timer // Timer to manage retry delays. + Notify Notify // Optional function to notify on each retry error. + MaxTries uint // Maximum number of retry attempts. + MaxElapsedTime time.Duration // Maximum total time for all retries. +} + +type RetryOption func(*retryOptions) + +// WithBackOff configures a custom backoff strategy. +func WithBackOff(b BackOff) RetryOption { + return func(args *retryOptions) { + args.BackOff = b + } +} + +// withTimer sets a custom timer for managing delays between retries. +func withTimer(t timer) RetryOption { + return func(args *retryOptions) { + args.Timer = t + } +} + +// WithNotify sets a notification function to handle retry errors. +func WithNotify(n Notify) RetryOption { + return func(args *retryOptions) { + args.Notify = n + } +} + +// WithMaxTries limits the number of all attempts. +func WithMaxTries(n uint) RetryOption { + return func(args *retryOptions) { + args.MaxTries = n + } +} + +// WithMaxElapsedTime limits the total duration for retry attempts. +func WithMaxElapsedTime(d time.Duration) RetryOption { + return func(args *retryOptions) { + args.MaxElapsedTime = d + } +} + +// Retry attempts the operation until success, a permanent error, or backoff completion. +// It ensures the operation is executed at least once. +// +// Returns the operation result or error if retries are exhausted or context is cancelled. +func Retry[T any](ctx context.Context, operation Operation[T], opts ...RetryOption) (T, error) { + // Initialize default retry options. + args := &retryOptions{ + BackOff: NewExponentialBackOff(), + Timer: &defaultTimer{}, + MaxElapsedTime: DefaultMaxElapsedTime, + } + + // Apply user-provided options to the default settings. + for _, opt := range opts { + opt(args) + } + + defer args.Timer.Stop() + + startedAt := time.Now() + args.BackOff.Reset() + for numTries := uint(1); ; numTries++ { + // Execute the operation. + res, err := operation() + if err == nil { + return res, nil + } + + // Stop retrying if maximum tries exceeded. + if args.MaxTries > 0 && numTries >= args.MaxTries { + return res, err + } + + // Handle permanent errors without retrying. + var permanent *PermanentError + if errors.As(err, &permanent) { + return res, permanent.Unwrap() + } + + // Stop retrying if context is cancelled. + if cerr := context.Cause(ctx); cerr != nil { + return res, cerr + } + + // Calculate next backoff duration. + next := args.BackOff.NextBackOff() + if next == Stop { + return res, err + } + + // Reset backoff if RetryAfterError is encountered. + var retryAfter *RetryAfterError + if errors.As(err, &retryAfter) { + next = retryAfter.Duration + args.BackOff.Reset() + } + + // Stop retrying if maximum elapsed time exceeded. + if args.MaxElapsedTime > 0 && time.Since(startedAt)+next > args.MaxElapsedTime { + return res, err + } + + // Notify on error if a notifier function is provided. + if args.Notify != nil { + args.Notify(err, next) + } + + // Wait for the next backoff period or context cancellation. + args.Timer.Start(next) + select { + case <-args.Timer.C(): + case <-ctx.Done(): + return res, context.Cause(ctx) + } + } +} diff --git a/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/ticker.go b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/ticker.go new file mode 100644 index 000000000..f0d4b2ae7 --- /dev/null +++ b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/ticker.go @@ -0,0 +1,83 @@ +package backoff + +import ( + "sync" + "time" +) + +// Ticker holds a channel that delivers `ticks' of a clock at times reported by a BackOff. +// +// Ticks will continue to arrive when the previous operation is still running, +// so operations that take a while to fail could run in quick succession. +type Ticker struct { + C <-chan time.Time + c chan time.Time + b BackOff + timer timer + stop chan struct{} + stopOnce sync.Once +} + +// NewTicker returns a new Ticker containing a channel that will send +// the time at times specified by the BackOff argument. Ticker is +// guaranteed to tick at least once. The channel is closed when Stop +// method is called or BackOff stops. It is not safe to manipulate the +// provided backoff policy (notably calling NextBackOff or Reset) +// while the ticker is running. +func NewTicker(b BackOff) *Ticker { + c := make(chan time.Time) + t := &Ticker{ + C: c, + c: c, + b: b, + timer: &defaultTimer{}, + stop: make(chan struct{}), + } + t.b.Reset() + go t.run() + return t +} + +// Stop turns off a ticker. After Stop, no more ticks will be sent. +func (t *Ticker) Stop() { + t.stopOnce.Do(func() { close(t.stop) }) +} + +func (t *Ticker) run() { + c := t.c + defer close(c) + + // Ticker is guaranteed to tick at least once. + afterC := t.send(time.Now()) + + for { + if afterC == nil { + return + } + + select { + case tick := <-afterC: + afterC = t.send(tick) + case <-t.stop: + t.c = nil // Prevent future ticks from being sent to the channel. + return + } + } +} + +func (t *Ticker) send(tick time.Time) <-chan time.Time { + select { + case t.c <- tick: + case <-t.stop: + return nil + } + + next := t.b.NextBackOff() + if next == Stop { + t.Stop() + return nil + } + + t.timer.Start(next) + return t.timer.C() +} diff --git a/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/timer.go b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/timer.go new file mode 100644 index 000000000..a89530974 --- /dev/null +++ b/plugins/traefik/vendor/github.com/cenkalti/backoff/v5/timer.go @@ -0,0 +1,35 @@ +package backoff + +import "time" + +type timer interface { + Start(duration time.Duration) + Stop() + C() <-chan time.Time +} + +// defaultTimer implements Timer interface using time.Timer +type defaultTimer struct { + timer *time.Timer +} + +// C returns the timers channel which receives the current time when the timer fires. +func (t *defaultTimer) C() <-chan time.Time { + return t.timer.C +} + +// Start starts the timer to fire after the given duration +func (t *defaultTimer) Start(duration time.Duration) { + if t.timer == nil { + t.timer = time.NewTimer(duration) + } else { + t.timer.Reset(duration) + } +} + +// Stop is called when the timer is not used anymore and resources may be freed. +func (t *defaultTimer) Stop() { + if t.timer != nil { + t.timer.Stop() + } +} diff --git a/plugins/traefik/vendor/github.com/cloudflare/circl/hpke/shortkem.go b/plugins/traefik/vendor/github.com/cloudflare/circl/hpke/shortkem.go index 2a0787e0b..63cce6852 100644 --- a/plugins/traefik/vendor/github.com/cloudflare/circl/hpke/shortkem.go +++ b/plugins/traefik/vendor/github.com/cloudflare/circl/hpke/shortkem.go @@ -103,7 +103,7 @@ func (s shortKEM) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) { func (s shortKEM) UnmarshalBinaryPrivateKey(data []byte) (kem.PrivateKey, error) { key, err := s.Curve.NewPrivateKey(data) if err != nil { - return nil, err + return nil, ErrInvalidKEMPrivateKey } return &shortKEMPrivKey{s, key}, nil @@ -112,7 +112,7 @@ func (s shortKEM) UnmarshalBinaryPrivateKey(data []byte) (kem.PrivateKey, error) func (s shortKEM) UnmarshalBinaryPublicKey(data []byte) (kem.PublicKey, error) { key, err := s.Curve.NewPublicKey(data) if err != nil { - return nil, err + return nil, ErrInvalidKEMPublicKey } return &shortKEMPubKey{s, *key}, nil diff --git a/plugins/traefik/vendor/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go b/plugins/traefik/vendor/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go index 052fc8d32..091061346 100644 --- a/plugins/traefik/vendor/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go +++ b/plugins/traefik/vendor/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go @@ -14,14 +14,14 @@ import "unsafe" type storageBuf [maxRate / 8]uint64 func (b *storageBuf) asBytes() *[maxRate]byte { - return (*[maxRate]byte)(unsafe.Pointer(b)) + return (*[maxRate]byte)(unsafe.Pointer(b)) //nolint:gosec } // xorInuses unaligned reads and writes to update d.a to contain d.a // XOR buf. func xorIn(d *State, buf []byte) { n := len(buf) - bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8] + bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8] //nolint:gosec if n >= 72 { d.a[0] ^= bw[0] d.a[1] ^= bw[1] @@ -56,6 +56,6 @@ func xorIn(d *State, buf []byte) { } func copyOut(d *State, buf []byte) { - ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0])) + ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0])) //nolint:gosec copy(buf, ab[:]) } diff --git a/plugins/traefik/vendor/github.com/cloudflare/circl/kem/xwing/xwing.go b/plugins/traefik/vendor/github.com/cloudflare/circl/kem/xwing/xwing.go index 7e2807907..e882d50c6 100644 --- a/plugins/traefik/vendor/github.com/cloudflare/circl/kem/xwing/xwing.go +++ b/plugins/traefik/vendor/github.com/cloudflare/circl/kem/xwing/xwing.go @@ -252,6 +252,9 @@ func (pk *PublicKey) EncapsulateTo(ct, ss, seed []byte) { copy(ekx[:], seed[32:]) x25519.KeyGen(&ctx, &ekx) + // A peer public key with low order points results in an all-zeroes + // shared secret. Ignored for now pending clarification in the spec, + // https://github.com/dconnolly/draft-connolly-cfrg-xwing-kem/issues/28 x25519.Shared(&ssx, &ekx, &pk.x) pk.m.EncapsulateTo(ct[:mlkem768.CiphertextSize], ssm[:], seedm[:]) @@ -283,6 +286,9 @@ func (sk *PrivateKey) DecapsulateTo(ss, ct []byte) { copy(ctx[:], ct[mlkem768.CiphertextSize:]) sk.m.DecapsulateTo(ssm[:], ctm) + // A peer public key with low order points results in an all-zeroes + // shared secret. Ignored for now pending clarification in the spec, + // https://github.com/dconnolly/draft-connolly-cfrg-xwing-kem/issues/28 x25519.Shared(&ssx, &sk.x, &ctx) combiner(ss, &ssm, &ssx, &ctx, &sk.xpk) } diff --git a/plugins/traefik/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/arm64.go b/plugins/traefik/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/arm64.go new file mode 100644 index 000000000..f6891b708 --- /dev/null +++ b/plugins/traefik/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/arm64.go @@ -0,0 +1,83 @@ +//go:build arm64 && !purego +// +build arm64,!purego + +package common + +// Sets p to a + b. Does not normalize coefficients. +func (p *Poly) Add(a, b *Poly) { + polyAddARM64(p, a, b) +} + +// Sets p to a - b. Does not normalize coefficients. +func (p *Poly) Sub(a, b *Poly) { + polySubARM64(p, a, b) +} + +// Executes an in-place forward "NTT" on p. +// +// Assumes the coefficients are in absolute value ≤q. The resulting +// coefficients are in absolute value ≤7q. If the input is in Montgomery +// form, then the result is in Montgomery form and so (by linearity of the NTT) +// if the input is in regular form, then the result is also in regular form. +// The order of coefficients will be "tangled". These can be put back into +// their proper order by calling Detangle(). +func (p *Poly) NTT() { + p.nttGeneric() +} + +// Executes an in-place inverse "NTT" on p and multiply by the Montgomery +// factor R. +// +// Requires coefficients to be in "tangled" order, see Tangle(). +// Assumes the coefficients are in absolute value ≤q. The resulting +// coefficients are in absolute value ≤q. If the input is in Montgomery +// form, then the result is in Montgomery form and so (by linearity) +// if the input is in regular form, then the result is also in regular form. +func (p *Poly) InvNTT() { + p.invNTTGeneric() +} + +// Sets p to the "pointwise" multiplication of a and b. +// +// That is: InvNTT(p) = InvNTT(a) * InvNTT(b). Assumes a and b are in +// Montgomery form. Products between coefficients of a and b must be strictly +// bounded in absolute value by 2¹⁵q. p will be in Montgomery form and +// bounded in absolute value by 2q. +// +// Requires a and b to be in "tangled" order, see Tangle(). p will be in +// tangled order as well. +func (p *Poly) MulHat(a, b *Poly) { + p.mulHatGeneric(a, b) +} + +// Puts p into the right form to be used with (among others) InvNTT(). +func (p *Poly) Tangle() { + // In the generic implementation there is no advantage to using a + // different order, so we use the standard order everywhere. +} + +// Puts p back into standard form. +func (p *Poly) Detangle() { + // In the generic implementation there is no advantage to using a + // different order, so we use the standard order everywhere. +} + +// Almost normalizes coefficients. +// +// Ensures each coefficient is in {0, …, q}. +func (p *Poly) BarrettReduce() { + p.barrettReduceGeneric() +} + +// Normalizes coefficients. +// +// Ensures each coefficient is in {0, …, q-1}. +func (p *Poly) Normalize() { + p.normalizeGeneric() +} + +//go:noescape +func polyAddARM64(p, a, b *Poly) + +//go:noescape +func polySubARM64(p, a, b *Poly) diff --git a/plugins/traefik/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/arm64.s b/plugins/traefik/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/arm64.s new file mode 100644 index 000000000..90c94a1a4 --- /dev/null +++ b/plugins/traefik/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/arm64.s @@ -0,0 +1,53 @@ +//go:build arm64 && !purego + +#include "go_asm.h" +#include "textflag.h" + +// func polyAddARM64(p, a, b *Poly) +TEXT ·polyAddARM64(SB), NOSPLIT|NOFRAME, $0-24 + MOVD p+0(FP), R0 + MOVD a+8(FP), R1 + MOVD b+16(FP), R2 + + MOVW $(const_N / 32), R3 + +loop: + VLD1.P (64)(R1), [V0.H8, V1.H8, V2.H8, V3.H8] + VLD1.P (64)(R2), [V4.H8, V5.H8, V6.H8, V7.H8] + + VADD V4.H8, V0.H8, V0.H8 + VADD V5.H8, V1.H8, V1.H8 + VADD V6.H8, V2.H8, V2.H8 + VADD V7.H8, V3.H8, V3.H8 + + VST1.P [V0.H8, V1.H8, V2.H8, V3.H8], (64)(R0) + + SUBS $1, R3, R3 + BGT loop + + RET + + +// func polySubARM64(p, a, b *Poly) +TEXT ·polySubARM64(SB), NOSPLIT|NOFRAME, $0-24 + MOVD p+0(FP), R0 + MOVD a+8(FP), R1 + MOVD b+16(FP), R2 + + MOVW $(const_N / 32), R3 + +loop: + VLD1.P (64)(R1), [V0.H8, V1.H8, V2.H8, V3.H8] + VLD1.P (64)(R2), [V4.H8, V5.H8, V6.H8, V7.H8] + + VSUB V4.H8, V0.H8, V0.H8 + VSUB V5.H8, V1.H8, V1.H8 + VSUB V6.H8, V2.H8, V2.H8 + VSUB V7.H8, V3.H8, V3.H8 + + VST1.P [V0.H8, V1.H8, V2.H8, V3.H8], (64)(R0) + + SUBS $1, R3, R3 + BGT loop + + RET diff --git a/plugins/traefik/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go b/plugins/traefik/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go index 66e0e86dc..fd1e2950e 100644 --- a/plugins/traefik/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go +++ b/plugins/traefik/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go @@ -1,5 +1,5 @@ -//go:build !amd64 || purego -// +build !amd64 purego +//go:build (!amd64 && !arm64) || purego +// +build !amd64,!arm64 purego package common diff --git a/plugins/traefik/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x.go b/plugins/traefik/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x.go index 20ac96f00..66b942cdf 100644 --- a/plugins/traefik/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x.go +++ b/plugins/traefik/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x.go @@ -76,7 +76,7 @@ func IsEnabledX2() bool { return enabledX2 } // If turbo is true, applies 12-round variant instead of the usual 24. func (s *StateX4) Initialize(turbo bool) []uint64 { s.turbo = turbo - rp := unsafe.Pointer(&s.a[0]) + rp := unsafe.Pointer(&s.a[0]) //nolint:gosec // uint64s are always aligned by a multiple of 8. Compute the remainder // of the address modulo 32 divided by 8. @@ -96,7 +96,7 @@ func (s *StateX4) Initialize(turbo bool) []uint64 { // If turbo is true, applies 12-round variant instead of the usual 24. func (s *StateX2) Initialize(turbo bool) []uint64 { s.turbo = turbo - rp := unsafe.Pointer(&s.a[0]) + rp := unsafe.Pointer(&s.a[0]) //nolint:gosec // uint64s are always aligned by a multiple of 8. Compute the remainder // of the address modulo 32 divided by 8. diff --git a/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/LICENSE b/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/LICENSE new file mode 100644 index 000000000..e06d20818 --- /dev/null +++ b/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/LICENSE @@ -0,0 +1,202 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. + diff --git a/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/NOTICE b/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/NOTICE new file mode 100644 index 000000000..b39ddfa5c --- /dev/null +++ b/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2014 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/jose.go b/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/jose.go new file mode 100644 index 000000000..f42d37d48 --- /dev/null +++ b/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/jose.go @@ -0,0 +1,32 @@ +package oidc + +import jose "github.com/go-jose/go-jose/v4" + +// JOSE asymmetric signing algorithm values as defined by RFC 7518 +// +// see: https://tools.ietf.org/html/rfc7518#section-3.1 +const ( + RS256 = "RS256" // RSASSA-PKCS-v1.5 using SHA-256 + RS384 = "RS384" // RSASSA-PKCS-v1.5 using SHA-384 + RS512 = "RS512" // RSASSA-PKCS-v1.5 using SHA-512 + ES256 = "ES256" // ECDSA using P-256 and SHA-256 + ES384 = "ES384" // ECDSA using P-384 and SHA-384 + ES512 = "ES512" // ECDSA using P-521 and SHA-512 + PS256 = "PS256" // RSASSA-PSS using SHA256 and MGF1-SHA256 + PS384 = "PS384" // RSASSA-PSS using SHA384 and MGF1-SHA384 + PS512 = "PS512" // RSASSA-PSS using SHA512 and MGF1-SHA512 + EdDSA = "EdDSA" // Ed25519 using SHA-512 +) + +var allAlgs = []jose.SignatureAlgorithm{ + jose.RS256, + jose.RS384, + jose.RS512, + jose.ES256, + jose.ES384, + jose.ES512, + jose.PS256, + jose.PS384, + jose.PS512, + jose.EdDSA, +} diff --git a/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go b/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go new file mode 100644 index 000000000..c5e4d787c --- /dev/null +++ b/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go @@ -0,0 +1,263 @@ +package oidc + +import ( + "context" + "crypto" + "crypto/ecdsa" + "crypto/ed25519" + "crypto/rsa" + "errors" + "fmt" + "io" + "net/http" + "sync" + + jose "github.com/go-jose/go-jose/v4" +) + +// StaticKeySet is a verifier that validates JWT against a static set of public keys. +type StaticKeySet struct { + // PublicKeys used to verify the JWT. Supported types are *rsa.PublicKey and + // *ecdsa.PublicKey. + PublicKeys []crypto.PublicKey +} + +// VerifySignature compares the signature against a static set of public keys. +func (s *StaticKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) { + // Algorithms are already checked by Verifier, so this parse method accepts + // any algorithm. + jws, err := jose.ParseSigned(jwt, allAlgs) + if err != nil { + return nil, fmt.Errorf("parsing jwt: %v", err) + } + for _, pub := range s.PublicKeys { + switch pub.(type) { + case *rsa.PublicKey: + case *ecdsa.PublicKey: + case ed25519.PublicKey: + default: + return nil, fmt.Errorf("invalid public key type provided: %T", pub) + } + payload, err := jws.Verify(pub) + if err != nil { + continue + } + return payload, nil + } + return nil, fmt.Errorf("no public keys able to verify jwt") +} + +// NewRemoteKeySet returns a KeySet that can validate JSON web tokens by using HTTP +// GETs to fetch JSON web token sets hosted at a remote URL. This is automatically +// used by NewProvider using the URLs returned by OpenID Connect discovery, but is +// exposed for providers that don't support discovery or to prevent round trips to the +// discovery URL. +// +// The returned KeySet is a long lived verifier that caches keys based on any +// keys change. Reuse a common remote key set instead of creating new ones as needed. +func NewRemoteKeySet(ctx context.Context, jwksURL string) *RemoteKeySet { + return newRemoteKeySet(ctx, jwksURL) +} + +func newRemoteKeySet(ctx context.Context, jwksURL string) *RemoteKeySet { + return &RemoteKeySet{ + jwksURL: jwksURL, + // For historical reasons, this package uses contexts for configuration, not just + // cancellation. In hindsight, this was a bad idea. + // + // Attemps to reason about how cancels should work with background requests have + // largely lead to confusion. Use the context here as a config bag-of-values and + // ignore the cancel function. + ctx: context.WithoutCancel(ctx), + } +} + +// RemoteKeySet is a KeySet implementation that validates JSON web tokens against +// a jwks_uri endpoint. +type RemoteKeySet struct { + jwksURL string + + // Used for configuration. Cancelation is ignored. + ctx context.Context + + // guard all other fields + mu sync.RWMutex + + // inflight suppresses parallel execution of updateKeys and allows + // multiple goroutines to wait for its result. + inflight *inflight + + // A set of cached keys. + cachedKeys []jose.JSONWebKey +} + +// inflight is used to wait on some in-flight request from multiple goroutines. +type inflight struct { + doneCh chan struct{} + + keys []jose.JSONWebKey + err error +} + +func newInflight() *inflight { + return &inflight{doneCh: make(chan struct{})} +} + +// wait returns a channel that multiple goroutines can receive on. Once it returns +// a value, the inflight request is done and result() can be inspected. +func (i *inflight) wait() <-chan struct{} { + return i.doneCh +} + +// done can only be called by a single goroutine. It records the result of the +// inflight request and signals other goroutines that the result is safe to +// inspect. +func (i *inflight) done(keys []jose.JSONWebKey, err error) { + i.keys = keys + i.err = err + close(i.doneCh) +} + +// result cannot be called until the wait() channel has returned a value. +func (i *inflight) result() ([]jose.JSONWebKey, error) { + return i.keys, i.err +} + +// paresdJWTKey is a context key that allows common setups to avoid parsing the +// JWT twice. It holds a *jose.JSONWebSignature value. +var parsedJWTKey contextKey + +// VerifySignature validates a payload against a signature from the jwks_uri. +// +// Users MUST NOT call this method directly and should use an IDTokenVerifier +// instead. This method skips critical validations such as 'alg' values and is +// only exported to implement the KeySet interface. +func (r *RemoteKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) { + jws, ok := ctx.Value(parsedJWTKey).(*jose.JSONWebSignature) + if !ok { + // The algorithm values are already enforced by the Validator, which also sets + // the context value above to pre-parsed signature. + // + // Practically, this codepath isn't called in normal use of this package, but + // if it is, the algorithms have already been checked. + var err error + jws, err = jose.ParseSigned(jwt, allAlgs) + if err != nil { + return nil, fmt.Errorf("oidc: malformed jwt: %v", err) + } + } + return r.verify(ctx, jws) +} + +func (r *RemoteKeySet) verify(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) { + // We don't support JWTs signed with multiple signatures. + keyID := "" + for _, sig := range jws.Signatures { + keyID = sig.Header.KeyID + break + } + + keys := r.keysFromCache() + for _, key := range keys { + if keyID == "" || key.KeyID == keyID { + if payload, err := jws.Verify(&key); err == nil { + return payload, nil + } + } + } + + // If the kid doesn't match, check for new keys from the remote. This is the + // strategy recommended by the spec. + // + // https://openid.net/specs/openid-connect-core-1_0.html#RotateSigKeys + keys, err := r.keysFromRemote(ctx) + if err != nil { + return nil, fmt.Errorf("fetching keys %w", err) + } + + for _, key := range keys { + if keyID == "" || key.KeyID == keyID { + if payload, err := jws.Verify(&key); err == nil { + return payload, nil + } + } + } + return nil, errors.New("failed to verify id token signature") +} + +func (r *RemoteKeySet) keysFromCache() (keys []jose.JSONWebKey) { + r.mu.RLock() + defer r.mu.RUnlock() + return r.cachedKeys +} + +// keysFromRemote syncs the key set from the remote set, records the values in the +// cache, and returns the key set. +func (r *RemoteKeySet) keysFromRemote(ctx context.Context) ([]jose.JSONWebKey, error) { + // Need to lock to inspect the inflight request field. + r.mu.Lock() + // If there's not a current inflight request, create one. + if r.inflight == nil { + r.inflight = newInflight() + + // This goroutine has exclusive ownership over the current inflight + // request. It releases the resource by nil'ing the inflight field + // once the goroutine is done. + go func() { + // Sync keys and finish inflight when that's done. + keys, err := r.updateKeys() + + r.inflight.done(keys, err) + + // Lock to update the keys and indicate that there is no longer an + // inflight request. + r.mu.Lock() + defer r.mu.Unlock() + + if err == nil { + r.cachedKeys = keys + } + + // Free inflight so a different request can run. + r.inflight = nil + }() + } + inflight := r.inflight + r.mu.Unlock() + + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-inflight.wait(): + return inflight.result() + } +} + +func (r *RemoteKeySet) updateKeys() ([]jose.JSONWebKey, error) { + req, err := http.NewRequest("GET", r.jwksURL, nil) + if err != nil { + return nil, fmt.Errorf("oidc: can't create request: %v", err) + } + + resp, err := doRequest(r.ctx, req) + if err != nil { + return nil, fmt.Errorf("oidc: get keys failed %w", err) + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("unable to read response body: %v", err) + } + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("oidc: get keys failed: %s %s", resp.Status, body) + } + + var keySet jose.JSONWebKeySet + err = unmarshalResp(resp, body, &keySet) + if err != nil { + return nil, fmt.Errorf("oidc: failed to decode keys: %v %s", err, body) + } + return keySet.Keys, nil +} diff --git a/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go b/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go new file mode 100644 index 000000000..2659518cc --- /dev/null +++ b/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go @@ -0,0 +1,584 @@ +// Package oidc implements OpenID Connect client logic for the golang.org/x/oauth2 package. +package oidc + +import ( + "context" + "crypto/sha256" + "crypto/sha512" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "hash" + "io" + "mime" + "net/http" + "strings" + "sync" + "time" + + "golang.org/x/oauth2" +) + +const ( + // ScopeOpenID is the mandatory scope for all OpenID Connect OAuth2 requests. + ScopeOpenID = "openid" + + // ScopeOfflineAccess is an optional scope defined by OpenID Connect for requesting + // OAuth2 refresh tokens. + // + // Support for this scope differs between OpenID Connect providers. For instance + // Google rejects it, favoring appending "access_type=offline" as part of the + // authorization request instead. + // + // See: https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess + ScopeOfflineAccess = "offline_access" +) + +var ( + errNoAtHash = errors.New("id token did not have an access token hash") + errInvalidAtHash = errors.New("access token hash does not match value in ID token") +) + +type contextKey int + +var issuerURLKey contextKey + +// ClientContext returns a new Context that carries the provided HTTP client. +// +// This method sets the same context key used by the golang.org/x/oauth2 package, +// so the returned context works for that package too. +// +// myClient := &http.Client{} +// ctx := oidc.ClientContext(parentContext, myClient) +// +// // This will use the custom client +// provider, err := oidc.NewProvider(ctx, "https://accounts.example.com") +func ClientContext(ctx context.Context, client *http.Client) context.Context { + return context.WithValue(ctx, oauth2.HTTPClient, client) +} + +func getClient(ctx context.Context) *http.Client { + if c, ok := ctx.Value(oauth2.HTTPClient).(*http.Client); ok { + return c + } + return nil +} + +// InsecureIssuerURLContext allows discovery to work when the issuer_url reported +// by upstream is mismatched with the discovery URL. This is meant for integration +// with off-spec providers such as Azure. +// +// discoveryBaseURL := "https://login.microsoftonline.com/organizations/v2.0" +// issuerURL := "https://login.microsoftonline.com/my-tenantid/v2.0" +// +// ctx := oidc.InsecureIssuerURLContext(parentContext, issuerURL) +// +// // Provider will be discovered with the discoveryBaseURL, but use issuerURL +// // for future issuer validation. +// provider, err := oidc.NewProvider(ctx, discoveryBaseURL) +// +// This is insecure because validating the correct issuer is critical for multi-tenant +// providers. Any overrides here MUST be carefully reviewed. +func InsecureIssuerURLContext(ctx context.Context, issuerURL string) context.Context { + return context.WithValue(ctx, issuerURLKey, issuerURL) +} + +func doRequest(ctx context.Context, req *http.Request) (*http.Response, error) { + client := http.DefaultClient + if c := getClient(ctx); c != nil { + client = c + } + return client.Do(req.WithContext(ctx)) +} + +// Provider represents an OpenID Connect server's configuration. +type Provider struct { + issuer string + authURL string + tokenURL string + deviceAuthURL string + userInfoURL string + jwksURL string + algorithms []string + + // Raw claims returned by the server. + rawClaims []byte + + // Guards all of the following fields. + mu sync.Mutex + // HTTP client specified from the initial NewProvider request. This is used + // when creating the common key set. + client *http.Client + // A key set that uses context.Background() and is shared between all code paths + // that don't have a convinent way of supplying a unique context. + commonRemoteKeySet KeySet +} + +func (p *Provider) remoteKeySet() KeySet { + p.mu.Lock() + defer p.mu.Unlock() + if p.commonRemoteKeySet == nil { + ctx := context.Background() + if p.client != nil { + ctx = ClientContext(ctx, p.client) + } + p.commonRemoteKeySet = NewRemoteKeySet(ctx, p.jwksURL) + } + return p.commonRemoteKeySet +} + +type providerJSON struct { + Issuer string `json:"issuer"` + AuthURL string `json:"authorization_endpoint"` + TokenURL string `json:"token_endpoint"` + DeviceAuthURL string `json:"device_authorization_endpoint"` + JWKSURL string `json:"jwks_uri"` + UserInfoURL string `json:"userinfo_endpoint"` + Algorithms []string `json:"id_token_signing_alg_values_supported"` +} + +// supportedAlgorithms is a list of algorithms explicitly supported by this +// package. If a provider supports other algorithms, such as HS256 or none, +// those values won't be passed to the IDTokenVerifier. +var supportedAlgorithms = map[string]bool{ + RS256: true, + RS384: true, + RS512: true, + ES256: true, + ES384: true, + ES512: true, + PS256: true, + PS384: true, + PS512: true, + EdDSA: true, +} + +// ProviderConfig allows direct creation of a [Provider] from metadata +// configuration. This is intended for interop with providers that don't support +// discovery, or host the JSON discovery document at an off-spec path. +// +// The ProviderConfig struct specifies JSON struct tags to support document +// parsing. +// +// // Directly fetch the metadata document. +// resp, err := http.Get("https://login.example.com/custom-metadata-path") +// if err != nil { +// // ... +// } +// defer resp.Body.Close() +// +// // Parse config from JSON metadata. +// config := &oidc.ProviderConfig{} +// if err := json.NewDecoder(resp.Body).Decode(config); err != nil { +// // ... +// } +// p := config.NewProvider(context.Background()) +// +// For providers that implement discovery, use [NewProvider] instead. +// +// See: https://openid.net/specs/openid-connect-discovery-1_0.html +type ProviderConfig struct { + // IssuerURL is the identity of the provider, and the string it uses to sign + // ID tokens with. For example "https://accounts.google.com". This value MUST + // match ID tokens exactly. + IssuerURL string `json:"issuer"` + // AuthURL is the endpoint used by the provider to support the OAuth 2.0 + // authorization endpoint. + AuthURL string `json:"authorization_endpoint"` + // TokenURL is the endpoint used by the provider to support the OAuth 2.0 + // token endpoint. + TokenURL string `json:"token_endpoint"` + // DeviceAuthURL is the endpoint used by the provider to support the OAuth 2.0 + // device authorization endpoint. + DeviceAuthURL string `json:"device_authorization_endpoint"` + // UserInfoURL is the endpoint used by the provider to support the OpenID + // Connect UserInfo flow. + // + // https://openid.net/specs/openid-connect-core-1_0.html#UserInfo + UserInfoURL string `json:"userinfo_endpoint"` + // JWKSURL is the endpoint used by the provider to advertise public keys to + // verify issued ID tokens. This endpoint is polled as new keys are made + // available. + JWKSURL string `json:"jwks_uri"` + + // Algorithms, if provided, indicate a list of JWT algorithms allowed to sign + // ID tokens. If not provided, this defaults to the algorithms advertised by + // the JWK endpoint, then the set of algorithms supported by this package. + Algorithms []string `json:"id_token_signing_alg_values_supported"` +} + +// NewProvider initializes a provider from a set of endpoints, rather than +// through discovery. +// +// The provided context is only used for [http.Client] configuration through +// [ClientContext], not cancelation. +func (p *ProviderConfig) NewProvider(ctx context.Context) *Provider { + return &Provider{ + issuer: p.IssuerURL, + authURL: p.AuthURL, + tokenURL: p.TokenURL, + deviceAuthURL: p.DeviceAuthURL, + userInfoURL: p.UserInfoURL, + jwksURL: p.JWKSURL, + algorithms: p.Algorithms, + client: getClient(ctx), + } +} + +// NewProvider uses the OpenID Connect discovery mechanism to construct a Provider. +// The issuer is the URL identifier for the service. For example: "https://accounts.google.com" +// or "https://login.salesforce.com". +// +// OpenID Connect providers that don't implement discovery or host the discovery +// document at a non-spec complaint path (such as requiring a URL parameter), +// should use [ProviderConfig] instead. +// +// See: https://openid.net/specs/openid-connect-discovery-1_0.html +func NewProvider(ctx context.Context, issuer string) (*Provider, error) { + wellKnown := strings.TrimSuffix(issuer, "/") + "/.well-known/openid-configuration" + req, err := http.NewRequest("GET", wellKnown, nil) + if err != nil { + return nil, err + } + resp, err := doRequest(ctx, req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("unable to read response body: %v", err) + } + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("%s: %s", resp.Status, body) + } + + var p providerJSON + err = unmarshalResp(resp, body, &p) + if err != nil { + return nil, fmt.Errorf("oidc: failed to decode provider discovery object: %v", err) + } + + issuerURL, skipIssuerValidation := ctx.Value(issuerURLKey).(string) + if !skipIssuerValidation { + issuerURL = issuer + } + if p.Issuer != issuerURL && !skipIssuerValidation { + return nil, fmt.Errorf("oidc: issuer URL provided to client (%q) did not match the issuer URL returned by provider (%q)", issuer, p.Issuer) + } + var algs []string + for _, a := range p.Algorithms { + if supportedAlgorithms[a] { + algs = append(algs, a) + } + } + return &Provider{ + issuer: issuerURL, + authURL: p.AuthURL, + tokenURL: p.TokenURL, + deviceAuthURL: p.DeviceAuthURL, + userInfoURL: p.UserInfoURL, + jwksURL: p.JWKSURL, + algorithms: algs, + rawClaims: body, + client: getClient(ctx), + }, nil +} + +// Claims unmarshals raw fields returned by the server during discovery. +// +// var claims struct { +// ScopesSupported []string `json:"scopes_supported"` +// ClaimsSupported []string `json:"claims_supported"` +// } +// +// if err := provider.Claims(&claims); err != nil { +// // handle unmarshaling error +// } +// +// For a list of fields defined by the OpenID Connect spec see: +// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata +func (p *Provider) Claims(v interface{}) error { + if p.rawClaims == nil { + return errors.New("oidc: claims not set") + } + return json.Unmarshal(p.rawClaims, v) +} + +// Endpoint returns the OAuth2 auth and token endpoints for the given provider. +func (p *Provider) Endpoint() oauth2.Endpoint { + return oauth2.Endpoint{AuthURL: p.authURL, DeviceAuthURL: p.deviceAuthURL, TokenURL: p.tokenURL} +} + +// UserInfoEndpoint returns the OpenID Connect userinfo endpoint for the given +// provider. +func (p *Provider) UserInfoEndpoint() string { + return p.userInfoURL +} + +// UserInfo represents the OpenID Connect userinfo claims. +type UserInfo struct { + Subject string `json:"sub"` + Profile string `json:"profile"` + Email string `json:"email"` + EmailVerified bool `json:"email_verified"` + + claims []byte +} + +type userInfoRaw struct { + Subject string `json:"sub"` + Profile string `json:"profile"` + Email string `json:"email"` + // Handle providers that return email_verified as a string + // https://forums.aws.amazon.com/thread.jspa?messageID=949441󧳁 and + // https://discuss.elastic.co/t/openid-error-after-authenticating-against-aws-cognito/206018/11 + EmailVerified stringAsBool `json:"email_verified"` +} + +// Claims unmarshals the raw JSON object claims into the provided object. +func (u *UserInfo) Claims(v interface{}) error { + if u.claims == nil { + return errors.New("oidc: claims not set") + } + return json.Unmarshal(u.claims, v) +} + +// UserInfo uses the token source to query the provider's user info endpoint. +func (p *Provider) UserInfo(ctx context.Context, tokenSource oauth2.TokenSource) (*UserInfo, error) { + if p.userInfoURL == "" { + return nil, errors.New("oidc: user info endpoint is not supported by this provider") + } + + req, err := http.NewRequest("GET", p.userInfoURL, nil) + if err != nil { + return nil, fmt.Errorf("oidc: create GET request: %v", err) + } + + token, err := tokenSource.Token() + if err != nil { + return nil, fmt.Errorf("oidc: get access token: %v", err) + } + token.SetAuthHeader(req) + + resp, err := doRequest(ctx, req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("%s: %s", resp.Status, body) + } + + ct := resp.Header.Get("Content-Type") + mediaType, _, parseErr := mime.ParseMediaType(ct) + if parseErr == nil && mediaType == "application/jwt" { + payload, err := p.remoteKeySet().VerifySignature(ctx, string(body)) + if err != nil { + return nil, fmt.Errorf("oidc: invalid userinfo jwt signature %v", err) + } + body = payload + } + + var userInfo userInfoRaw + if err := json.Unmarshal(body, &userInfo); err != nil { + return nil, fmt.Errorf("oidc: failed to decode userinfo: %v", err) + } + return &UserInfo{ + Subject: userInfo.Subject, + Profile: userInfo.Profile, + Email: userInfo.Email, + EmailVerified: bool(userInfo.EmailVerified), + claims: body, + }, nil +} + +// IDToken is an OpenID Connect extension that provides a predictable representation +// of an authorization event. +// +// The ID Token only holds fields OpenID Connect requires. To access additional +// claims returned by the server, use the Claims method. +type IDToken struct { + // The URL of the server which issued this token. OpenID Connect + // requires this value always be identical to the URL used for + // initial discovery. + // + // Note: Because of a known issue with Google Accounts' implementation + // this value may differ when using Google. + // + // See: https://developers.google.com/identity/protocols/OpenIDConnect#obtainuserinfo + Issuer string + + // The client ID, or set of client IDs, that this token is issued for. For + // common uses, this is the client that initialized the auth flow. + // + // This package ensures the audience contains an expected value. + Audience []string + + // A unique string which identifies the end user. + Subject string + + // Expiry of the token. Ths package will not process tokens that have + // expired unless that validation is explicitly turned off. + Expiry time.Time + // When the token was issued by the provider. + IssuedAt time.Time + + // Initial nonce provided during the authentication redirect. + // + // This package does NOT provided verification on the value of this field + // and it's the user's responsibility to ensure it contains a valid value. + Nonce string + + // at_hash claim, if set in the ID token. Callers can verify an access token + // that corresponds to the ID token using the VerifyAccessToken method. + AccessTokenHash string + + // signature algorithm used for ID token, needed to compute a verification hash of an + // access token + sigAlgorithm string + + // Raw payload of the id_token. + claims []byte + + // Map of distributed claim names to claim sources + distributedClaims map[string]claimSource +} + +// Claims unmarshals the raw JSON payload of the ID Token into a provided struct. +// +// idToken, err := idTokenVerifier.Verify(rawIDToken) +// if err != nil { +// // handle error +// } +// var claims struct { +// Email string `json:"email"` +// EmailVerified bool `json:"email_verified"` +// } +// if err := idToken.Claims(&claims); err != nil { +// // handle error +// } +func (i *IDToken) Claims(v interface{}) error { + if i.claims == nil { + return errors.New("oidc: claims not set") + } + return json.Unmarshal(i.claims, v) +} + +// VerifyAccessToken verifies that the hash of the access token that corresponds to the iD token +// matches the hash in the id token. It returns an error if the hashes don't match. +// It is the caller's responsibility to ensure that the optional access token hash is present for the ID token +// before calling this method. See https://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken +func (i *IDToken) VerifyAccessToken(accessToken string) error { + if i.AccessTokenHash == "" { + return errNoAtHash + } + var h hash.Hash + switch i.sigAlgorithm { + case RS256, ES256, PS256: + h = sha256.New() + case RS384, ES384, PS384: + h = sha512.New384() + case RS512, ES512, PS512, EdDSA: + h = sha512.New() + default: + return fmt.Errorf("oidc: unsupported signing algorithm %q", i.sigAlgorithm) + } + h.Write([]byte(accessToken)) // hash documents that Write will never return an error + sum := h.Sum(nil)[:h.Size()/2] + actual := base64.RawURLEncoding.EncodeToString(sum) + if actual != i.AccessTokenHash { + return errInvalidAtHash + } + return nil +} + +type idToken struct { + Issuer string `json:"iss"` + Subject string `json:"sub"` + Audience audience `json:"aud"` + Expiry jsonTime `json:"exp"` + IssuedAt jsonTime `json:"iat"` + NotBefore *jsonTime `json:"nbf"` + Nonce string `json:"nonce"` + AtHash string `json:"at_hash"` + ClaimNames map[string]string `json:"_claim_names"` + ClaimSources map[string]claimSource `json:"_claim_sources"` +} + +type claimSource struct { + Endpoint string `json:"endpoint"` + AccessToken string `json:"access_token"` +} + +type stringAsBool bool + +func (sb *stringAsBool) UnmarshalJSON(b []byte) error { + switch string(b) { + case "true", `"true"`: + *sb = true + case "false", `"false"`: + *sb = false + default: + return errors.New("invalid value for boolean") + } + return nil +} + +type audience []string + +func (a *audience) UnmarshalJSON(b []byte) error { + var s string + if json.Unmarshal(b, &s) == nil { + *a = audience{s} + return nil + } + var auds []string + if err := json.Unmarshal(b, &auds); err != nil { + return err + } + *a = auds + return nil +} + +type jsonTime time.Time + +func (j *jsonTime) UnmarshalJSON(b []byte) error { + var n json.Number + if err := json.Unmarshal(b, &n); err != nil { + return err + } + var unix int64 + + if t, err := n.Int64(); err == nil { + unix = t + } else { + f, err := n.Float64() + if err != nil { + return err + } + unix = int64(f) + } + *j = jsonTime(time.Unix(unix, 0)) + return nil +} + +func unmarshalResp(r *http.Response, body []byte, v interface{}) error { + err := json.Unmarshal(body, &v) + if err == nil { + return nil + } + ct := r.Header.Get("Content-Type") + mediaType, _, parseErr := mime.ParseMediaType(ct) + if parseErr == nil && mediaType == "application/json" { + return fmt.Errorf("got Content-Type = application/json, but could not unmarshal as JSON: %v", err) + } + return fmt.Errorf("expected Content-Type = application/json, got %q: %v", ct, err) +} diff --git a/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go b/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go new file mode 100644 index 000000000..a8bf107d4 --- /dev/null +++ b/plugins/traefik/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go @@ -0,0 +1,338 @@ +package oidc + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "time" + + jose "github.com/go-jose/go-jose/v4" + "golang.org/x/oauth2" +) + +const ( + issuerGoogleAccounts = "https://accounts.google.com" + issuerGoogleAccountsNoScheme = "accounts.google.com" +) + +// TokenExpiredError indicates that Verify failed because the token was expired. This +// error does NOT indicate that the token is not also invalid for other reasons. Other +// checks might have failed if the expiration check had not failed. +type TokenExpiredError struct { + // Expiry is the time when the token expired. + Expiry time.Time +} + +func (e *TokenExpiredError) Error() string { + return fmt.Sprintf("oidc: token is expired (Token Expiry: %v)", e.Expiry) +} + +// KeySet is a set of publc JSON Web Keys that can be used to validate the signature +// of JSON web tokens. This is expected to be backed by a remote key set through +// provider metadata discovery or an in-memory set of keys delivered out-of-band. +type KeySet interface { + // VerifySignature parses the JSON web token, verifies the signature, and returns + // the raw payload. Header and claim fields are validated by other parts of the + // package. For example, the KeySet does not need to check values such as signature + // algorithm, issuer, and audience since the IDTokenVerifier validates these values + // independently. + // + // If VerifySignature makes HTTP requests to verify the token, it's expected to + // use any HTTP client associated with the context through ClientContext. + VerifySignature(ctx context.Context, jwt string) (payload []byte, err error) +} + +// IDTokenVerifier provides verification for ID Tokens. +type IDTokenVerifier struct { + keySet KeySet + config *Config + issuer string +} + +// NewVerifier returns a verifier manually constructed from a key set and issuer URL. +// +// It's easier to use provider discovery to construct an IDTokenVerifier than creating +// one directly. This method is intended to be used with provider that don't support +// metadata discovery, or avoiding round trips when the key set URL is already known. +// +// This constructor can be used to create a verifier directly using the issuer URL and +// JSON Web Key Set URL without using discovery: +// +// keySet := oidc.NewRemoteKeySet(ctx, "https://www.googleapis.com/oauth2/v3/certs") +// verifier := oidc.NewVerifier("https://accounts.google.com", keySet, config) +// +// Or a static key set (e.g. for testing): +// +// keySet := &oidc.StaticKeySet{PublicKeys: []crypto.PublicKey{pub1, pub2}} +// verifier := oidc.NewVerifier("https://accounts.google.com", keySet, config) +func NewVerifier(issuerURL string, keySet KeySet, config *Config) *IDTokenVerifier { + return &IDTokenVerifier{keySet: keySet, config: config, issuer: issuerURL} +} + +// Config is the configuration for an IDTokenVerifier. +type Config struct { + // Expected audience of the token. For a majority of the cases this is expected to be + // the ID of the client that initialized the login flow. It may occasionally differ if + // the provider supports the authorizing party (azp) claim. + // + // If not provided, users must explicitly set SkipClientIDCheck. + ClientID string + // If specified, only this set of algorithms may be used to sign the JWT. + // + // If the IDTokenVerifier is created from a provider with (*Provider).Verifier, this + // defaults to the set of algorithms the provider supports. Otherwise this values + // defaults to RS256. + SupportedSigningAlgs []string + + // If true, no ClientID check performed. Must be true if ClientID field is empty. + SkipClientIDCheck bool + // If true, token expiry is not checked. + SkipExpiryCheck bool + + // SkipIssuerCheck is intended for specialized cases where the the caller wishes to + // defer issuer validation. When enabled, callers MUST independently verify the Token's + // Issuer is a known good value. + // + // Mismatched issuers often indicate client mis-configuration. If mismatches are + // unexpected, evaluate if the provided issuer URL is incorrect instead of enabling + // this option. + SkipIssuerCheck bool + + // Time function to check Token expiry. Defaults to time.Now + Now func() time.Time + + // InsecureSkipSignatureCheck causes this package to skip JWT signature validation. + // It's intended for special cases where providers (such as Azure), use the "none" + // algorithm. + // + // This option can only be enabled safely when the ID Token is received directly + // from the provider after the token exchange. + // + // This option MUST NOT be used when receiving an ID Token from sources other + // than the token endpoint. + InsecureSkipSignatureCheck bool +} + +// VerifierContext returns an IDTokenVerifier that uses the provider's key set to +// verify JWTs. As opposed to Verifier, the context is used to configure requests +// to the upstream JWKs endpoint. The provided context's cancellation is ignored. +func (p *Provider) VerifierContext(ctx context.Context, config *Config) *IDTokenVerifier { + return p.newVerifier(NewRemoteKeySet(ctx, p.jwksURL), config) +} + +// Verifier returns an IDTokenVerifier that uses the provider's key set to verify JWTs. +// +// The returned verifier uses a background context for all requests to the upstream +// JWKs endpoint. To control that context, use VerifierContext instead. +func (p *Provider) Verifier(config *Config) *IDTokenVerifier { + return p.newVerifier(p.remoteKeySet(), config) +} + +func (p *Provider) newVerifier(keySet KeySet, config *Config) *IDTokenVerifier { + if len(config.SupportedSigningAlgs) == 0 && len(p.algorithms) > 0 { + // Make a copy so we don't modify the config values. + cp := &Config{} + *cp = *config + cp.SupportedSigningAlgs = p.algorithms + config = cp + } + return NewVerifier(p.issuer, keySet, config) +} + +func contains(sli []string, ele string) bool { + for _, s := range sli { + if s == ele { + return true + } + } + return false +} + +// Returns the Claims from the distributed JWT token +func resolveDistributedClaim(ctx context.Context, verifier *IDTokenVerifier, src claimSource) ([]byte, error) { + req, err := http.NewRequest("GET", src.Endpoint, nil) + if err != nil { + return nil, fmt.Errorf("malformed request: %v", err) + } + if src.AccessToken != "" { + req.Header.Set("Authorization", "Bearer "+src.AccessToken) + } + + resp, err := doRequest(ctx, req) + if err != nil { + return nil, fmt.Errorf("oidc: Request to endpoint failed: %v", err) + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("unable to read response body: %v", err) + } + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("oidc: request failed: %v", resp.StatusCode) + } + + token, err := verifier.Verify(ctx, string(body)) + if err != nil { + return nil, fmt.Errorf("malformed response body: %v", err) + } + + return token.claims, nil +} + +// Verify parses a raw ID Token, verifies it's been signed by the provider, performs +// any additional checks depending on the Config, and returns the payload. +// +// Verify does NOT do nonce validation, which is the callers responsibility. +// +// See: https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation +// +// oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code")) +// if err != nil { +// // handle error +// } +// +// // Extract the ID Token from oauth2 token. +// rawIDToken, ok := oauth2Token.Extra("id_token").(string) +// if !ok { +// // handle error +// } +// +// token, err := verifier.Verify(ctx, rawIDToken) +func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDToken, error) { + var supportedSigAlgs []jose.SignatureAlgorithm + for _, alg := range v.config.SupportedSigningAlgs { + supportedSigAlgs = append(supportedSigAlgs, jose.SignatureAlgorithm(alg)) + } + if len(supportedSigAlgs) == 0 { + // If no algorithms were specified by both the config and discovery, default + // to the one mandatory algorithm "RS256". + supportedSigAlgs = []jose.SignatureAlgorithm{jose.RS256} + } + if v.config.InsecureSkipSignatureCheck { + // "none" is a required value to even parse a JWT with the "none" algorithm + // using go-jose. + supportedSigAlgs = append(supportedSigAlgs, "none") + } + + // Parse and verify the signature first. This at least forces the user to have + // a valid, signed ID token before we do any other processing. + jws, err := jose.ParseSigned(rawIDToken, supportedSigAlgs) + if err != nil { + return nil, fmt.Errorf("oidc: malformed jwt: %v", err) + } + switch len(jws.Signatures) { + case 0: + return nil, fmt.Errorf("oidc: id token not signed") + case 1: + default: + return nil, fmt.Errorf("oidc: multiple signatures on id token not supported") + } + sig := jws.Signatures[0] + + var payload []byte + if v.config.InsecureSkipSignatureCheck { + // Yolo mode. + payload = jws.UnsafePayloadWithoutVerification() + } else { + // The JWT is attached here for the happy path to avoid the verifier from + // having to parse the JWT twice. + ctx = context.WithValue(ctx, parsedJWTKey, jws) + payload, err = v.keySet.VerifySignature(ctx, rawIDToken) + if err != nil { + return nil, fmt.Errorf("failed to verify signature: %v", err) + } + } + var token idToken + if err := json.Unmarshal(payload, &token); err != nil { + return nil, fmt.Errorf("oidc: failed to unmarshal claims: %v", err) + } + + distributedClaims := make(map[string]claimSource) + + //step through the token to map claim names to claim sources" + for cn, src := range token.ClaimNames { + if src == "" { + return nil, fmt.Errorf("oidc: failed to obtain source from claim name") + } + s, ok := token.ClaimSources[src] + if !ok { + return nil, fmt.Errorf("oidc: source does not exist") + } + distributedClaims[cn] = s + } + + t := &IDToken{ + Issuer: token.Issuer, + Subject: token.Subject, + Audience: []string(token.Audience), + Expiry: time.Time(token.Expiry), + IssuedAt: time.Time(token.IssuedAt), + Nonce: token.Nonce, + AccessTokenHash: token.AtHash, + claims: payload, + distributedClaims: distributedClaims, + sigAlgorithm: sig.Header.Algorithm, + } + + // Check issuer. + if !v.config.SkipIssuerCheck && t.Issuer != v.issuer { + // Google sometimes returns "accounts.google.com" as the issuer claim instead of + // the required "https://accounts.google.com". Detect this case and allow it only + // for Google. + // + // We will not add hooks to let other providers go off spec like this. + if !(v.issuer == issuerGoogleAccounts && t.Issuer == issuerGoogleAccountsNoScheme) { + return nil, fmt.Errorf("oidc: id token issued by a different provider, expected %q got %q", v.issuer, t.Issuer) + } + } + + // If a client ID has been provided, make sure it's part of the audience. SkipClientIDCheck must be true if ClientID is empty. + // + // This check DOES NOT ensure that the ClientID is the party to which the ID Token was issued (i.e. Authorized party). + if !v.config.SkipClientIDCheck { + if v.config.ClientID != "" { + if !contains(t.Audience, v.config.ClientID) { + return nil, fmt.Errorf("oidc: expected audience %q got %q", v.config.ClientID, t.Audience) + } + } else { + return nil, fmt.Errorf("oidc: invalid configuration, clientID must be provided or SkipClientIDCheck must be set") + } + } + + // If a SkipExpiryCheck is false, make sure token is not expired. + if !v.config.SkipExpiryCheck { + now := time.Now + if v.config.Now != nil { + now = v.config.Now + } + nowTime := now() + + if t.Expiry.Before(nowTime) { + return nil, &TokenExpiredError{Expiry: t.Expiry} + } + + // If nbf claim is provided in token, ensure that it is indeed in the past. + if token.NotBefore != nil { + nbfTime := time.Time(*token.NotBefore) + // Set to 5 minutes since this is what other OpenID Connect providers do to deal with clock skew. + // https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/6.12.2/src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs#L149-L153 + leeway := 5 * time.Minute + + if nowTime.Add(leeway).Before(nbfTime) { + return nil, fmt.Errorf("oidc: current time %v before the nbf (not before) time: %v", nowTime, nbfTime) + } + } + } + + return t, nil +} + +// Nonce returns an auth code option which requires the ID Token created by the +// OpenID Connect provider to contain the specified nonce. +func Nonce(nonce string) oauth2.AuthCodeOption { + return oauth2.SetAuthURLParam("nonce", nonce) +} diff --git a/plugins/traefik/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go b/plugins/traefik/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go index 62d91b77d..5673f5c0b 100644 --- a/plugins/traefik/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go +++ b/plugins/traefik/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go @@ -1,3 +1,4 @@ +// Package md2man aims in converting markdown into roff (man pages). package md2man import ( diff --git a/plugins/traefik/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go b/plugins/traefik/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go index 96a80c99b..4f1070fc5 100644 --- a/plugins/traefik/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go +++ b/plugins/traefik/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go @@ -47,13 +47,13 @@ const ( tableStart = "\n.TS\nallbox;\n" tableEnd = ".TE\n" tableCellStart = "T{\n" - tableCellEnd = "\nT}\n" + tableCellEnd = "\nT}" tablePreprocessor = `'\" t` ) // NewRoffRenderer creates a new blackfriday Renderer for generating roff documents // from markdown -func NewRoffRenderer() *roffRenderer { // nolint: golint +func NewRoffRenderer() *roffRenderer { return &roffRenderer{} } @@ -316,9 +316,8 @@ func (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, ente } else if nodeLiteralSize(node) > 30 { end = tableCellEnd } - if node.Next == nil && end != tableCellEnd { - // Last cell: need to carriage return if we are at the end of the - // header row and content isn't wrapped in a "tablecell" + if node.Next == nil { + // Last cell: need to carriage return if we are at the end of the header row. end += crTag } out(w, end) @@ -356,7 +355,7 @@ func countColumns(node *blackfriday.Node) int { } func out(w io.Writer, output string) { - io.WriteString(w, output) // nolint: errcheck + io.WriteString(w, output) //nolint:errcheck } func escapeSpecialChars(w io.Writer, text []byte) { @@ -395,7 +394,7 @@ func escapeSpecialCharsLine(w io.Writer, text []byte) { i++ } if i > org { - w.Write(text[org:i]) // nolint: errcheck + w.Write(text[org:i]) //nolint:errcheck } // escape a character @@ -403,7 +402,7 @@ func escapeSpecialCharsLine(w io.Writer, text []byte) { break } - w.Write([]byte{'\\', text[i]}) // nolint: errcheck + w.Write([]byte{'\\', text[i]}) //nolint:errcheck } } diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/api/main.go b/plugins/traefik/vendor/github.com/darkweak/souin/api/main.go deleted file mode 100644 index 03230b136..000000000 --- a/plugins/traefik/vendor/github.com/darkweak/souin/api/main.go +++ /dev/null @@ -1,50 +0,0 @@ -package api - -import ( - "net/http" - - "github.com/darkweak/souin/configurationtypes" - "github.com/darkweak/souin/pkg/storage/types" - "github.com/darkweak/souin/pkg/surrogate/providers" -) - -// MapHandler is a map to store the available http Handlers -type MapHandler struct { - Handlers *map[string]http.HandlerFunc -} - -// GenerateHandlerMap generate the MapHandler -func GenerateHandlerMap( - configuration configurationtypes.AbstractConfigurationInterface, - storers []types.Storer, - surrogateStorage providers.SurrogateInterface, -) *MapHandler { - hm := make(map[string]http.HandlerFunc) - shouldEnable := false - - souinAPI := configuration.GetAPI() - basePathAPIS := souinAPI.BasePath - if basePathAPIS == "" { - basePathAPIS = "/souin-api" - } - - for _, endpoint := range Initialize(configuration, storers, surrogateStorage) { - if endpoint.IsEnabled() { - shouldEnable = true - if e, ok := endpoint.(*SouinAPI); ok { - hm[basePathAPIS+endpoint.GetBasePath()] = e.HandleRequest - } - } - } - - if shouldEnable { - return &MapHandler{Handlers: &hm} - } - - return nil -} - -// Initialize contains all apis that should be enabled -func Initialize(c configurationtypes.AbstractConfigurationInterface, storers []types.Storer, surrogateStorage providers.SurrogateInterface) []EndpointInterface { - return []EndpointInterface{initializeSouin(c, storers, surrogateStorage)} -} diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/api/prometheus/prometheus.go b/plugins/traefik/vendor/github.com/darkweak/souin/api/prometheus/prometheus.go deleted file mode 100644 index 2712571d6..000000000 --- a/plugins/traefik/vendor/github.com/darkweak/souin/api/prometheus/prometheus.go +++ /dev/null @@ -1,5 +0,0 @@ -package prometheus - -const RequestCounter = "" - -func Increment(string) {} diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/api/souin.go b/plugins/traefik/vendor/github.com/darkweak/souin/api/souin.go deleted file mode 100644 index 8f5305cb9..000000000 --- a/plugins/traefik/vendor/github.com/darkweak/souin/api/souin.go +++ /dev/null @@ -1,233 +0,0 @@ -package api - -import ( - "encoding/json" - "fmt" - "net/http" - "regexp" - "strings" - - "github.com/darkweak/souin/configurationtypes" - "github.com/darkweak/souin/pkg/storage/types" - "github.com/darkweak/souin/pkg/surrogate/providers" -) - -// SouinAPI object contains informations related to the endpoints -type SouinAPI struct { - basePath string - enabled bool - storers []types.Storer - surrogateStorage providers.SurrogateInterface - allowedMethods []string -} - -type invalidationType string - -const ( - uriInvalidationType invalidationType = "uri" - uriPrefixInvalidationType invalidationType = "uri-prefix" - originInvalidationType invalidationType = "origin" - groupInvalidationType invalidationType = "group" -) - -type invalidation struct { - Type invalidationType `json:"type"` - Selectors []string `json:"selectors"` - Groups []string `json:"groups"` - Purge bool `json:"purge"` -} - -func initializeSouin( - configuration configurationtypes.AbstractConfigurationInterface, - storers []types.Storer, - surrogateStorage providers.SurrogateInterface, -) *SouinAPI { - basePath := configuration.GetAPI().Souin.BasePath - if basePath == "" { - basePath = "/souin" - } - - allowedMethods := configuration.GetDefaultCache().GetAllowedHTTPVerbs() - if len(allowedMethods) == 0 { - allowedMethods = []string{http.MethodGet, http.MethodHead} - } - - return &SouinAPI{ - basePath, - configuration.GetAPI().Souin.Enable, - storers, - surrogateStorage, - allowedMethods, - } -} - -// BulkDelete allow user to delete multiple items with regexp -func (s *SouinAPI) BulkDelete(key string) { - for _, current := range s.storers { - current.DeleteMany(key) - } -} - -// Delete will delete a record into the provider cache system and will update the Souin API if enabled -func (s *SouinAPI) Delete(key string) { - for _, current := range s.storers { - current.Delete(key) - } -} - -// GetAll will retrieve all stored keys in the provider -func (s *SouinAPI) GetAll() []string { - keys := []string{} - for _, current := range s.storers { - keys = append(keys, current.ListKeys()...) - } - - return keys -} - -// GetBasePath will return the basepath for this resource -func (s *SouinAPI) GetBasePath() string { - return s.basePath -} - -// IsEnabled will return enabled status -func (s *SouinAPI) IsEnabled() bool { - return s.enabled -} - -func (s *SouinAPI) listKeys(search string) []string { - res := []string{} - re, err := regexp.Compile(search) - if err != nil { - return res - } - for _, key := range s.GetAll() { - if re.MatchString(key) { - res = append(res, key) - } - } - - return res -} - -// HandleRequest will handle the request -func (s *SouinAPI) HandleRequest(w http.ResponseWriter, r *http.Request) { - res := []byte{} - compile := regexp.MustCompile(s.GetBasePath()+"/.+").FindString(r.RequestURI) != "" - switch r.Method { - case http.MethodGet: - if regexp.MustCompile(s.GetBasePath()+"/surrogate_keys").FindString(r.RequestURI) != "" { - res, _ = json.Marshal(s.surrogateStorage.List()) - } else if compile { - search := regexp.MustCompile(s.GetBasePath()+"/(.+)").FindAllStringSubmatch(r.RequestURI, -1)[0][1] - res, _ = json.Marshal(s.listKeys(search)) - if len(res) == 2 { - w.WriteHeader(http.StatusNotFound) - } - } else { - res, _ = json.Marshal(s.GetAll()) - } - w.Header().Set("Content-Type", "application/json") - case http.MethodPost: - var invalidator invalidation - err := json.NewDecoder(r.Body).Decode(&invalidator) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - return - } - - keysToInvalidate := []string{} - switch invalidator.Type { - case groupInvalidationType: - keysToInvalidate, _ = s.surrogateStorage.Purge(http.Header{"Surrogate-Key": invalidator.Groups}) - case uriPrefixInvalidationType, uriInvalidationType: - bodyKeys := []string{} - listedKeys := s.GetAll() - for _, k := range invalidator.Selectors { - if !strings.Contains(k, "//") { - rq, err := http.NewRequest(http.MethodGet, "//"+k, nil) - if err != nil { - continue - } - - bodyKeys = append(bodyKeys, rq.Host+"-"+rq.URL.Path) - } - } - - for _, allKey := range listedKeys { - for _, bk := range bodyKeys { - if invalidator.Type == uriInvalidationType { - if strings.Contains(allKey, bk) && strings.Contains(allKey, bk+"-") && strings.HasSuffix(allKey, bk) { - keysToInvalidate = append(keysToInvalidate, allKey) - break - } - } else { - if strings.Contains(allKey, bk) && - (strings.Contains(allKey, bk+"-") || strings.Contains(allKey, bk+"?") || strings.Contains(allKey, bk+"/") || strings.HasSuffix(allKey, bk)) { - keysToInvalidate = append(keysToInvalidate, allKey) - break - } - } - } - } - case originInvalidationType: - bodyKeys := []string{} - listedKeys := s.GetAll() - for _, k := range invalidator.Selectors { - if !strings.Contains(k, "//") { - rq, err := http.NewRequest(http.MethodGet, "//"+k, nil) - if err != nil { - continue - } - - bodyKeys = append(bodyKeys, rq.Host) - } - } - - for _, allKey := range listedKeys { - for _, bk := range bodyKeys { - if strings.Contains(allKey, bk) { - keysToInvalidate = append(keysToInvalidate, allKey) - break - } - } - } - } - - for _, k := range keysToInvalidate { - for _, current := range s.storers { - current.Delete(k) - } - } - w.WriteHeader(http.StatusOK) - case "PURGE": - if compile { - keysRg := regexp.MustCompile(s.GetBasePath() + "/(.+)") - flushRg := regexp.MustCompile(s.GetBasePath() + "/flush$") - - if flushRg.FindString(r.RequestURI) != "" { - for _, current := range s.storers { - current.DeleteMany(".+") - } - e := s.surrogateStorage.Destruct() - if e != nil { - fmt.Printf("Error while purging the surrogate keys: %+v.", e) - } - fmt.Println("Successfully clear the cache and the surrogate keys storage.") - } else { - submatch := keysRg.FindAllStringSubmatch(r.RequestURI, -1)[0][1] - s.BulkDelete(submatch) - } - } else { - ck, _ := s.surrogateStorage.Purge(r.Header) - for _, k := range ck { - for _, current := range s.storers { - current.Delete(k) - } - } - } - w.WriteHeader(http.StatusNoContent) - default: - } - _, _ = w.Write(res) -} diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/api/types.go b/plugins/traefik/vendor/github.com/darkweak/souin/api/types.go deleted file mode 100644 index a1c5c53e9..000000000 --- a/plugins/traefik/vendor/github.com/darkweak/souin/api/types.go +++ /dev/null @@ -1,12 +0,0 @@ -package api - -import ( - "net/http" -) - -// EndpointInterface is the contract to be able to enable your custom endpoints -type EndpointInterface interface { - GetBasePath() string - IsEnabled() bool - HandleRequest(http.ResponseWriter, *http.Request) -} diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/configurationtypes/types.go b/plugins/traefik/vendor/github.com/darkweak/souin/configurationtypes/types.go index e03ed7f93..8b5d5d8c5 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/configurationtypes/types.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/configurationtypes/types.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "github.com/darkweak/storages/core" "gopkg.in/yaml.v3" ) @@ -198,6 +199,26 @@ type CacheProvider struct { Configuration interface{} `json:"configuration" yaml:"configuration"` } +func (c *CacheProvider) MarshalJSON() ([]byte, error) { + if !c.Found && c.URL == "" && c.Path == "" && c.Configuration == nil && c.Uuid == "" { + return []byte("null"), nil + } + + return json.Marshal(struct { + Uuid string + Found bool `json:"found"` + URL string `json:"url"` + Path string `json:"path"` + Configuration interface{} `json:"configuration"` + }{ + Uuid: c.Uuid, + Found: c.Found, + URL: c.URL, + Path: c.Path, + Configuration: c.Configuration, + }) +} + // Timeout configuration to handle the cache provider and the // reverse-proxy timeout. type Timeout struct { @@ -258,6 +279,7 @@ type DefaultCache struct { DefaultCacheControl string `json:"default_cache_control" yaml:"default_cache_control"` MaxBodyBytes uint64 `json:"max_cacheable_body_bytes" yaml:"max_cacheable_body_bytes"` DisableCoalescing bool `json:"disable_coalescing" yaml:"disable_coalescing"` + MappingEvictionInterval Duration `json:"mapping_eviction_interval" yaml:"mapping_eviction_interval"` } // GetAllowedHTTPVerbs returns the allowed verbs to cache @@ -380,6 +402,14 @@ func (d *DefaultCache) IsCoalescingDisable() bool { return d.DisableCoalescing } +// GetMappingEvictionInterval returns the interval for mapping eviction +func (d *DefaultCache) GetMappingEvictionInterval() time.Duration { + if d.MappingEvictionInterval.Duration == 0 { + return time.Minute + } + return d.MappingEvictionInterval.Duration +} + // DefaultCacheInterface interface type DefaultCacheInterface interface { GetAllowedHTTPVerbs() []string @@ -406,6 +436,7 @@ type DefaultCacheInterface interface { GetDefaultCacheControl() string GetMaxBodyBytes() uint64 IsCoalescingDisable() bool + GetMappingEvictionInterval() time.Duration } // APIEndpoint is the minimal structure to define an endpoint @@ -456,7 +487,10 @@ type AbstractConfigurationInterface interface { GetDefaultCache() DefaultCacheInterface GetAPI() API GetLogLevel() string + GetLogger() core.Logger + SetLogger(core.Logger) GetYkeys() map[string]SurrogateKeys GetSurrogateKeys() map[string]SurrogateKeys + IsSurrogateDisabled() bool GetCacheKeys() CacheKeys } diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/context/cache.go b/plugins/traefik/vendor/github.com/darkweak/souin/context/cache.go index c4051f0c4..0e24066b4 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/context/cache.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/context/cache.go @@ -28,6 +28,7 @@ func (cc *cacheContext) SetupContext(c configurationtypes.AbstractConfigurationI if c.GetDefaultCache().GetCacheName() != "" { cc.cacheName = c.GetDefaultCache().GetCacheName() } + c.GetLogger().Debugf("Set %s as Cache-Status name", cc.cacheName) } func (cc *cacheContext) SetContext(req *http.Request) *http.Request { diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/context/graphql.go b/plugins/traefik/vendor/github.com/darkweak/souin/context/graphql.go index 46def862e..d37922136 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/context/graphql.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/context/graphql.go @@ -50,6 +50,7 @@ func (g *graphQLContext) SetContextWithBaseRequest(req *http.Request, baseRq *ht func (g *graphQLContext) SetupContext(c configurationtypes.AbstractConfigurationInterface) { if len(c.GetDefaultCache().GetAllowedHTTPVerbs()) != 0 { g.custom = true + c.GetLogger().Debug("Enable GraphQL logic due to your custom HTTP verbs setup.") } } diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/context/key.go b/plugins/traefik/vendor/github.com/darkweak/souin/context/key.go index d4edc3a85..ab0e99dbe 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/context/key.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/context/key.go @@ -5,7 +5,10 @@ import ( "net/http" "regexp" + "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/modules/caddyhttp" "github.com/darkweak/souin/configurationtypes" + "github.com/darkweak/storages/core" ) const ( @@ -20,8 +23,8 @@ type keyContext struct { disable_host bool disable_method bool disable_query bool - disable_scheme bool disable_vary bool + disable_scheme bool displayable bool hash bool headers []string @@ -50,24 +53,34 @@ func (g *keyContext) SetupContext(c configurationtypes.AbstractConfigurationInte g.overrides = make([]map[*regexp.Regexp]keyContext, 0) - // for _, cacheKey := range c.GetCacheKeys() { - // for r, v := range cacheKey { - // g.overrides = append(g.overrides, map[*regexp.Regexp]keyContext{r.Regexp: { - // disable_body: v.DisableBody, - // disable_host: v.DisableHost, - // disable_method: v.DisableMethod, - // disable_query: v.DisableQuery, - // disable_scheme: v.DisableScheme, - // hash: v.Hash, - // displayable: !v.Hide, - // template: v.Template, - // headers: v.Headers, - // }}) - // } - // } - - g.initializer = func(r *http.Request) *http.Request { - return r + for _, cacheKey := range c.GetCacheKeys() { + for r, v := range cacheKey { + g.overrides = append(g.overrides, map[*regexp.Regexp]keyContext{r.Regexp: { + disable_body: v.DisableBody, + disable_host: v.DisableHost, + disable_method: v.DisableMethod, + disable_query: v.DisableQuery, + disable_scheme: v.DisableScheme, + disable_vary: v.DisableVary, + hash: v.Hash, + displayable: !v.Hide, + template: v.Template, + headers: v.Headers, + }}) + } + } + + switch c.GetPluginName() { + case "caddy": + g.initializer = func(r *http.Request) *http.Request { + return r + } + default: + g.initializer = func(r *http.Request) *http.Request { + repl := caddy.NewReplacer() + + return caddyhttp.PrepareRequest(r, repl, nil, nil) + } } } @@ -107,6 +120,9 @@ func parseKeyInformations(req *http.Request, kCtx keyContext) (query, body, host } func (g *keyContext) computeKey(req *http.Request) (key string, headers []string, hash, displayable bool) { + if g.template != "" { + return req.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer).ReplaceAll(g.template, ""), g.headers, g.hash, g.displayable + } key = req.URL.Path query, body, host, scheme, method, headerValues, headers, displayable, hash := parseKeyInformations(req, *g) @@ -114,6 +130,9 @@ func (g *keyContext) computeKey(req *http.Request) (key string, headers []string for _, current := range g.overrides { for k, v := range current { if k.MatchString(req.RequestURI) { + if v.template != "" { + return req.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer).ReplaceAll(v.template, ""), v.headers, v.hash, v.displayable + } query, body, host, scheme, method, headerValues, headers, displayable, hash = parseKeyInformations(req, v) hasOverride = true break @@ -139,9 +158,13 @@ func (g *keyContext) SetContext(req *http.Request) *http.Request { context.WithValue( context.WithValue( context.WithValue( - req.Context(), - Key, - key, + context.WithValue( + req.Context(), + Key, + key, + ), + core.DISABLE_VARY_CTX, //nolint:staticcheck // we don't care about collision + g.disable_vary, ), Hashed, hash, diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/context/method.go b/plugins/traefik/vendor/github.com/darkweak/souin/context/method.go index ee772a3de..502e4f2cd 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/context/method.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/context/method.go @@ -26,6 +26,7 @@ func (m *methodContext) SetupContext(c configurationtypes.AbstractConfigurationI m.allowedVerbs = c.GetDefaultCache().GetAllowedHTTPVerbs() m.custom = true } + c.GetLogger().Debugf("Allow %d method(s). %v.", len(m.allowedVerbs), m.allowedVerbs) } func (m *methodContext) SetContext(req *http.Request) *http.Request { diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/context/mode.go b/plugins/traefik/vendor/github.com/darkweak/souin/context/mode.go index ec2d5221d..d436152b5 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/context/mode.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/context/mode.go @@ -22,6 +22,7 @@ func (mc *ModeContext) SetupContext(c configurationtypes.AbstractConfigurationIn mc.Bypass_request = mode == "bypass" || mode == "bypass_request" mc.Bypass_response = mode == "bypass" || mode == "bypass_response" mc.Strict = !mc.Bypass_request && !mc.Bypass_response + c.GetLogger().Debugf("The cache logic will run as %s: %+v", mode, mc) } func (mc *ModeContext) SetContext(req *http.Request) *http.Request { diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/context/now.go b/plugins/traefik/vendor/github.com/darkweak/souin/context/now.go index d0d4e0f3b..da52beb39 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/context/now.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/context/now.go @@ -19,8 +19,16 @@ func (*nowContext) SetContextWithBaseRequest(req *http.Request, _ *http.Request) func (cc *nowContext) SetupContext(_ configurationtypes.AbstractConfigurationInterface) {} func (cc *nowContext) SetContext(req *http.Request) *http.Request { - now := time.Now().UTC() - req.Header.Set("Date", now.Format(time.RFC1123)) + var now time.Time + var e error + + now, e = time.Parse(time.RFC1123, req.Header.Get("Date")) + + if e != nil { + now = time.Now().UTC() + req.Header.Set("Date", now.Format(time.RFC1123)) + } + return req.WithContext(context.WithValue(req.Context(), Now, now)) } diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/context/timeout.go b/plugins/traefik/vendor/github.com/darkweak/souin/context/timeout.go index 4da27d984..a38fb593e 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/context/timeout.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/context/timeout.go @@ -35,6 +35,8 @@ func (t *timeoutContext) SetupContext(c configurationtypes.AbstractConfiguration if c.GetDefaultCache().GetTimeout().Backend.Duration != 0 { t.timeoutBackend = c.GetDefaultCache().GetTimeout().Backend.Duration } + c.GetLogger().Infof("Set backend timeout to %v", t.timeoutBackend) + c.GetLogger().Infof("Set cache timeout to %v", t.timeoutCache) } func (t *timeoutContext) SetContext(req *http.Request) *http.Request { diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/debug/debug.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/debug/debug.go new file mode 100644 index 000000000..00856f5c5 --- /dev/null +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/debug/debug.go @@ -0,0 +1,87 @@ +package debug + +import ( + "net/http" + "net/http/pprof" + "strings" + + "github.com/darkweak/souin/configurationtypes" +) + +// DebugAPI object contains informations related to the endpoints +type DebugAPI struct { + basePath string + enabled bool +} + +type DefaultHandler struct{} + +func (d *DefaultHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + pprof.Index(w, r) +} + +// InitializeDebug initialize the debug endpoints +func InitializeDebug(configuration configurationtypes.AbstractConfigurationInterface) *DebugAPI { + basePath := configuration.GetAPI().Debug.BasePath + enabled := configuration.GetAPI().Debug.Enable + if basePath == "" { + basePath = "/debug/" + } + + return &DebugAPI{ + basePath, + enabled, + } +} + +// GetBasePath will return the basepath for this resource +func (p *DebugAPI) GetBasePath() string { + return p.basePath +} + +// IsEnabled will return enabled status +func (p *DebugAPI) IsEnabled() bool { + return p.enabled +} + +// HandleRequest will handle the request +func (p *DebugAPI) HandleRequest(w http.ResponseWriter, r *http.Request) { + var executor http.Handler + executor = &DefaultHandler{} + + if strings.Contains(r.RequestURI, "allocs") { + executor = pprof.Handler("allocs") + } + if strings.Contains(r.RequestURI, "cmdline") { + executor = pprof.Handler("cmdline") + } + if strings.Contains(r.RequestURI, "profile") { + executor = pprof.Handler("profile") + } + if strings.Contains(r.RequestURI, "symbol") { + executor = pprof.Handler("symbol") + } + if strings.Contains(r.RequestURI, "trace") { + executor = pprof.Handler("trace") + } + if strings.Contains(r.RequestURI, "goroutine") { + executor = pprof.Handler("goroutine") + } + if strings.Contains(r.RequestURI, "heap") { + executor = pprof.Handler("heap") + } + if strings.Contains(r.RequestURI, "block") { + executor = pprof.Handler("block") + } + if strings.Contains(r.RequestURI, "heap") { + executor = pprof.Handler("heap") + } + if strings.Contains(r.RequestURI, "mutex") { + executor = pprof.Handler("mutex") + } + if strings.Contains(r.RequestURI, "threadcreate") { + executor = pprof.Handler("threadcreate") + } + + executor.ServeHTTP(w, r) +} diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/main.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/main.go index 03230b136..810f447ff 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/main.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/main.go @@ -4,6 +4,8 @@ import ( "net/http" "github.com/darkweak/souin/configurationtypes" + "github.com/darkweak/souin/pkg/api/debug" + "github.com/darkweak/souin/pkg/api/prometheus" "github.com/darkweak/souin/pkg/storage/types" "github.com/darkweak/souin/pkg/surrogate/providers" ) @@ -31,9 +33,7 @@ func GenerateHandlerMap( for _, endpoint := range Initialize(configuration, storers, surrogateStorage) { if endpoint.IsEnabled() { shouldEnable = true - if e, ok := endpoint.(*SouinAPI); ok { - hm[basePathAPIS+endpoint.GetBasePath()] = e.HandleRequest - } + hm[basePathAPIS+endpoint.GetBasePath()] = endpoint.HandleRequest } } @@ -46,5 +46,6 @@ func GenerateHandlerMap( // Initialize contains all apis that should be enabled func Initialize(c configurationtypes.AbstractConfigurationInterface, storers []types.Storer, surrogateStorage providers.SurrogateInterface) []EndpointInterface { - return []EndpointInterface{initializeSouin(c, storers, surrogateStorage)} + return []EndpointInterface{initializeSouin(c, storers, + surrogateStorage), debug.InitializeDebug(c), prometheus.InitializePrometheus(c)} } diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/prometheus/prometheus.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/prometheus/prometheus.go index 2712571d6..051d122f6 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/prometheus/prometheus.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/prometheus/prometheus.go @@ -1,5 +1,107 @@ package prometheus -const RequestCounter = "" +import ( + "net/http" -func Increment(string) {} + "github.com/darkweak/souin/configurationtypes" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" +) + +const ( + counter = "counter" + average = "average" + + RequestCounter = "souin_request_upstream_counter" + RequestRevalidationCounter = "souin_request_revalidation_counter" + NoCachedResponseCounter = "souin_no_cached_response_counter" + CachedResponseCounter = "souin_cached_response_counter" + AvgResponseTime = "souin_avg_response_time" +) + +// PrometheusAPI object contains informations related to the endpoints +type PrometheusAPI struct { + basePath string + enabled bool +} + +// InitializePrometheus initialize the prometheus endpoints +func InitializePrometheus(configuration configurationtypes.AbstractConfigurationInterface) *PrometheusAPI { + basePath := configuration.GetAPI().Prometheus.BasePath + enabled := configuration.GetAPI().Prometheus.Enable + if basePath == "" { + basePath = "/metrics" + } + + if registered == nil { + run() + } + return &PrometheusAPI{ + basePath, + enabled, + } +} + +// GetBasePath will return the basepath for this resource +func (p *PrometheusAPI) GetBasePath() string { + return p.basePath +} + +// IsEnabled will return enabled status +func (p *PrometheusAPI) IsEnabled() bool { + return p.enabled +} + +// HandleRequest will handle the request +func (p *PrometheusAPI) HandleRequest(w http.ResponseWriter, r *http.Request) { + promhttp.Handler().ServeHTTP(w, r) +} + +var registered map[string]interface{} + +// Increment will increment the counter. +func Increment(name string) { + if _, ok := registered[name]; ok { + registered[name].(prometheus.Counter).Inc() + } +} + +// Increment will add the referred value the counter. +func Add(name string, value float64) { + if c, ok := registered[name].(prometheus.Counter); ok { + c.Add(value) + } + if g, ok := registered[name].(prometheus.Histogram); ok { + g.Observe(value) + } +} + +func push(promType, name, help string) { + switch promType { + case counter: + registered[name] = promauto.NewCounter(prometheus.CounterOpts{ + Name: name, + Help: help, + }) + + return + case average: + avg := prometheus.NewHistogram(prometheus.HistogramOpts{ + Name: name, + Help: help, + }) + prometheus.MustRegister(avg) + registered[name] = avg + } +} + +// Run populate and prepare the map with the default values. +func run() { + registered = make(map[string]interface{}) + push(counter, RequestCounter, "Total upstream request counter") + push(counter, RequestRevalidationCounter, "Total revalidation request revalidation counter") + push(counter, NoCachedResponseCounter, "No cached response counter") + push(counter, CachedResponseCounter, "Cached response counter") + push(average, AvgResponseTime, "Average response time") +} diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/souin.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/souin.go index 8f5305cb9..d5888b50d 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/souin.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/api/souin.go @@ -6,10 +6,14 @@ import ( "net/http" "regexp" "strings" + "time" "github.com/darkweak/souin/configurationtypes" "github.com/darkweak/souin/pkg/storage/types" "github.com/darkweak/souin/pkg/surrogate/providers" + "github.com/darkweak/storages/core" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/timestamppb" ) // SouinAPI object contains informations related to the endpoints @@ -62,16 +66,54 @@ func initializeSouin( } // BulkDelete allow user to delete multiple items with regexp -func (s *SouinAPI) BulkDelete(key string) { +func (s *SouinAPI) BulkDelete(key string, purge bool) { + key, _ = strings.CutPrefix(key, core.MappingKeyPrefix) for _, current := range s.storers { - current.DeleteMany(key) + if b := current.Get(core.MappingKeyPrefix + key); len(b) > 0 { + var mapping core.StorageMapper + + if e := proto.Unmarshal(b, &mapping); e == nil { + for k := range mapping.GetMapping() { + current.Delete(k) + } + } + + if !purge { + newFreshTime := time.Now() + for k, v := range mapping.Mapping { + v.FreshTime = timestamppb.New(newFreshTime) + mapping.Mapping[k] = v + } + + v, e := proto.Marshal(&mapping) + if e != nil { + fmt.Println("Impossible to re-encode the mapping", core.MappingKeyPrefix+key) + current.Delete(core.MappingKeyPrefix + key) + } + _ = current.Set(core.MappingKeyPrefix+key, v, storageToInfiniteTTLMap[current.Name()]) + } + } + + if purge { + current.Delete(core.MappingKeyPrefix + key) + } + + current.Delete(key) } + + s.Delete(key) } // Delete will delete a record into the provider cache system and will update the Souin API if enabled +// The key can be a regexp to delete multiple items func (s *SouinAPI) Delete(key string) { + _, err := regexp.Compile(key) for _, current := range s.storers { - current.Delete(key) + if err != nil { + current.DeleteMany(key) + } else { + current.Delete(key) + } } } @@ -110,6 +152,63 @@ func (s *SouinAPI) listKeys(search string) []string { return res } +var storageToInfiniteTTLMap = map[string]time.Duration{ + "BADGER": types.OneYearDuration, + "ETCD": types.OneYearDuration, + "GO-REDIS": 0, + "NUTS": 0, + "OLRIC": types.OneYearDuration, + "OTTER": types.OneYearDuration, + "REDIS": -1, + "SIMPLEFS": 0, + types.DefaultStorageName: types.OneYearDuration, +} + +func EvictMapping(current types.Storer) { + values := current.MapKeys(core.MappingKeyPrefix) + now := time.Now() + infiniteStoreDuration := storageToInfiniteTTLMap[current.Name()] + + for k, v := range values { + mapping := &core.StorageMapper{} + + e := proto.Unmarshal([]byte(v), mapping) + if e != nil { + current.Delete(core.MappingKeyPrefix + k) + continue + } + + updated := false + for key, val := range mapping.GetMapping() { + if now.Sub(val.FreshTime.AsTime()) > 0 && now.Sub(val.StaleTime.AsTime()) > 0 { + delete(mapping.GetMapping(), key) + updated = true + } + } + + if updated { + v, e := proto.Marshal(mapping) + if e != nil { + fmt.Println("Impossible to re-encode the mapping", core.MappingKeyPrefix+k) + current.Delete(core.MappingKeyPrefix + k) + } + _ = current.Set(core.MappingKeyPrefix+k, v, infiniteStoreDuration) + } + + if len(mapping.GetMapping()) == 0 { + current.Delete(core.MappingKeyPrefix + k) + } + } +} + +func (s *SouinAPI) purgeMapping() { + for _, current := range s.storers { + EvictMapping(current) + } + + fmt.Println("Successfully clear the mappings.") +} + // HandleRequest will handle the request func (s *SouinAPI) HandleRequest(w http.ResponseWriter, r *http.Request) { res := []byte{} @@ -130,6 +229,9 @@ func (s *SouinAPI) HandleRequest(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") case http.MethodPost: var invalidator invalidation + defer func() { + _ = r.Body.Close() + }() err := json.NewDecoder(r.Body).Decode(&invalidator) if err != nil { w.WriteHeader(http.StatusBadRequest) @@ -139,7 +241,9 @@ func (s *SouinAPI) HandleRequest(w http.ResponseWriter, r *http.Request) { keysToInvalidate := []string{} switch invalidator.Type { case groupInvalidationType: - keysToInvalidate, _ = s.surrogateStorage.Purge(http.Header{"Surrogate-Key": invalidator.Groups}) + var surrogateKeys []string + keysToInvalidate, surrogateKeys = s.surrogateStorage.Purge(http.Header{"Surrogate-Key": invalidator.Groups}) + keysToInvalidate = append(keysToInvalidate, surrogateKeys...) case uriPrefixInvalidationType, uriInvalidationType: bodyKeys := []string{} listedKeys := s.GetAll() @@ -195,15 +299,14 @@ func (s *SouinAPI) HandleRequest(w http.ResponseWriter, r *http.Request) { } for _, k := range keysToInvalidate { - for _, current := range s.storers { - current.Delete(k) - } + s.BulkDelete(k, invalidator.Purge) } w.WriteHeader(http.StatusOK) case "PURGE": if compile { keysRg := regexp.MustCompile(s.GetBasePath() + "/(.+)") flushRg := regexp.MustCompile(s.GetBasePath() + "/flush$") + mappingRg := regexp.MustCompile(s.GetBasePath() + "/mapping$") if flushRg.FindString(r.RequestURI) != "" { for _, current := range s.storers { @@ -214,16 +317,21 @@ func (s *SouinAPI) HandleRequest(w http.ResponseWriter, r *http.Request) { fmt.Printf("Error while purging the surrogate keys: %+v.", e) } fmt.Println("Successfully clear the cache and the surrogate keys storage.") + } else if mappingRg.FindString(r.RequestURI) != "" { + s.purgeMapping() } else { submatch := keysRg.FindAllStringSubmatch(r.RequestURI, -1)[0][1] - s.BulkDelete(submatch) + for _, current := range s.storers { + current.DeleteMany(submatch) + } } } else { - ck, _ := s.surrogateStorage.Purge(r.Header) + ck, surrogateKeys := s.surrogateStorage.Purge(r.Header) for _, k := range ck { - for _, current := range s.storers { - current.Delete(k) - } + s.BulkDelete(k, true) + } + for _, k := range surrogateKeys { + s.BulkDelete("SURROGATE_"+k, true) } } w.WriteHeader(http.StatusNoContent) diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/configuration.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/configuration.go index 238dfcdb8..34bdd0c56 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/configuration.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/configuration.go @@ -2,6 +2,7 @@ package middleware import ( "github.com/darkweak/souin/configurationtypes" + "github.com/darkweak/storages/core" ) // BaseConfiguration holder @@ -11,6 +12,7 @@ type BaseConfiguration struct { CacheKeys configurationtypes.CacheKeys `json:"cache_keys" yaml:"cache_keys"` URLs map[string]configurationtypes.URL `json:"urls" yaml:"urls"` LogLevel string `json:"log_level" yaml:"log_level"` + Logger core.Logger PluginName string Ykeys map[string]configurationtypes.SurrogateKeys `json:"ykeys" yaml:"ykeys"` SurrogateKeys map[string]configurationtypes.SurrogateKeys `json:"surrogate_keys" yaml:"surrogate_keys"` @@ -42,6 +44,16 @@ func (c *BaseConfiguration) GetLogLevel() string { return c.LogLevel } +// GetLogger get the logger +func (c *BaseConfiguration) GetLogger() core.Logger { + return c.Logger +} + +// SetLogger set the logger +func (c *BaseConfiguration) SetLogger(l core.Logger) { + c.Logger = l +} + // GetYkeys get the ykeys list func (c *BaseConfiguration) GetYkeys() map[string]configurationtypes.SurrogateKeys { return c.SurrogateKeys diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/middleware.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/middleware.go index e81c15dfc..c9a02d07b 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/middleware.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/middleware.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "maps" "net/http" "net/http/httputil" "regexp" @@ -13,29 +14,172 @@ import ( "sync" "time" + "github.com/cespare/xxhash/v2" "github.com/darkweak/souin/configurationtypes" "github.com/darkweak/souin/context" "github.com/darkweak/souin/helpers" "github.com/darkweak/souin/pkg/api" + "github.com/darkweak/souin/pkg/api/prometheus" "github.com/darkweak/souin/pkg/rfc" "github.com/darkweak/souin/pkg/storage" "github.com/darkweak/souin/pkg/storage/types" "github.com/darkweak/souin/pkg/surrogate" "github.com/darkweak/souin/pkg/surrogate/providers" + "github.com/darkweak/storages/core" "github.com/google/uuid" "github.com/pquerna/cachecontrol/cacheobject" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" "golang.org/x/sync/singleflight" ) +func reorderStorers(storers []types.Storer, expectedStorers []string) []types.Storer { + if len(expectedStorers) == 0 { + return storers + } + + newStorers := make([]types.Storer, 0) + for _, expectedStorer := range expectedStorers { + for _, storer := range storers { + if storer.Name() == strings.ToUpper(expectedStorer) { + newStorers = append(newStorers, storer) + } + } + } + + return newStorers +} + +const ( + evictionLockKey = "eviction-lock" + evictionLockTTL = 2 * time.Minute +) + +// evictionLockHolder is a unique identifier for this instance, used for distributed lock ownership. +var evictionLockHolder = uuid.NewString() + +func tryAcquireEvictionLock(storer types.Storer) bool { + now := time.Now() + existing := storer.Get(evictionLockKey) + + if len(existing) > 0 { + // Lock value format: "holder_id|expiry_timestamp" + parts := strings.SplitN(string(existing), "|", 2) + if len(parts) == 2 { + holderID := parts[0] + lockedUntil, err := time.Parse(time.RFC3339, parts[1]) + if err == nil && now.Before(lockedUntil) { + // Lock is still valid - check if we own it + if holderID == evictionLockHolder { + return true + } + return false + } + } + } + + // Lock expired or doesn't exist - attempt to claim it using optimistic locking + newLockExpiry := now.Add(evictionLockTTL) + lockValue := evictionLockHolder + "|" + newLockExpiry.Format(time.RFC3339) + if err := storer.Set(evictionLockKey, []byte(lockValue), evictionLockTTL); err != nil { + return false + } + + // Verify we actually got the lock (optimistic locking) + // Another instance might have written between our check and set + time.Sleep(10 * time.Millisecond) + verifyValue := storer.Get(evictionLockKey) + return string(verifyValue) == lockValue +} + +func registerMappingKeysEviction(logger core.Logger, storers []types.Storer, interval time.Duration) { + for _, storer := range storers { + logger.Debugf("registering mapping eviction for storer %s (interval: %s)", storer.Name(), interval) + go func(current types.Storer, currentInterval time.Duration) { + for { + if !tryAcquireEvictionLock(current) { + logger.Debugf("skipping mapping eviction for storer %s, another instance holds the lock", current.Name()) + time.Sleep(currentInterval) + + continue + } + + logger.Debugf("run mapping eviction for storer %s", current.Name()) + api.EvictMapping(current) + <-time.After(10 * time.Minute) + } + }(storer, interval) + } +} + func NewHTTPCacheHandler(c configurationtypes.AbstractConfigurationInterface) *SouinBaseHandler { - storers, err := storage.NewStorages(c) - if err != nil { - panic(err) + if c.GetLogger() == nil { + var logLevel zapcore.Level + if c.GetLogLevel() == "" { + logLevel = zapcore.FatalLevel + } else if err := logLevel.UnmarshalText([]byte(c.GetLogLevel())); err != nil { + logLevel = zapcore.FatalLevel + } + cfg := zap.Config{ + Encoding: "json", + Level: zap.NewAtomicLevelAt(logLevel), + OutputPaths: []string{"stderr"}, + ErrorOutputPaths: []string{"stderr"}, + EncoderConfig: zapcore.EncoderConfig{ + MessageKey: "message", + + LevelKey: "level", + EncodeLevel: zapcore.CapitalLevelEncoder, + + TimeKey: "time", + EncodeTime: zapcore.ISO8601TimeEncoder, + + CallerKey: "caller", + EncodeCaller: zapcore.ShortCallerEncoder, + }, + } + logger, _ := cfg.Build() + c.SetLogger(logger.Sugar()) + } + + storedStorers := core.GetRegisteredStorers() + storers := []types.Storer{} + if len(storedStorers) != 0 { + dc := c.GetDefaultCache() + for _, s := range []string{dc.GetBadger().Uuid, dc.GetEtcd().Uuid, dc.GetNats().Uuid, dc.GetNuts().Uuid, dc.GetOlric().Uuid, dc.GetOtter().Uuid, dc.GetRedis().Uuid, dc.GetSimpleFS().Uuid} { + if s != "" { + if st := core.GetRegisteredStorer(s); st != nil { + storers = append(storers, st.(types.Storer)) + } + } + } + + storers = reorderStorers(storers, c.GetDefaultCache().GetStorers()) + + if len(storers) > 0 { + names := []string{} + for _, storer := range storers { + names = append(names, storer.Name()) + } + c.GetLogger().Debugf("You're running Souin with the following storages in this order %s", strings.Join(names, ", ")) + } + } + if len(storers) == 0 { + c.GetLogger().Warn("You're running Souin with the default storage that is not optimized and for development purpose. We recommend to use at least one of the storages from https://github.com/darkweak/storages") + + memoryStorer, _ := storage.Factory(c) + if st := core.GetRegisteredStorer(types.DefaultStorageName + "-"); st != nil { + memoryStorer = st.(types.Storer) + } else { + core.RegisterStorage(memoryStorer) + } + storers = append(storers, memoryStorer) } - fmt.Println("Storers initialized.") + + c.GetLogger().Debugf("Storer initialized: %#v.", storers) regexpUrls := helpers.InitializeRegexp(c) - surrogateStorage := surrogate.InitializeSurrogate(c, storers[0].Name()) - fmt.Println("Surrogate storage initialized.") + surrogateStorage := surrogate.InitializeSurrogate(c, fmt.Sprintf("%s-%s", storers[0].Name(), storers[0].Uuid())) + c.GetLogger().Debug("Surrogate storage initialized.") var excludedRegexp *regexp.Regexp = nil if c.GetDefaultCache().GetRegex().Exclude != "" { excludedRegexp = regexp.MustCompile(c.GetDefaultCache().GetRegex().Exclude) @@ -54,7 +198,10 @@ func NewHTTPCacheHandler(c configurationtypes.AbstractConfigurationInterface) *S Headers: c.GetDefaultCache().GetHeaders(), DefaultCacheControl: c.GetDefaultCache().GetDefaultCacheControl(), } - fmt.Println("Souin configuration is now loaded.") + c.GetLogger().Info("Souin configuration is now loaded.") + c.GetLogger().Debugf("Configuration: %#v.", c.GetDefaultCache()) + + registerMappingKeysEviction(c.GetLogger(), storers, c.GetDefaultCache().GetMappingEvictionInterval()) return &SouinBaseHandler{ Configuration: c, @@ -137,6 +284,7 @@ func (s *SouinBaseHandler) Store( rq *http.Request, requestCc *cacheobject.RequestCacheDirectives, cachedKey string, + uri string, ) error { statusCode := customWriter.GetStatusCode() if !isCacheableCode(statusCode) && !s.hasAllowedAdditionalStatusCodesToCache(statusCode) { @@ -161,6 +309,7 @@ func (s *SouinBaseHandler) Store( } responseCc, _ := cacheobject.ParseResponseCacheControl(rfc.HeaderAllCommaSepValuesString(customWriter.Header(), headerName)) + s.Configuration.GetLogger().Debugf("Response cache-control %+v", responseCc) if responseCc == nil { customWriter.Header().Set("Cache-Status", fmt.Sprintf("%s; fwd=uri-miss; key=%s; detail=INVALID-RESPONSE-CACHE-CONTROL", rq.Context().Value(context.CacheName), rfc.GetCacheKeyFromCtx(rq.Context()))) return nil @@ -251,13 +400,18 @@ func (s *SouinBaseHandler) Store( } res.Header.Set(rfc.StoredLengthHeader, res.Header.Get("Content-Length")) response, err := httputil.DumpResponse(&res, true) - if err == nil && (bLen > 0 || canStatusCodeEmptyContent(statusCode) || s.hasAllowedAdditionalStatusCodesToCache(statusCode)) { + if err == nil && (bLen > 0 || rq.Method == http.MethodHead || canStatusCodeEmptyContent(statusCode) || s.hasAllowedAdditionalStatusCodesToCache(statusCode)) { variedHeaders, isVaryStar := rfc.VariedHeaderAllCommaSepValues(res.Header) if isVaryStar { // "Implies that the response is uncacheable" status += "; detail=UPSTREAM-VARY-STAR" } else { variedKey := cachedKey + rfc.GetVariedCacheKey(rq, variedHeaders) + if rq.Context().Value(context.Hashed).(bool) { + cachedKey = fmt.Sprint(xxhash.Sum64String(cachedKey)) + variedKey = fmt.Sprint(xxhash.Sum64String(variedKey)) + } + s.Configuration.GetLogger().Debugf("Store the response for %s with duration %v", variedKey, ma) var wg sync.WaitGroup mu := sync.Mutex{} @@ -271,32 +425,61 @@ func (s *SouinBaseHandler) Store( hn := strings.Split(hname, ":") vhs.Set(hn[0], rq.Header.Get(hn[0])) } - for _, storer := range s.Storers { - wg.Add(1) - go func(currentStorer types.Storer) { - defer wg.Done() - if currentStorer.SetMultiLevel( - cachedKey, - variedKey, - response, - vhs, - res.Header.Get("Etag"), ma, - variedKey, - ) == nil { - res.Request = rq - } else { - mu.Lock() - fails = append(fails, fmt.Sprintf("; detail=%s-INSERTION-ERROR", currentStorer.Name())) - mu.Unlock() + if upstreamStorerTarget := res.Header.Get("X-Souin-Storer"); upstreamStorerTarget != "" { + res.Header.Del("X-Souin-Storer") + + var overridedStorer types.Storer + for _, storer := range s.Storers { + if strings.Contains(strings.ToLower(storer.Name()), strings.ToLower(upstreamStorerTarget)) { + overridedStorer = storer } - }(storer) + } + + if overridedStorer.SetMultiLevel( + cachedKey, + variedKey, + response, + vhs, + res.Header.Get("Etag"), ma, + variedKey, + ) == nil { + s.Configuration.GetLogger().Debugf("Stored the key %s in the %s provider", variedKey, overridedStorer.Name()) + res.Request = rq + } else { + fails = append(fails, fmt.Sprintf("; detail=%s-INSERTION-ERROR", overridedStorer.Name())) + } + } else { + for _, storer := range s.Storers { + wg.Add(1) + go func(currentStorer types.Storer, currentRes http.Response) { + defer wg.Done() + if currentStorer.SetMultiLevel( + cachedKey, + variedKey, + response, + vhs, + currentRes.Header.Get("Etag"), ma, + variedKey, + ) == nil { + s.Configuration.GetLogger().Debugf("Stored the key %s in the %s provider", variedKey, currentStorer.Name()) + currentRes.Request = rq + } else { + mu.Lock() + fails = append(fails, fmt.Sprintf("; detail=%s-INSERTION-ERROR", currentStorer.Name())) + mu.Unlock() + } + }(storer, res) + } } wg.Wait() if len(fails) < s.storersLen { - go func(rs http.Response, key string) { - _ = s.SurrogateKeyStorer.Store(&rs, key, "") - }(res, variedKey) + if !s.Configuration.IsSurrogateDisabled() { + go func(rs http.Response, key string) { + _ = s.SurrogateKeyStorer.Store(&rs, key, uri) + }(res, variedKey) + } + status += "; stored" } @@ -318,10 +501,11 @@ func (s *SouinBaseHandler) Store( } type singleflightValue struct { - body []byte - headers http.Header - requestHeaders http.Header - code int + body []byte + headers http.Header + requestHeaders http.Header + code int + disableCoalescing bool } func (s *SouinBaseHandler) Upstream( @@ -330,7 +514,12 @@ func (s *SouinBaseHandler) Upstream( next handlerFunc, requestCc *cacheobject.RequestCacheDirectives, cachedKey string, + uri string, + disableCoalescing bool, ) error { + s.Configuration.GetLogger().Debug("Request the upstream server") + prometheus.Increment(prometheus.RequestCounter) + var recoveredFromErr error = nil defer func() { // In case of "http.ErrAbortHandler" panic, @@ -347,16 +536,19 @@ func (s *SouinBaseHandler) Upstream( }() singleflightCacheKey := cachedKey - if s.Configuration.GetDefaultCache().IsCoalescingDisable() { + if s.Configuration.GetDefaultCache().IsCoalescingDisable() || disableCoalescing { singleflightCacheKey += uuid.NewString() } - sfValue, err, _ := s.singleflightPool.Do(singleflightCacheKey, func() (interface{}, error) { + sfValue, err, shared := s.singleflightPool.Do(singleflightCacheKey, func() (interface{}, error) { if e := next(customWriter, rq); e != nil { + s.Configuration.GetLogger().Warnf("%#v", e) customWriter.Header().Set("Cache-Status", fmt.Sprintf("%s; fwd=uri-miss; key=%s; detail=SERVE-HTTP-ERROR", rq.Context().Value(context.CacheName), rfc.GetCacheKeyFromCtx(rq.Context()))) return nil, e } - s.SurrogateKeyStorer.Invalidate(rq.Method, customWriter.Header()) + if !s.Configuration.IsSurrogateDisabled() { + s.SurrogateKeyStorer.Invalidate(rq.Method, customWriter.Header()) + } statusCode := customWriter.GetStatusCode() if !isCacheableCode(statusCode) && !s.hasAllowedAdditionalStatusCodesToCache(statusCode) { @@ -373,16 +565,23 @@ func (s *SouinBaseHandler) Upstream( customWriter.Header().Set(headerName, s.DefaultMatchedUrl.DefaultCacheControl) } - err := s.Store(customWriter, rq, requestCc, cachedKey) + err := s.Store(customWriter, rq, requestCc, cachedKey, uri) + + // Copy the buffer bytes so the returned value is independent of the + // underlying buffer, which may be reset or returned to the pool. + bodySnapshot := make([]byte, customWriter.Buf.Len()) + copy(bodySnapshot, customWriter.Buf.Bytes()) + defer customWriter.handleBuffer(func(b *bytes.Buffer) { b.Reset() }) return singleflightValue{ - body: customWriter.Buf.Bytes(), - headers: customWriter.Header().Clone(), - requestHeaders: rq.Header, - code: statusCode, + body: bodySnapshot, + headers: customWriter.Header().Clone(), + requestHeaders: rq.Header, + code: statusCode, + disableCoalescing: strings.Contains(cacheControl, "private") || customWriter.Header().Get("Set-Cookie") != "", }, err }) if recoveredFromErr != nil { @@ -393,37 +592,48 @@ func (s *SouinBaseHandler) Upstream( } if sfWriter, ok := sfValue.(singleflightValue); ok { + if shared && sfWriter.disableCoalescing { + return s.Upstream(customWriter, rq, next, requestCc, cachedKey, uri, true) + } + if vary := sfWriter.headers.Get("Vary"); vary != "" { variedHeaders, isVaryStar := rfc.VariedHeaderAllCommaSepValues(sfWriter.headers) if !isVaryStar { for _, vh := range variedHeaders { if rq.Header.Get(vh) != sfWriter.requestHeaders.Get(vh) { // cachedKey += rfc.GetVariedCacheKey(rq, variedHeaders) - return s.Upstream(customWriter, rq, next, requestCc, cachedKey) + return s.Upstream(customWriter, rq, next, requestCc, cachedKey, uri, false) } } } } + + if shared { + s.Configuration.GetLogger().Infof("Reused response from concurrent request with the key %s", cachedKey) + } customWriter.Buf.Reset() _, _ = customWriter.Write(sfWriter.body) - // Yaegi sucks, we can't use maps. - for k := range sfWriter.headers { - customWriter.Header().Set(k, sfWriter.headers.Get(k)) - } + maps.Copy(customWriter.Header(), sfWriter.headers) customWriter.WriteHeader(sfWriter.code) } return nil } -func (s *SouinBaseHandler) Revalidate(validator *types.Revalidator, next handlerFunc, customWriter *CustomWriter, rq *http.Request, requestCc *cacheobject.RequestCacheDirectives, cachedKey string, uri string) error { +func (s *SouinBaseHandler) Revalidate(validator *core.Revalidator, next handlerFunc, customWriter *CustomWriter, rq *http.Request, requestCc *cacheobject.RequestCacheDirectives, cachedKey string, uri string) error { + s.Configuration.GetLogger().Debug("Revalidate the request with the upstream server") + prometheus.Increment(prometheus.RequestRevalidationCounter) + singleflightCacheKey := cachedKey if s.Configuration.GetDefaultCache().IsCoalescingDisable() { singleflightCacheKey += uuid.NewString() } - sfValue, err, _ := s.singleflightPool.Do(singleflightCacheKey, func() (interface{}, error) { + sfValue, err, shared := s.singleflightPool.Do(singleflightCacheKey, func() (interface{}, error) { err := next(customWriter, rq) - s.SurrogateKeyStorer.Invalidate(rq.Method, customWriter.Header()) + + if !s.Configuration.IsSurrogateDisabled() { + s.SurrogateKeyStorer.Invalidate(rq.Method, customWriter.Header()) + } statusCode := customWriter.GetStatusCode() if err == nil { @@ -448,7 +658,7 @@ func (s *SouinBaseHandler) Revalidate(validator *types.Revalidator, next handler } if statusCode != http.StatusNotModified { - err = s.Store(customWriter, rq, requestCc, cachedKey) + err = s.Store(customWriter, rq, requestCc, cachedKey, uri) } } @@ -462,22 +672,28 @@ func (s *SouinBaseHandler) Revalidate(validator *types.Revalidator, next handler ), ) + // Copy the buffer bytes so the returned value is independent of the + // underlying buffer, which may be reset or returned to the pool. + bodySnapshot := make([]byte, customWriter.Buf.Len()) + copy(bodySnapshot, customWriter.Buf.Bytes()) + defer customWriter.handleBuffer(func(b *bytes.Buffer) { b.Reset() }) return singleflightValue{ - body: customWriter.Buf.Bytes(), + body: bodySnapshot, headers: customWriter.Header().Clone(), code: statusCode, }, err }) if sfWriter, ok := sfValue.(singleflightValue); ok { - _, _ = customWriter.Write(sfWriter.body) - // Yaegi sucks, we can't use maps. - for k := range sfWriter.headers { - customWriter.Header().Set(k, sfWriter.headers.Get(k)) + if shared { + s.Configuration.GetLogger().Infof("Reused response from concurrent request with the key %s", cachedKey) } + customWriter.Buf.Reset() + _, _ = customWriter.Write(sfWriter.body) + maps.Copy(customWriter.Header(), sfWriter.headers) customWriter.WriteHeader(sfWriter.code) } @@ -493,8 +709,7 @@ func (s *SouinBaseHandler) HandleInternally(r *http.Request) (bool, http.Handler } } - // Because Yægi interpretation sucks, we have to return the empty function instead of nil. - return false, func(w http.ResponseWriter, r *http.Request) {} + return false, nil } type handlerFunc = func(http.ResponseWriter, *http.Request) error @@ -508,7 +723,62 @@ func (s *statusCodeLogger) WriteHeader(code int) { s.ResponseWriter.WriteHeader(code) } +func (s *SouinBaseHandler) backfillStorers(idx int, cachedKey string, rq *http.Request, response *http.Response) { + if idx == 0 { + return + } + + storedDuration, err := time.ParseDuration(response.Header.Get(rfc.StoredTTLHeader)) + if err != nil { + return + } + + dateHeader, err := http.ParseTime(response.Header.Get("Date")) + if err != nil { + return + } + + now := time.Now() + + ma := storedDuration - now.Sub(dateHeader) + + variedHeaders, _ := rfc.VariedHeaderAllCommaSepValues(response.Header) + variedKey := cachedKey + rfc.GetVariedCacheKey(rq, variedHeaders) + + if rq.Context().Value(context.Hashed).(bool) { + cachedKey = fmt.Sprint(xxhash.Sum64String(cachedKey)) + variedKey = fmt.Sprint(xxhash.Sum64String(variedKey)) + } + + vhs := http.Header{} + for _, hname := range variedHeaders { + hn := strings.Split(hname, ":") + vhs.Set(hn[0], rq.Header.Get(hn[0])) + } + + res, _ := httputil.DumpResponse(response, true) + + for _, currentStorer := range s.Storers[:idx] { + err = currentStorer.SetMultiLevel( + cachedKey, + variedKey, + res, + vhs, + response.Header.Get("Etag"), ma, + variedKey, + ) + if err != nil { + s.Configuration.GetLogger().Errorf("Error while backfilling the storer %s: %v", currentStorer.Name(), err) + } + } +} + func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, next handlerFunc) error { + start := time.Now() + defer func(s time.Time) { + prometheus.Add(prometheus.AvgResponseTime, float64(time.Since(s).Milliseconds())) + }(start) + s.Configuration.GetLogger().Debugf("Incomming request %+v", rq) if b, handler := s.HandleInternally(rq); b { handler(rw, rq) return nil @@ -530,14 +800,17 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n } err := next(nrw, req) - s.SurrogateKeyStorer.Invalidate(req.Method, rw.Header()) + + if !s.Configuration.IsSurrogateDisabled() { + s.SurrogateKeyStorer.Invalidate(req.Method, rw.Header()) + } if err == nil && req.Method != http.MethodGet && nrw.statusCode < http.StatusBadRequest { // Invalidate related GET keys when the method is not allowed and the response is valid req.Method = http.MethodGet keyname := s.context.SetContext(req, rq).Context().Value(context.Key).(string) for _, storer := range s.Storers { - storer.Delete("IDX_" + keyname) + storer.Delete(core.MappingKeyPrefix + keyname) } } @@ -551,37 +824,45 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n rw.Header().Set("Cache-Status", cacheName+"; fwd=bypass; detail=CACHE-CONTROL-EXTRACTION-ERROR") err := next(rw, req) - s.SurrogateKeyStorer.Invalidate(req.Method, rw.Header()) + + if !s.Configuration.IsSurrogateDisabled() { + s.SurrogateKeyStorer.Invalidate(req.Method, rw.Header()) + } return err } req = s.context.SetContext(req, rq) - - isMutationRequest := false - // Yaegi sucks AGAIN, it considers the value as nil if we directly try to cast as bool - mutationRequestValue := req.Context().Value(context.IsMutationRequest) - if mutationRequestValue != nil { - isMutationRequest = mutationRequestValue.(bool) - } - - if isMutationRequest { + if req.Context().Value(context.IsMutationRequest).(bool) { rw.Header().Set("Cache-Status", cacheName+"; fwd=bypass; detail=IS-MUTATION-REQUEST") err := next(rw, req) - s.SurrogateKeyStorer.Invalidate(req.Method, rw.Header()) + + if !s.Configuration.IsSurrogateDisabled() { + s.SurrogateKeyStorer.Invalidate(req.Method, rw.Header()) + } return err } - cachedKey := req.Context().Value(context.Key).(string) // Need to copy URL path before calling next because it can alter the URI uri := req.URL.Path bufPool := s.bufPool.Get().(*bytes.Buffer) bufPool.Reset() - defer s.bufPool.Put(bufPool) + // Track whether the buffer ownership has been handed off to the background + // goroutine. If so, we must not return it to the pool on exit because the + // goroutine may still be writing to it. + bufPoolOwned := true + defer func() { + if bufPoolOwned { + s.bufPool.Put(bufPool) + } + }() + customWriter := NewCustomWriter(req, rw, bufPool) + customWriter.Headers.Add("Range", req.Header.Get("Range")) + req.Header.Del("Range") go func(req *http.Request, crw *CustomWriter) { <-req.Context().Done() @@ -590,22 +871,37 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n crw.mutex.Unlock() }(req, customWriter) + backfillIds := 0 + + s.Configuration.GetLogger().Debugf("Request cache-control %+v", requestCc) if modeContext.Bypass_request || !requestCc.NoCache { validator := rfc.ParseRequest(req) var fresh, stale *http.Response var storerName string + finalKey := cachedKey + if req.Context().Value(context.Hashed).(bool) { + finalKey = fmt.Sprint(xxhash.Sum64String(finalKey)) + } for _, currentStorer := range s.Storers { - fresh, stale = currentStorer.GetMultiLevel(cachedKey, req, validator) + fresh, stale = currentStorer.GetMultiLevel(finalKey, req, validator) if fresh != nil || stale != nil { storerName = currentStorer.Name() + s.Configuration.GetLogger().Debugf("Found at least one valid response in the %s storage", storerName) break } + + backfillIds++ } headerName, _ := s.SurrogateKeyStorer.GetSurrogateControl(customWriter.Header()) if fresh != nil && (!modeContext.Strict || rfc.ValidateCacheControl(fresh, requestCc)) { + go func() { + s.backfillStorers(backfillIds, cachedKey, req, fresh) + }() + response := fresh + if validator.ResponseETag != "" && validator.Matched { rfc.SetCacheStatusHeader(response, storerName) for h, v := range response.Header { @@ -637,6 +933,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n return err } if resCc, _ := cacheobject.ParseResponseCacheControl(rfc.HeaderAllCommaSepValuesString(response.Header, headerName)); !modeContext.Bypass_response && resCc.NoCachePresent { + prometheus.Increment(prometheus.NoCachedResponseCounter) err := s.Revalidate(validator, next, customWriter, req, requestCc, cachedKey, uri) _, _ = customWriter.Send() @@ -648,10 +945,12 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n customWriter.Header()[h] = v } customWriter.WriteHeader(response.StatusCode) + s.Configuration.GetLogger().Debugf("Serve from cache %+v", req) customWriter.handleBuffer(func(b *bytes.Buffer) { _, _ = io.Copy(b, response.Body) }) _, err := customWriter.Send() + prometheus.Increment(prometheus.CachedResponseCounter) return err } @@ -674,7 +973,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n }) _, err := customWriter.Send() customWriter = NewCustomWriter(req, rw, bufPool) - go func(v *types.Revalidator, goCw *CustomWriter, goRq *http.Request, goNext func(http.ResponseWriter, *http.Request) error, goCc *cacheobject.RequestCacheDirectives, goCk string, goUri string) { + go func(v *core.Revalidator, goCw *CustomWriter, goRq *http.Request, goNext func(http.ResponseWriter, *http.Request) error, goCc *cacheobject.RequestCacheDirectives, goCk string, goUri string) { _ = s.Revalidate(v, goNext, goCw, goRq, goCc, goCk, goUri) }(validator, customWriter, req, next, requestCc, cachedKey, uri) buf := s.bufPool.Get().(*bytes.Buffer) @@ -693,10 +992,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n code := fmt.Sprintf("; fwd-status=%d", statusCode) rfc.HitStaleCache(&response.Header) response.Header.Set("Cache-Status", response.Header.Get("Cache-Status")+code) - // Yaegi sucks, we can't use maps. - for k := range response.Header { - customWriter.Header().Set(k, response.Header.Get(k)) - } + maps.Copy(customWriter.Header(), response.Header) customWriter.WriteHeader(response.StatusCode) customWriter.handleBuffer(func(b *bytes.Buffer) { b.Reset() @@ -719,10 +1015,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n if !validator.Matched { rfc.SetCacheStatusHeader(response, storerName) customWriter.WriteHeader(response.StatusCode) - // Yaegi sucks, we can't use maps. - for k := range response.Header { - customWriter.Header().Set(k, response.Header.Get(k)) - } + maps.Copy(customWriter.Header(), response.Header) customWriter.handleBuffer(func(b *bytes.Buffer) { _, _ = io.Copy(b, response.Body) }) @@ -750,10 +1043,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n if !modeContext.Strict || rfc.ValidateMaxAgeCachedStaleResponse(requestCc, responseCc, response, int(addTime.Seconds())) != nil { customWriter.WriteHeader(response.StatusCode) rfc.HitStaleCache(&response.Header) - // Yaegi sucks, we can't use maps. - for k := range response.Header { - customWriter.Header().Set(k, response.Header.Get(k)) - } + maps.Copy(customWriter.Header(), response.Header) customWriter.handleBuffer(func(b *bytes.Buffer) { _, _ = io.Copy(b, response.Body) }) @@ -764,6 +1054,20 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n } } else if stale != nil { response := stale + + if !modeContext.Strict { + rfc.SetCacheStatusHeader(response, storerName) + customWriter.WriteHeader(response.StatusCode) + rfc.HitStaleCache(&response.Header) + maps.Copy(customWriter.Header(), response.Header) + customWriter.handleBuffer(func(b *bytes.Buffer) { + _, _ = io.Copy(b, response.Body) + }) + _, err := customWriter.Send() + + return err + } + addTime, _ := time.ParseDuration(response.Header.Get(rfc.StoredTTLHeader)) responseCc, _ := cacheobject.ParseResponseCacheControl(rfc.HeaderAllCommaSepValuesString(response.Header, "Cache-Control")) @@ -780,10 +1084,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n code := fmt.Sprintf("; fwd-status=%d", statusCode) rfc.HitStaleCache(&response.Header) response.Header.Set("Cache-Status", response.Header.Get("Cache-Status")+code) - // Yaegi sucks, we can't use maps. - for k := range response.Header { - customWriter.Header().Set(k, response.Header.Get(k)) - } + maps.Copy(customWriter.Header(), response.Header) customWriter.WriteHeader(response.StatusCode) customWriter.handleBuffer(func(b *bytes.Buffer) { b.Reset() @@ -799,29 +1100,34 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n } } - errorCacheCh := make(chan error) + errorCacheCh := make(chan error, 1) + // Release buffer ownership before launching the goroutine. The goroutine + // writes to customWriter (which wraps bufPool) and will finish + // asynchronously if the context is cancelled. + bufPoolOwned = false go func(vr *http.Request, cw *CustomWriter) { - errorCacheCh <- s.Upstream(cw, vr, next, requestCc, cachedKey) + prometheus.Increment(prometheus.NoCachedResponseCounter) + errorCacheCh <- s.Upstream(cw, vr, next, requestCc, cachedKey, uri, false) }(req, customWriter) select { case <-req.Context().Done(): - switch req.Context().Err() { case baseCtx.DeadlineExceeded: - customWriter.WriteHeader(http.StatusGatewayTimeout) rw.Header().Set("Cache-Status", cacheName+"; fwd=bypass; detail=DEADLINE-EXCEEDED") + customWriter.Rw.WriteHeader(http.StatusGatewayTimeout) _, _ = customWriter.Rw.Write([]byte("Internal server error")) + s.Configuration.GetLogger().Infof("Internal server error on endpoint %s: %v", req.URL, s.Storers) return baseCtx.DeadlineExceeded case baseCtx.Canceled: return baseCtx.Canceled default: return nil } - case v := <-errorCacheCh: - + // Goroutine has finished — safe to reclaim the buffer. + s.bufPool.Put(bufPool) switch v { case nil: _, _ = customWriter.Send() diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/writer.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/writer.go index 13208fad1..c4e836861 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/writer.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/writer.go @@ -5,8 +5,10 @@ import ( "fmt" "net/http" "strconv" + "strings" "sync" + "github.com/darkweak/go-esi/esi" "github.com/darkweak/souin/pkg/rfc" ) @@ -85,18 +87,134 @@ func (r *CustomWriter) Write(b []byte) (int, error) { return len(b), nil } +type rangeValue struct { + from, to int64 +} + +const separator = "--SOUIN-HTTP-CACHE-SEPARATOR" + +func parseRange(rangeHeaders []string, contentRange string) ([]rangeValue, rangeValue, int64) { + if len(rangeHeaders) == 0 { + return nil, rangeValue{}, -1 + } + + crv := rangeValue{from: 0, to: 0} + var total int64 = -1 + if contentRange != "" { + crVal := strings.Split(strings.TrimPrefix(contentRange, "bytes "), "/") + total, _ = strconv.ParseInt(crVal[1], 10, 64) + total-- + + crSplit := strings.Split(crVal[0], "-") + crv.from, _ = strconv.ParseInt(crSplit[0], 10, 64) + crv.to, _ = strconv.ParseInt(crSplit[1], 10, 64) + } + + values := make([]rangeValue, len(rangeHeaders)) + + for idx, header := range rangeHeaders { + ranges := strings.Split(header, "-") + rv := rangeValue{from: -1, to: total} + + // e.g. Range: -5 + if len(ranges) == 2 && ranges[0] == "" { + ranges[0] = "-" + ranges[1] + from, _ := strconv.ParseInt(ranges[0], 10, 64) + rv.from = total + from + + values[idx] = rv + + continue + } + + rv.from, _ = strconv.ParseInt(ranges[0], 10, 64) + + if ranges[1] != "" { + rv.to, _ = strconv.ParseInt(ranges[1], 10, 64) + rv.to++ + } + + values[idx] = rv + } + + return values, crv, total + 1 +} + // Send delays the response to handle Cache-Status func (r *CustomWriter) Send() (int, error) { - defer r.Buf.Reset() - fmt.Println("Upstream Send", r.Buf.Len()) + defer r.handleBuffer(func(b *bytes.Buffer) { + b.Reset() + }) storedLength := r.Header().Get(rfc.StoredLengthHeader) if storedLength != "" { r.Header().Set("Content-Length", storedLength) } - b := r.Buf.Bytes() - if len(b) != 0 { - r.Header().Set("Content-Length", strconv.Itoa(len(b))) + + result := r.Buf.Bytes() + + result = esi.Parse(result, r.Req) + + if r.Headers.Get("Range") != "" { + + var bufStr string + mimeType := r.Header().Get("Content-Type") + + r.WriteHeader(http.StatusPartialContent) + + rangeHeader, contentRangeValue, total := parseRange( + strings.Split(strings.TrimPrefix(r.Headers.Get("Range"), "bytes="), ", "), + r.Header().Get("Content-Range"), + ) + bodyBytes := r.Buf.Bytes() + bufLen := int64(r.Buf.Len()) + if total > 0 { + bufLen = total + } + + if len(rangeHeader) == 1 { + header := rangeHeader[0] + internalFrom := (header.from - contentRangeValue.from) % bufLen + internalTo := (header.to - contentRangeValue.from) % bufLen + + content := bodyBytes[internalFrom:] + + r.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", contentRangeValue.from, contentRangeValue.to, bufLen)) + + if internalTo >= 0 { + content = content[:internalTo-internalFrom] + r.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", header.from, header.to, bufLen)) + } + + result = content + } + + if len(rangeHeader) > 1 { + r.Header().Set("Content-Type", "multipart/byteranges; boundary="+separator) + + for _, header := range rangeHeader { + + content := bodyBytes[header.from:] + if header.to >= 0 { + content = content[:header.to-header.from] + } + + bufStr += fmt.Sprintf(` +%s +Content-Type: %s +Content-Range: bytes %d-%d/%d + +%s +`, separator, mimeType, header.from, header.to, r.Buf.Len(), content) + } + + result = []byte(bufStr + separator + "--") + } } + + if len(result) != 0 { + r.Header().Set("Content-Length", strconv.Itoa(len(result))) + } + r.Header().Del(rfc.StoredLengthHeader) r.Header().Del(rfc.StoredTTLHeader) @@ -105,5 +223,5 @@ func (r *CustomWriter) Send() (int, error) { r.headersSent = true } - return r.Rw.Write(b) + return r.Rw.Write(result) } diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/rfc/revalidation.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/rfc/revalidation.go index ccb6e73be..c2d63e4aa 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/rfc/revalidation.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/rfc/revalidation.go @@ -1,66 +1,31 @@ package rfc import ( - "bufio" - "bytes" - "encoding/json" "net/http" "strings" "time" - "github.com/darkweak/souin/pkg/storage/types" + "github.com/darkweak/storages/core" ) -func ValidateETagFromHeader(etag string, validator *types.Revalidator) { - validator.ResponseETag = etag - validator.NeedRevalidation = validator.NeedRevalidation || validator.ResponseETag != "" - validator.Matched = validator.ResponseETag == "" || (validator.ResponseETag != "" && len(validator.RequestETags) == 0) - - if len(validator.RequestETags) == 0 { - validator.NotModified = false - return - } - - // If-None-Match - if validator.IfNoneMatchPresent { - for _, ifNoneMatch := range validator.IfNoneMatch { - // Asrterisk special char to match any of ETag - if ifNoneMatch == "*" { - validator.Matched = true - return - } - if ifNoneMatch == validator.ResponseETag { - validator.Matched = true - return - } - } - - validator.Matched = false - return - } - - // If-Match - if validator.IfMatchPresent { - validator.Matched = false - if validator.ResponseETag == "" { - return - } - - for _, ifMatch := range validator.IfMatch { - // Asrterisk special char to match any of ETag - if ifMatch == "*" { - validator.Matched = true - return - } - if ifMatch == validator.ResponseETag { - validator.Matched = true - return - } - } - } +type Revalidator struct { + Matched bool + IfNoneMatchPresent bool + IfMatchPresent bool + IfModifiedSincePresent bool + IfUnmodifiedSincePresent bool + IfUnmotModifiedSincePresent bool + NeedRevalidation bool + NotModified bool + IfModifiedSince time.Time + IfUnmodifiedSince time.Time + IfNoneMatch []string + IfMatch []string + RequestETags []string + ResponseETag string } -func ParseRequest(req *http.Request) *types.Revalidator { +func ParseRequest(req *http.Request) *core.Revalidator { var rqEtags []string if len(req.Header.Get("If-None-Match")) > 0 { rqEtags = strings.Split(req.Header.Get("If-None-Match"), ",") @@ -68,7 +33,7 @@ func ParseRequest(req *http.Request) *types.Revalidator { for i, tag := range rqEtags { rqEtags[i] = strings.Trim(tag, " ") } - validator := types.Revalidator{ + validator := core.Revalidator{ NotModified: len(rqEtags) > 0, RequestETags: rqEtags, } @@ -94,116 +59,3 @@ func ParseRequest(req *http.Request) *types.Revalidator { return &validator } - -func DecodeMapping(item []byte) (*StorageMapper, error) { - mapping := &StorageMapper{} - e := json.Unmarshal(item, mapping) - - return mapping, e -} - -func MappingElection(provider types.Storer, item []byte, req *http.Request, validator *types.Revalidator) (resultFresh *http.Response, resultStale *http.Response, e error) { - mapping := &StorageMapper{} - - if len(item) != 0 { - mapping, e = DecodeMapping(item) - if e != nil { - return resultFresh, resultStale, e - } - } - - for keyName, keyItem := range mapping.Mapping { - valid := true - - for hname, hval := range keyItem.VariedHeaders { - if req.Header.Get(hname) != strings.Join(hval, ", ") { - valid = false - - break - } - } - - if !valid { - continue - } - - ValidateETagFromHeader(keyItem.Etag, validator) - - if validator.Matched { - // If the key is fresh enough. - if time.Since(keyItem.FreshTime) < 0 { - response := provider.Get(keyName) - if response != nil { - if resultFresh, e = http.ReadResponse(bufio.NewReader(bytes.NewBuffer(response)), req); e != nil { - return resultFresh, resultStale, e - } - - return resultFresh, resultStale, e - } - } - - // If the key is still stale. - if time.Since(keyItem.StaleTime) < 0 { - response := provider.Get(keyName) - if response != nil { - if resultStale, e = http.ReadResponse(bufio.NewReader(bytes.NewBuffer(response)), req); e != nil { - return resultFresh, resultStale, e - } - } - } - } - } - - return resultFresh, resultStale, e -} - -type KeyIndex struct { - StoredAt time.Time `json:"stored_at,omitempty"` - FreshTime time.Time `json:"fresh_time,omitempty"` - StaleTime time.Time `json:"stale_time,omitempty"` - VariedHeaders map[string][]string `json:"varied_headers,omitempty"` - Etag string `json:"etag,omitempty"` - RealKey string `json:"real_key,omitempty"` -} -type StorageMapper struct { - Mapping map[string]*KeyIndex `json:"mapping,omitempty"` -} - -func MappingUpdater(key string, item []byte, now, freshTime, staleTime time.Time, variedHeaders http.Header, etag, realKey string) (val []byte, e error) { - mapping := &StorageMapper{} - if len(item) != 0 { - e = json.Unmarshal(item, mapping) - if e != nil { - return nil, e - } - } - - if mapping.Mapping == nil { - mapping.Mapping = make(map[string]*KeyIndex) - } - - var pbvariedeheader map[string][]string - if variedHeaders != nil { - pbvariedeheader = make(map[string][]string) - } - - for k, v := range variedHeaders { - pbvariedeheader[k] = append(pbvariedeheader[k], v...) - } - - mapping.Mapping[key] = &KeyIndex{ - StoredAt: now, - FreshTime: freshTime, - StaleTime: staleTime, - VariedHeaders: pbvariedeheader, - Etag: etag, - RealKey: realKey, - } - - val, e = json.Marshal(mapping) - if e != nil { - return nil, e - } - - return val, e -} diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/rfc/vary.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/rfc/vary.go index bc958f40d..d1c0e157e 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/rfc/vary.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/rfc/vary.go @@ -6,6 +6,8 @@ import ( "net/url" "slices" "strings" + + "github.com/darkweak/storages/core" ) const ( @@ -15,10 +17,14 @@ const ( // GetVariedCacheKey returns the varied cache key for req and resp. func GetVariedCacheKey(rq *http.Request, headers []string) string { - if len(headers) == 0 { + isVaryDisabled := rq.Context().Value(core.DISABLE_VARY_CTX) + if isVaryDisabled != nil && isVaryDisabled.(bool) { return "" } + if len(headers) == 0 { + return "" + } for i, v := range headers { h := strings.TrimSpace(rq.Header.Get(v)) if strings.Contains(h, ";") || strings.Contains(h, ":") { diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/abstractProvider.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/abstractProvider.go deleted file mode 100644 index 577d5fade..000000000 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/abstractProvider.go +++ /dev/null @@ -1,57 +0,0 @@ -package storage - -import ( - "net/http" - "net/url" - "strings" - - "github.com/darkweak/souin/configurationtypes" - "github.com/darkweak/souin/pkg/storage/types" -) - -const ( - VarySeparator = "{-VARY-}" - DecodedHeaderSeparator = ";" - encodedHeaderSemiColonSeparator = "%3B" - encodedHeaderColonSeparator = "%3A" - StalePrefix = "STALE_" -) - -type StorerInstanciator func(configurationtypes.AbstractConfigurationInterface) (types.Storer, error) - -func NewStorages(configuration configurationtypes.AbstractConfigurationInterface) ([]types.Storer, error) { - s, err := Factory(configuration) - return []types.Storer{s}, err -} - -func varyVoter(baseKey string, req *http.Request, currentKey string) bool { - if currentKey == baseKey { - return true - } - - if strings.Contains(currentKey, VarySeparator) && strings.HasPrefix(currentKey, baseKey+VarySeparator) { - list := currentKey[(strings.LastIndex(currentKey, VarySeparator) + len(VarySeparator)):] - if len(list) == 0 { - return false - } - - for _, item := range strings.Split(list, ";") { - index := strings.LastIndex(item, ":") - if len(item) < index+1 { - return false - } - - hVal := item[index+1:] - if strings.Contains(hVal, encodedHeaderSemiColonSeparator) || strings.Contains(hVal, encodedHeaderColonSeparator) { - hVal, _ = url.QueryUnescape(hVal) - } - if req.Header.Get(item[:index]) != hVal { - return false - } - } - - return true - } - - return false -} diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/cacheProvider.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/cacheProvider.go deleted file mode 100644 index f0ff8847e..000000000 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/cacheProvider.go +++ /dev/null @@ -1,178 +0,0 @@ -package storage - -import ( - "bufio" - "bytes" - "net/http" - "regexp" - "strings" - "time" - - "github.com/akyoto/cache" - t "github.com/darkweak/souin/configurationtypes" - "github.com/darkweak/souin/pkg/rfc" - "github.com/darkweak/souin/pkg/storage/types" -) - -// Cache provider type -type Cache struct { - *cache.Cache - stale time.Duration -} - -var sharedCache *Cache - -// Factory function create new Cache instance -func Factory(c t.AbstractConfigurationInterface) (types.Storer, error) { - provider := cache.New(1 * time.Second) - - if sharedCache == nil { - sharedCache = &Cache{Cache: provider, stale: c.GetDefaultCache().GetStale()} - } - - return sharedCache, nil -} - -// Name returns the storer name -func (provider *Cache) Name() string { - return "CACHE" -} - -// Uuid returns an unique identifier -func (provider *Cache) Uuid() string { - return "" -} - -// ListKeys method returns the list of existing keys -func (provider *Cache) ListKeys() []string { - var keys []string - provider.Range(func(key, _ interface{}) bool { - keys = append(keys, key.(string)) - return true - }) - - return keys -} - -// MapKeys method returns the map of existing keys -func (provider *Cache) MapKeys(prefix string) map[string]string { - keys := map[string]string{} - provider.Range(func(key, value interface{}) bool { - if strings.HasPrefix(key.(string), prefix) { - k, _ := strings.CutPrefix(key.(string), prefix) - keys[k] = string(value.([]byte)) - } - return true - }) - - return keys -} - -// Get method returns the populated response if exists, empty response then -func (provider *Cache) Get(key string) []byte { - result, found := provider.Cache.Get(key) - - if !found { - return []byte{} - } - - return result.([]byte) -} - -// GetMultiLevel tries to load the key and check if one of linked keys is a fresh/stale candidate. -func (provider *Cache) GetMultiLevel(key string, req *http.Request, validator *types.Revalidator) (fresh *http.Response, stale *http.Response) { - result, found := provider.Cache.Get("IDX_" + key) - if !found { - return - } - - fresh, stale, _ = rfc.MappingElection(provider, result.([]byte), req, validator) - - return -} - -// SetMultiLevel tries to store the key with the given value and update the mapping key to store metadata. -func (provider *Cache) SetMultiLevel(baseKey, variedKey string, value []byte, variedHeaders http.Header, etag string, duration time.Duration, realKey string) error { - now := time.Now() - - var e error - - provider.Cache.Set(variedKey, value, duration) - - mappingKey := "IDX_" + baseKey - item, ok := provider.Cache.Get(mappingKey) - var val []byte - if ok { - val = item.([]byte) - } - - val, e = rfc.MappingUpdater(variedKey, val, now, now.Add(duration), now.Add(duration+provider.stale), variedHeaders, etag, realKey) - if e != nil { - return e - } - - provider.Cache.Set(mappingKey, val, 0) - return nil -} - -// Prefix method returns the populated response if exists, empty response then -func (provider *Cache) Prefix(key string, req *http.Request, validator *types.Revalidator) *http.Response { - var result *http.Response - - provider.Range(func(k, v interface{}) bool { - if !strings.HasPrefix(k.(string), key) { - return true - } - - if k == key || varyVoter(key, req, k.(string)) { - if res, err := http.ReadResponse(bufio.NewReader(bytes.NewBuffer(v.([]byte))), req); err == nil { - rfc.ValidateETagFromHeader(res.Header.Get("etag"), validator) - if validator.Matched { - result = res - return false - } - } - return true - } - - return true - }) - - return result -} - -// Set method will store the response in Cache provider -func (provider *Cache) Set(key string, value []byte, duration time.Duration) error { - provider.Cache.Set(key, value, duration) - - return nil -} - -// Delete method will delete the response in Cache provider if exists corresponding to key param -func (provider *Cache) Delete(key string) { - provider.Cache.Delete(key) -} - -// DeleteMany method will delete the responses in Cache provider if exists corresponding to the regex key param -func (provider *Cache) DeleteMany(key string) { - re, _ := regexp.Compile(key) - - provider.Range(func(current, _ any) bool { - if (re != nil && re.MatchString(current.(string))) || strings.HasPrefix(current.(string), key) { - provider.Delete(current.(string)) - } - return true - }) -} - -// Init method will -func (provider *Cache) Init() error { - return nil -} - -// Reset method will reset or close provider -func (provider *Cache) Reset() error { - provider.DeleteMany("*") - - return nil -} diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/defaultProvider.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/defaultProvider.go new file mode 100644 index 000000000..c6abe23cc --- /dev/null +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/defaultProvider.go @@ -0,0 +1,213 @@ +package storage + +import ( + "bytes" + "net/http" + "regexp" + "strings" + "sync" + "time" + + "github.com/darkweak/souin/configurationtypes" + "github.com/darkweak/souin/pkg/storage/types" + "github.com/darkweak/storages/core" + "github.com/pierrec/lz4/v4" +) + +// Default provider type +type Default struct { + m *sync.Map + stale time.Duration + logger core.Logger + + mu sync.Mutex +} + +type item struct { + invalidAt time.Time + value []byte +} + +// Factory function create new Default instance +func Factory(c configurationtypes.AbstractConfigurationInterface) (types.Storer, error) { + return &Default{m: &sync.Map{}, logger: c.GetLogger(), stale: c.GetDefaultCache().GetStale()}, nil +} + +// Name returns the storer name +func (provider *Default) Name() string { + return types.DefaultStorageName +} + +// Uuid returns an unique identifier +func (provider *Default) Uuid() string { + return "" +} + +// MapKeys method returns a map with the key and value +func (provider *Default) MapKeys(prefix string) map[string]string { + provider.mu.Lock() + defer provider.mu.Unlock() + + now := time.Now() + keys := map[string]string{} + + provider.m.Range(func(key, value any) bool { + if strings.HasPrefix(key.(string), prefix) { + k, _ := strings.CutPrefix(key.(string), prefix) + if v, ok := value.(item); ok { + if v.invalidAt.After(now) { + keys[k] = string(v.value) + } + + return true + } + + if v, ok := value.(*core.StorageMapper); ok { + for _, v := range v.Mapping { + if v.StaleTime.AsTime().After(now) { + keys[v.RealKey] = string(provider.Get(v.RealKey)) + } + } + } + } + + return true + }) + + return keys +} + +// ListKeys method returns the list of existing keys +func (provider *Default) ListKeys() []string { + now := time.Now() + keys := []string{} + + provider.m.Range(func(key, value any) bool { + if strings.HasPrefix(key.(string), core.MappingKeyPrefix) { + mapping, err := core.DecodeMapping(value.([]byte)) + if err == nil { + for _, v := range mapping.Mapping { + if v.StaleTime.AsTime().After(now) { + keys = append(keys, v.RealKey) + } else { + provider.m.Delete(v.RealKey) + } + } + } + } + + return true + }) + + return keys +} + +// Get method returns the populated response if exists, empty response then +func (provider *Default) Get(key string) []byte { + result, ok := provider.m.Load(key) + if !ok || result == nil { + return nil + } + + res, ok := result.(item) + if !ok { + return nil + } + + if res.invalidAt.After(time.Now()) { + return res.value + } + + return nil +} + +// GetMultiLevel tries to load the key and check if one of linked keys is a fresh/stale candidate. +func (provider *Default) GetMultiLevel(key string, req *http.Request, validator *core.Revalidator) (fresh *http.Response, stale *http.Response) { + result, found := provider.m.Load(core.MappingKeyPrefix + key) + if !found { + return + } + + fresh, stale, _ = core.MappingElection(provider, result.([]byte), req, validator, provider.logger) + + return +} + +// SetMultiLevel tries to store the key with the given value and update the mapping key to store metadata. +func (provider *Default) SetMultiLevel(baseKey, variedKey string, value []byte, variedHeaders http.Header, etag string, duration time.Duration, realKey string) error { + now := time.Now() + + var e error + compressed := new(bytes.Buffer) + if _, e = lz4.NewWriter(compressed).ReadFrom(bytes.NewReader(value)); e != nil { + provider.logger.Errorf("Impossible to compress the key %s into Badger, %v", variedKey, e) + return e + } + + provider.m.Store(variedKey, item{ + invalidAt: now.Add(duration + provider.stale), + value: compressed.Bytes(), + }) + + mappingKey := core.MappingKeyPrefix + baseKey + item, ok := provider.m.Load(mappingKey) + var val []byte + if ok { + val = item.([]byte) + } + + val, e = core.MappingUpdater(variedKey, val, provider.logger, now, now.Add(duration), now.Add(duration+provider.stale), variedHeaders, etag, realKey) + if e != nil { + return e + } + + provider.logger.Debugf("Store the new mapping for the key %s in Default", variedKey) + provider.m.Store(mappingKey, val) + return nil +} + +// Set method will store the response in Badger provider +func (provider *Default) Set(key string, value []byte, duration time.Duration) error { + provider.m.Store(key, item{ + invalidAt: time.Now().Add(duration), + value: value, + }) + + return nil +} + +// Delete method will delete the response in Badger provider if exists corresponding to key param +func (provider *Default) Delete(key string) { + provider.m.Delete(key) +} + +// DeleteMany method will delete the responses in Badger provider if exists corresponding to the regex key param +func (provider *Default) DeleteMany(key string) { + re, e := regexp.Compile(key) + + if e != nil { + provider.logger.Infof("Failed to compile key %s, %v", key, e) + } + + provider.m.Range(func(current, _ any) bool { + if (re != nil && re.MatchString(current.(string))) || strings.HasPrefix(current.(string), key) { + provider.m.Delete(current) + } + + return true + }) +} + +// Init method will +func (provider *Default) Init() error { + return nil +} + +// Reset method will reset or close provider +func (provider *Default) Reset() error { + provider.mu.Lock() + provider.m = new(sync.Map) + provider.mu.Unlock() + + return nil +} diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/types/types.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/types/types.go index e41007745..e4c8603fc 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/types/types.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/storage/types/types.go @@ -3,26 +3,11 @@ package types import ( "net/http" "time" -) -type Revalidator struct { - Matched bool - IfNoneMatchPresent bool - IfMatchPresent bool - IfModifiedSincePresent bool - IfUnmodifiedSincePresent bool - IfUnmotModifiedSincePresent bool - NeedRevalidation bool - NotModified bool - IfModifiedSince time.Time - IfUnmodifiedSince time.Time - IfNoneMatch []string - IfMatch []string - RequestETags []string - ResponseETag string -} + "github.com/darkweak/storages/core" +) -const DefaultStorageName = "CACHE" +const DefaultStorageName = "DEFAULT" const OneYearDuration = 365 * 24 * time.Hour type Storer interface { @@ -38,6 +23,6 @@ type Storer interface { Reset() error // Multi level storer to handle fresh/stale at once - GetMultiLevel(key string, req *http.Request, validator *Revalidator) (fresh *http.Response, stale *http.Response) + GetMultiLevel(key string, req *http.Request, validator *core.Revalidator) (fresh *http.Response, stale *http.Response) SetMultiLevel(baseKey, variedKey string, value []byte, variedHeaders http.Header, etag string, duration time.Duration, realKey string) error } diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/surrogate/providers/common.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/surrogate/providers/common.go index 10895888c..802156920 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/surrogate/providers/common.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/surrogate/providers/common.go @@ -1,7 +1,6 @@ package providers import ( - "fmt" "net/http" "net/url" "regexp" @@ -10,8 +9,8 @@ import ( "time" "github.com/darkweak/souin/configurationtypes" - "github.com/darkweak/souin/pkg/storage" "github.com/darkweak/souin/pkg/storage/types" + "github.com/darkweak/storages/core" ) const ( @@ -28,16 +27,38 @@ const ( cacheTags = "Cache-Tags" cacheTag = "Cache-Tag" - stalePrefix = "STALE_" surrogatePrefix = "SURROGATE_" ) var storageToInfiniteTTLMap = map[string]time.Duration{ - "CACHE": 365 * 24 * time.Hour, + "BADGER": types.OneYearDuration, + "ETCD": types.OneYearDuration, + "NUTS": 0, + "OLRIC": types.OneYearDuration, + "OTTER": types.OneYearDuration, + "REDIS": -1, + "SIMPLEFS": 0, + types.DefaultStorageName: types.OneYearDuration, } func (s *baseStorage) ParseHeaders(value string) []string { - return regexp.MustCompile(s.parent.getHeaderSeparator()+" *").Split(value, -1) + res := strings.Split(value, s.parent.getHeaderSeparator()) + for i, v := range res { + res[i] = strings.TrimSpace(v) + } + + return res +} + +func getCandidateHeader(header http.Header, getCandidates func() []string) (string, string) { + candidates := getCandidates() + for _, candidate := range candidates { + if h := header.Get(candidate); h != "" { + return candidate, h + } + } + + return candidates[len(candidates)-1], "" } func isSafeHTTPMethod(method string) bool { @@ -59,8 +80,11 @@ func uniqueTag(values []string) []string { } if _, found := tmp[item]; !found { tmp[item] = true - i, _ := url.QueryUnescape(item) - list = append(list, i) + + if strings.Contains(item, "%") { + item, _ = url.QueryUnescape(item) + } + list = append(list, item) } } @@ -79,17 +103,35 @@ type baseStorage struct { keysRegexp map[string]keysRegexpInner dynamic bool keepStale bool + logger core.Logger mu sync.Mutex duration time.Duration } -func (s *baseStorage) init(config configurationtypes.AbstractConfigurationInterface, _ string) { - storers, err := storage.NewStorages(config) - if err != nil { - panic(fmt.Sprintf("Impossible to instanciate the storer for the surrogate-keys: %v", err)) - } +func (s *baseStorage) init(config configurationtypes.AbstractConfigurationInterface, defaultStorerName string) { + if configuration, ok := config.GetSurrogateKeys()["_configuration"]; ok { + storer := core.GetRegisteredStorer(configuration.Storer) + if storer == nil { + storer = core.GetRegisteredStorer(types.DefaultStorageName + "-") + if storer == nil { + config.GetLogger().Errorf("Impossible to retrieve the storers %s for the surrogate-keys from it's configuration", configuration.Storer) + } + } - s.Storage = storers[0] + s.Storage = storer + } else { + config.GetLogger().Debugf("Try to load the storer %s as surrogate backend", defaultStorerName) + storer := core.GetRegisteredStorer(defaultStorerName) + if storer == nil { + config.GetLogger().Errorf("Impossible to retrieve the storers %s for the surrogate-keys fallback to the default storage", configuration.Storer) + storer = core.GetRegisteredStorer(types.DefaultStorageName + "-") + if storer == nil { + config.GetLogger().Error("Impossible to retrieve the default storer") + } + } + + s.Storage = storer + } s.Keys = config.GetSurrogateKeys() s.keepStale = config.GetDefaultCache().GetCDN().Strategy != "hard" @@ -115,8 +157,8 @@ func (s *baseStorage) init(config configurationtypes.AbstractConfigurationInterf } s.dynamic = config.GetDefaultCache().GetCDN().Dynamic + s.logger = config.GetLogger() s.keysRegexp = keysRegexp - s.mu = sync.Mutex{} s.duration = storageToInfiniteTTLMap[s.Storage.Name()] } @@ -151,8 +193,8 @@ func (s *baseStorage) storeTag(tag string, cacheKey string) { s.mu.Lock() currentValue := string(s.Storage.Get(surrogatePrefix + tag)) if !containsCacheKey(currentValue, cacheKey) { - fmt.Printf("Store the tag %s", tag) - _ = s.Storage.Set(surrogatePrefix+tag, []byte(currentValue+souinStorageSeparator+cacheKey), -1) + s.logger.Debugf("Store the tag %s", tag) + _ = s.Storage.Set(surrogatePrefix+tag, []byte(currentValue+souinStorageSeparator+cacheKey), s.duration) } } @@ -162,6 +204,7 @@ func (*baseStorage) candidateStore(tag string) bool { func (*baseStorage) getOrderedSurrogateKeyHeadersCandidate() []string { return []string{ + cacheGroupKey, surrogateKey, edgeCacheTag, cacheTags, @@ -178,14 +221,7 @@ func (*baseStorage) getOrderedSurrogateControlHeadersCandidate() []string { } func (s *baseStorage) GetSurrogateControl(header http.Header) (string, string) { - parent := s.parent.getOrderedSurrogateControlHeadersCandidate() - for _, candidate := range parent { - if h := header.Get(candidate); h != "" { - return candidate, h - } - } - - return parent[len(parent)-1], "" + return getCandidateHeader(header, s.parent.getOrderedSurrogateControlHeadersCandidate) } func (s *baseStorage) GetSurrogateControlName() string { @@ -193,23 +229,15 @@ func (s *baseStorage) GetSurrogateControlName() string { } func (s *baseStorage) getSurrogateKey(header http.Header) string { - for _, candidate := range s.parent.getOrderedSurrogateKeyHeadersCandidate() { - if h := header.Get(candidate); h != "" { - return h - } - } - - return "" + _, v := getCandidateHeader(header, s.parent.getOrderedSurrogateKeyHeadersCandidate) + return v } func (s *baseStorage) purgeTag(tag string) []string { - toInvalidate := string(s.Storage.Get(tag)) - fmt.Printf("Purge the tag %s", tag) - s.Storage.Delete(surrogatePrefix + tag) + toInvalidate := string(s.Storage.Get(surrogatePrefix + tag)) + s.logger.Debugf("Purge the tag %s", tag) if !s.keepStale { - toInvalidate = toInvalidate + "," + string(s.Storage.Get(stalePrefix+tag)) - fmt.Printf("Purge the tag %s", stalePrefix+tag) - s.Storage.Delete(surrogatePrefix + stalePrefix + tag) + s.Storage.Delete(surrogatePrefix + tag) } return strings.Split(toInvalidate, souinStorageSeparator) } @@ -219,7 +247,6 @@ func (s *baseStorage) Store(response *http.Response, cacheKey, uri string) error h := response.Header cacheKey = url.QueryEscape(cacheKey) - staleKey := stalePrefix + cacheKey keys := s.ParseHeaders(s.parent.getSurrogateKey(h)) @@ -228,19 +255,21 @@ func (s *baseStorage) Store(response *http.Response, cacheKey, uri string) error if controls := s.ParseHeaders(v); len(controls) != 0 { if len(controls) == 1 && controls[0] == "" { s.storeTag(key, cacheKey) - s.storeTag(stalePrefix+key, staleKey) + s.storeTag(uri, cacheKey) continue } for _, control := range controls { if s.parent.candidateStore(control) { s.storeTag(key, cacheKey) - s.storeTag(stalePrefix+key, staleKey) + s.storeTag(uri, cacheKey) + + break } } } else { s.storeTag(key, cacheKey) - s.storeTag(stalePrefix+key, staleKey) + s.storeTag(uri, cacheKey) } } @@ -256,6 +285,8 @@ func (s *baseStorage) Purge(header http.Header) (cacheKeys []string, surrogateKe toInvalidate = append(toInvalidate, s.purgeTag(su)...) } + s.logger.Debugf("Purge the following tags: %+v", toInvalidate) + return uniqueTag(toInvalidate), surrogates } @@ -275,7 +306,5 @@ func (s *baseStorage) List() map[string]string { // Destruct method will shutdown properly the provider func (s *baseStorage) Destruct() error { - s.Storage.DeleteMany(surrogatePrefix + ".*") - - return nil + return s.Storage.Reset() } diff --git a/plugins/traefik/vendor/github.com/felixge/httpsnoop/.gitignore b/plugins/traefik/vendor/github.com/felixge/httpsnoop/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/plugins/traefik/vendor/github.com/felixge/httpsnoop/LICENSE.txt b/plugins/traefik/vendor/github.com/felixge/httpsnoop/LICENSE.txt new file mode 100644 index 000000000..e028b46a9 --- /dev/null +++ b/plugins/traefik/vendor/github.com/felixge/httpsnoop/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2016 Felix Geisendörfer (felix@debuggable.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/plugins/traefik/vendor/github.com/felixge/httpsnoop/Makefile b/plugins/traefik/vendor/github.com/felixge/httpsnoop/Makefile new file mode 100644 index 000000000..4e12afdd9 --- /dev/null +++ b/plugins/traefik/vendor/github.com/felixge/httpsnoop/Makefile @@ -0,0 +1,10 @@ +.PHONY: ci generate clean + +ci: clean generate + go test -race -v ./... + +generate: + go generate . + +clean: + rm -rf *_generated*.go diff --git a/plugins/traefik/vendor/github.com/felixge/httpsnoop/README.md b/plugins/traefik/vendor/github.com/felixge/httpsnoop/README.md new file mode 100644 index 000000000..cf6b42f3d --- /dev/null +++ b/plugins/traefik/vendor/github.com/felixge/httpsnoop/README.md @@ -0,0 +1,95 @@ +# httpsnoop + +Package httpsnoop provides an easy way to capture http related metrics (i.e. +response time, bytes written, and http status code) from your application's +http.Handlers. + +Doing this requires non-trivial wrapping of the http.ResponseWriter interface, +which is also exposed for users interested in a more low-level API. + +[![Go Reference](https://pkg.go.dev/badge/github.com/felixge/httpsnoop.svg)](https://pkg.go.dev/github.com/felixge/httpsnoop) +[![Build Status](https://github.com/felixge/httpsnoop/actions/workflows/main.yaml/badge.svg)](https://github.com/felixge/httpsnoop/actions/workflows/main.yaml) + +## Usage Example + +```go +// myH is your app's http handler, perhaps a http.ServeMux or similar. +var myH http.Handler +// wrappedH wraps myH in order to log every request. +wrappedH := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + m := httpsnoop.CaptureMetrics(myH, w, r) + log.Printf( + "%s %s (code=%d dt=%s written=%d)", + r.Method, + r.URL, + m.Code, + m.Duration, + m.Written, + ) +}) +http.ListenAndServe(":8080", wrappedH) +``` + +## Why this package exists + +Instrumenting an application's http.Handler is surprisingly difficult. + +However if you google for e.g. "capture ResponseWriter status code" you'll find +lots of advise and code examples that suggest it to be a fairly trivial +undertaking. Unfortunately everything I've seen so far has a high chance of +breaking your application. + +The main problem is that a `http.ResponseWriter` often implements additional +interfaces such as `http.Flusher`, `http.CloseNotifier`, `http.Hijacker`, `http.Pusher`, and +`io.ReaderFrom`. So the naive approach of just wrapping `http.ResponseWriter` +in your own struct that also implements the `http.ResponseWriter` interface +will hide the additional interfaces mentioned above. This has a high change of +introducing subtle bugs into any non-trivial application. + +Another approach I've seen people take is to return a struct that implements +all of the interfaces above. However, that's also problematic, because it's +difficult to fake some of these interfaces behaviors when the underlying +`http.ResponseWriter` doesn't have an implementation. It's also dangerous, +because an application may choose to operate differently, merely because it +detects the presence of these additional interfaces. + +This package solves this problem by checking which additional interfaces a +`http.ResponseWriter` implements, returning a wrapped version implementing the +exact same set of interfaces. + +Additionally this package properly handles edge cases such as `WriteHeader` not +being called, or called more than once, as well as concurrent calls to +`http.ResponseWriter` methods, and even calls happening after the wrapped +`ServeHTTP` has already returned. + +Unfortunately this package is not perfect either. It's possible that it is +still missing some interfaces provided by the go core (let me know if you find +one), and it won't work for applications adding their own interfaces into the +mix. You can however use `httpsnoop.Unwrap(w)` to access the underlying +`http.ResponseWriter` and type-assert the result to its other interfaces. + +However, hopefully the explanation above has sufficiently scared you of rolling +your own solution to this problem. httpsnoop may still break your application, +but at least it tries to avoid it as much as possible. + +Anyway, the real problem here is that smuggling additional interfaces inside +`http.ResponseWriter` is a problematic design choice, but it probably goes as +deep as the Go language specification itself. But that's okay, I still prefer +Go over the alternatives ;). + +## Performance + +``` +BenchmarkBaseline-8 20000 94912 ns/op +BenchmarkCaptureMetrics-8 20000 95461 ns/op +``` + +As you can see, using `CaptureMetrics` on a vanilla http.Handler introduces an +overhead of ~500 ns per http request on my machine. However, the margin of +error appears to be larger than that, therefor it should be reasonable to +assume that the overhead introduced by `CaptureMetrics` is absolutely +negligible. + +## License + +MIT diff --git a/plugins/traefik/vendor/github.com/felixge/httpsnoop/capture_metrics.go b/plugins/traefik/vendor/github.com/felixge/httpsnoop/capture_metrics.go new file mode 100644 index 000000000..bec7b71b3 --- /dev/null +++ b/plugins/traefik/vendor/github.com/felixge/httpsnoop/capture_metrics.go @@ -0,0 +1,86 @@ +package httpsnoop + +import ( + "io" + "net/http" + "time" +) + +// Metrics holds metrics captured from CaptureMetrics. +type Metrics struct { + // Code is the first http response code passed to the WriteHeader func of + // the ResponseWriter. If no such call is made, a default code of 200 is + // assumed instead. + Code int + // Duration is the time it took to execute the handler. + Duration time.Duration + // Written is the number of bytes successfully written by the Write or + // ReadFrom function of the ResponseWriter. ResponseWriters may also write + // data to their underlaying connection directly (e.g. headers), but those + // are not tracked. Therefor the number of Written bytes will usually match + // the size of the response body. + Written int64 +} + +// CaptureMetrics wraps the given hnd, executes it with the given w and r, and +// returns the metrics it captured from it. +func CaptureMetrics(hnd http.Handler, w http.ResponseWriter, r *http.Request) Metrics { + return CaptureMetricsFn(w, func(ww http.ResponseWriter) { + hnd.ServeHTTP(ww, r) + }) +} + +// CaptureMetricsFn wraps w and calls fn with the wrapped w and returns the +// resulting metrics. This is very similar to CaptureMetrics (which is just +// sugar on top of this func), but is a more usable interface if your +// application doesn't use the Go http.Handler interface. +func CaptureMetricsFn(w http.ResponseWriter, fn func(http.ResponseWriter)) Metrics { + m := Metrics{Code: http.StatusOK} + m.CaptureMetrics(w, fn) + return m +} + +// CaptureMetrics wraps w and calls fn with the wrapped w and updates +// Metrics m with the resulting metrics. This is similar to CaptureMetricsFn, +// but allows one to customize starting Metrics object. +func (m *Metrics) CaptureMetrics(w http.ResponseWriter, fn func(http.ResponseWriter)) { + var ( + start = time.Now() + headerWritten bool + hooks = Hooks{ + WriteHeader: func(next WriteHeaderFunc) WriteHeaderFunc { + return func(code int) { + next(code) + + if !(code >= 100 && code <= 199) && !headerWritten { + m.Code = code + headerWritten = true + } + } + }, + + Write: func(next WriteFunc) WriteFunc { + return func(p []byte) (int, error) { + n, err := next(p) + + m.Written += int64(n) + headerWritten = true + return n, err + } + }, + + ReadFrom: func(next ReadFromFunc) ReadFromFunc { + return func(src io.Reader) (int64, error) { + n, err := next(src) + + headerWritten = true + m.Written += n + return n, err + } + }, + } + ) + + fn(Wrap(w, hooks)) + m.Duration += time.Since(start) +} diff --git a/plugins/traefik/vendor/github.com/felixge/httpsnoop/docs.go b/plugins/traefik/vendor/github.com/felixge/httpsnoop/docs.go new file mode 100644 index 000000000..203c35b3c --- /dev/null +++ b/plugins/traefik/vendor/github.com/felixge/httpsnoop/docs.go @@ -0,0 +1,10 @@ +// Package httpsnoop provides an easy way to capture http related metrics (i.e. +// response time, bytes written, and http status code) from your application's +// http.Handlers. +// +// Doing this requires non-trivial wrapping of the http.ResponseWriter +// interface, which is also exposed for users interested in a more low-level +// API. +package httpsnoop + +//go:generate go run codegen/main.go diff --git a/plugins/traefik/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go b/plugins/traefik/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go new file mode 100644 index 000000000..101cedde6 --- /dev/null +++ b/plugins/traefik/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go @@ -0,0 +1,436 @@ +// +build go1.8 +// Code generated by "httpsnoop/codegen"; DO NOT EDIT. + +package httpsnoop + +import ( + "bufio" + "io" + "net" + "net/http" +) + +// HeaderFunc is part of the http.ResponseWriter interface. +type HeaderFunc func() http.Header + +// WriteHeaderFunc is part of the http.ResponseWriter interface. +type WriteHeaderFunc func(code int) + +// WriteFunc is part of the http.ResponseWriter interface. +type WriteFunc func(b []byte) (int, error) + +// FlushFunc is part of the http.Flusher interface. +type FlushFunc func() + +// CloseNotifyFunc is part of the http.CloseNotifier interface. +type CloseNotifyFunc func() <-chan bool + +// HijackFunc is part of the http.Hijacker interface. +type HijackFunc func() (net.Conn, *bufio.ReadWriter, error) + +// ReadFromFunc is part of the io.ReaderFrom interface. +type ReadFromFunc func(src io.Reader) (int64, error) + +// PushFunc is part of the http.Pusher interface. +type PushFunc func(target string, opts *http.PushOptions) error + +// Hooks defines a set of method interceptors for methods included in +// http.ResponseWriter as well as some others. You can think of them as +// middleware for the function calls they target. See Wrap for more details. +type Hooks struct { + Header func(HeaderFunc) HeaderFunc + WriteHeader func(WriteHeaderFunc) WriteHeaderFunc + Write func(WriteFunc) WriteFunc + Flush func(FlushFunc) FlushFunc + CloseNotify func(CloseNotifyFunc) CloseNotifyFunc + Hijack func(HijackFunc) HijackFunc + ReadFrom func(ReadFromFunc) ReadFromFunc + Push func(PushFunc) PushFunc +} + +// Wrap returns a wrapped version of w that provides the exact same interface +// as w. Specifically if w implements any combination of: +// +// - http.Flusher +// - http.CloseNotifier +// - http.Hijacker +// - io.ReaderFrom +// - http.Pusher +// +// The wrapped version will implement the exact same combination. If no hooks +// are set, the wrapped version also behaves exactly as w. Hooks targeting +// methods not supported by w are ignored. Any other hooks will intercept the +// method they target and may modify the call's arguments and/or return values. +// The CaptureMetrics implementation serves as a working example for how the +// hooks can be used. +func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { + rw := &rw{w: w, h: hooks} + _, i0 := w.(http.Flusher) + _, i1 := w.(http.CloseNotifier) + _, i2 := w.(http.Hijacker) + _, i3 := w.(io.ReaderFrom) + _, i4 := w.(http.Pusher) + switch { + // combination 1/32 + case !i0 && !i1 && !i2 && !i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + }{rw, rw} + // combination 2/32 + case !i0 && !i1 && !i2 && !i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.Pusher + }{rw, rw, rw} + // combination 3/32 + case !i0 && !i1 && !i2 && i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + io.ReaderFrom + }{rw, rw, rw} + // combination 4/32 + case !i0 && !i1 && !i2 && i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw} + // combination 5/32 + case !i0 && !i1 && i2 && !i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.Hijacker + }{rw, rw, rw} + // combination 6/32 + case !i0 && !i1 && i2 && !i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.Hijacker + http.Pusher + }{rw, rw, rw, rw} + // combination 7/32 + case !i0 && !i1 && i2 && i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw} + // combination 8/32 + case !i0 && !i1 && i2 && i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.Hijacker + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw, rw} + // combination 9/32 + case !i0 && i1 && !i2 && !i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.CloseNotifier + }{rw, rw, rw} + // combination 10/32 + case !i0 && i1 && !i2 && !i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.CloseNotifier + http.Pusher + }{rw, rw, rw, rw} + // combination 11/32 + case !i0 && i1 && !i2 && i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.CloseNotifier + io.ReaderFrom + }{rw, rw, rw, rw} + // combination 12/32 + case !i0 && i1 && !i2 && i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.CloseNotifier + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw, rw} + // combination 13/32 + case !i0 && i1 && i2 && !i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.CloseNotifier + http.Hijacker + }{rw, rw, rw, rw} + // combination 14/32 + case !i0 && i1 && i2 && !i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.CloseNotifier + http.Hijacker + http.Pusher + }{rw, rw, rw, rw, rw} + // combination 15/32 + case !i0 && i1 && i2 && i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.CloseNotifier + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw, rw} + // combination 16/32 + case !i0 && i1 && i2 && i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.CloseNotifier + http.Hijacker + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw, rw, rw} + // combination 17/32 + case i0 && !i1 && !i2 && !i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + }{rw, rw, rw} + // combination 18/32 + case i0 && !i1 && !i2 && !i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.Pusher + }{rw, rw, rw, rw} + // combination 19/32 + case i0 && !i1 && !i2 && i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + io.ReaderFrom + }{rw, rw, rw, rw} + // combination 20/32 + case i0 && !i1 && !i2 && i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw, rw} + // combination 21/32 + case i0 && !i1 && i2 && !i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.Hijacker + }{rw, rw, rw, rw} + // combination 22/32 + case i0 && !i1 && i2 && !i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.Hijacker + http.Pusher + }{rw, rw, rw, rw, rw} + // combination 23/32 + case i0 && !i1 && i2 && i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw, rw} + // combination 24/32 + case i0 && !i1 && i2 && i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.Hijacker + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw, rw, rw} + // combination 25/32 + case i0 && i1 && !i2 && !i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.CloseNotifier + }{rw, rw, rw, rw} + // combination 26/32 + case i0 && i1 && !i2 && !i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Pusher + }{rw, rw, rw, rw, rw} + // combination 27/32 + case i0 && i1 && !i2 && i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.CloseNotifier + io.ReaderFrom + }{rw, rw, rw, rw, rw} + // combination 28/32 + case i0 && i1 && !i2 && i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.CloseNotifier + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw, rw, rw} + // combination 29/32 + case i0 && i1 && i2 && !i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Hijacker + }{rw, rw, rw, rw, rw} + // combination 30/32 + case i0 && i1 && i2 && !i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Hijacker + http.Pusher + }{rw, rw, rw, rw, rw, rw} + // combination 31/32 + case i0 && i1 && i2 && i3 && !i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw, rw, rw} + // combination 32/32 + case i0 && i1 && i2 && i3 && i4: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Hijacker + io.ReaderFrom + http.Pusher + }{rw, rw, rw, rw, rw, rw, rw} + } + panic("unreachable") +} + +type rw struct { + w http.ResponseWriter + h Hooks +} + +func (w *rw) Unwrap() http.ResponseWriter { + return w.w +} + +func (w *rw) Header() http.Header { + f := w.w.(http.ResponseWriter).Header + if w.h.Header != nil { + f = w.h.Header(f) + } + return f() +} + +func (w *rw) WriteHeader(code int) { + f := w.w.(http.ResponseWriter).WriteHeader + if w.h.WriteHeader != nil { + f = w.h.WriteHeader(f) + } + f(code) +} + +func (w *rw) Write(b []byte) (int, error) { + f := w.w.(http.ResponseWriter).Write + if w.h.Write != nil { + f = w.h.Write(f) + } + return f(b) +} + +func (w *rw) Flush() { + f := w.w.(http.Flusher).Flush + if w.h.Flush != nil { + f = w.h.Flush(f) + } + f() +} + +func (w *rw) CloseNotify() <-chan bool { + f := w.w.(http.CloseNotifier).CloseNotify + if w.h.CloseNotify != nil { + f = w.h.CloseNotify(f) + } + return f() +} + +func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) { + f := w.w.(http.Hijacker).Hijack + if w.h.Hijack != nil { + f = w.h.Hijack(f) + } + return f() +} + +func (w *rw) ReadFrom(src io.Reader) (int64, error) { + f := w.w.(io.ReaderFrom).ReadFrom + if w.h.ReadFrom != nil { + f = w.h.ReadFrom(f) + } + return f(src) +} + +func (w *rw) Push(target string, opts *http.PushOptions) error { + f := w.w.(http.Pusher).Push + if w.h.Push != nil { + f = w.h.Push(f) + } + return f(target, opts) +} + +type Unwrapper interface { + Unwrap() http.ResponseWriter +} + +// Unwrap returns the underlying http.ResponseWriter from within zero or more +// layers of httpsnoop wrappers. +func Unwrap(w http.ResponseWriter) http.ResponseWriter { + if rw, ok := w.(Unwrapper); ok { + // recurse until rw.Unwrap() returns a non-Unwrapper + return Unwrap(rw.Unwrap()) + } else { + return w + } +} diff --git a/plugins/traefik/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go b/plugins/traefik/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go new file mode 100644 index 000000000..e0951df15 --- /dev/null +++ b/plugins/traefik/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go @@ -0,0 +1,278 @@ +// +build !go1.8 +// Code generated by "httpsnoop/codegen"; DO NOT EDIT. + +package httpsnoop + +import ( + "bufio" + "io" + "net" + "net/http" +) + +// HeaderFunc is part of the http.ResponseWriter interface. +type HeaderFunc func() http.Header + +// WriteHeaderFunc is part of the http.ResponseWriter interface. +type WriteHeaderFunc func(code int) + +// WriteFunc is part of the http.ResponseWriter interface. +type WriteFunc func(b []byte) (int, error) + +// FlushFunc is part of the http.Flusher interface. +type FlushFunc func() + +// CloseNotifyFunc is part of the http.CloseNotifier interface. +type CloseNotifyFunc func() <-chan bool + +// HijackFunc is part of the http.Hijacker interface. +type HijackFunc func() (net.Conn, *bufio.ReadWriter, error) + +// ReadFromFunc is part of the io.ReaderFrom interface. +type ReadFromFunc func(src io.Reader) (int64, error) + +// Hooks defines a set of method interceptors for methods included in +// http.ResponseWriter as well as some others. You can think of them as +// middleware for the function calls they target. See Wrap for more details. +type Hooks struct { + Header func(HeaderFunc) HeaderFunc + WriteHeader func(WriteHeaderFunc) WriteHeaderFunc + Write func(WriteFunc) WriteFunc + Flush func(FlushFunc) FlushFunc + CloseNotify func(CloseNotifyFunc) CloseNotifyFunc + Hijack func(HijackFunc) HijackFunc + ReadFrom func(ReadFromFunc) ReadFromFunc +} + +// Wrap returns a wrapped version of w that provides the exact same interface +// as w. Specifically if w implements any combination of: +// +// - http.Flusher +// - http.CloseNotifier +// - http.Hijacker +// - io.ReaderFrom +// +// The wrapped version will implement the exact same combination. If no hooks +// are set, the wrapped version also behaves exactly as w. Hooks targeting +// methods not supported by w are ignored. Any other hooks will intercept the +// method they target and may modify the call's arguments and/or return values. +// The CaptureMetrics implementation serves as a working example for how the +// hooks can be used. +func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { + rw := &rw{w: w, h: hooks} + _, i0 := w.(http.Flusher) + _, i1 := w.(http.CloseNotifier) + _, i2 := w.(http.Hijacker) + _, i3 := w.(io.ReaderFrom) + switch { + // combination 1/16 + case !i0 && !i1 && !i2 && !i3: + return struct { + Unwrapper + http.ResponseWriter + }{rw, rw} + // combination 2/16 + case !i0 && !i1 && !i2 && i3: + return struct { + Unwrapper + http.ResponseWriter + io.ReaderFrom + }{rw, rw, rw} + // combination 3/16 + case !i0 && !i1 && i2 && !i3: + return struct { + Unwrapper + http.ResponseWriter + http.Hijacker + }{rw, rw, rw} + // combination 4/16 + case !i0 && !i1 && i2 && i3: + return struct { + Unwrapper + http.ResponseWriter + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw} + // combination 5/16 + case !i0 && i1 && !i2 && !i3: + return struct { + Unwrapper + http.ResponseWriter + http.CloseNotifier + }{rw, rw, rw} + // combination 6/16 + case !i0 && i1 && !i2 && i3: + return struct { + Unwrapper + http.ResponseWriter + http.CloseNotifier + io.ReaderFrom + }{rw, rw, rw, rw} + // combination 7/16 + case !i0 && i1 && i2 && !i3: + return struct { + Unwrapper + http.ResponseWriter + http.CloseNotifier + http.Hijacker + }{rw, rw, rw, rw} + // combination 8/16 + case !i0 && i1 && i2 && i3: + return struct { + Unwrapper + http.ResponseWriter + http.CloseNotifier + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw, rw} + // combination 9/16 + case i0 && !i1 && !i2 && !i3: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + }{rw, rw, rw} + // combination 10/16 + case i0 && !i1 && !i2 && i3: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + io.ReaderFrom + }{rw, rw, rw, rw} + // combination 11/16 + case i0 && !i1 && i2 && !i3: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.Hijacker + }{rw, rw, rw, rw} + // combination 12/16 + case i0 && !i1 && i2 && i3: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw, rw} + // combination 13/16 + case i0 && i1 && !i2 && !i3: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.CloseNotifier + }{rw, rw, rw, rw} + // combination 14/16 + case i0 && i1 && !i2 && i3: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.CloseNotifier + io.ReaderFrom + }{rw, rw, rw, rw, rw} + // combination 15/16 + case i0 && i1 && i2 && !i3: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Hijacker + }{rw, rw, rw, rw, rw} + // combination 16/16 + case i0 && i1 && i2 && i3: + return struct { + Unwrapper + http.ResponseWriter + http.Flusher + http.CloseNotifier + http.Hijacker + io.ReaderFrom + }{rw, rw, rw, rw, rw, rw} + } + panic("unreachable") +} + +type rw struct { + w http.ResponseWriter + h Hooks +} + +func (w *rw) Unwrap() http.ResponseWriter { + return w.w +} + +func (w *rw) Header() http.Header { + f := w.w.(http.ResponseWriter).Header + if w.h.Header != nil { + f = w.h.Header(f) + } + return f() +} + +func (w *rw) WriteHeader(code int) { + f := w.w.(http.ResponseWriter).WriteHeader + if w.h.WriteHeader != nil { + f = w.h.WriteHeader(f) + } + f(code) +} + +func (w *rw) Write(b []byte) (int, error) { + f := w.w.(http.ResponseWriter).Write + if w.h.Write != nil { + f = w.h.Write(f) + } + return f(b) +} + +func (w *rw) Flush() { + f := w.w.(http.Flusher).Flush + if w.h.Flush != nil { + f = w.h.Flush(f) + } + f() +} + +func (w *rw) CloseNotify() <-chan bool { + f := w.w.(http.CloseNotifier).CloseNotify + if w.h.CloseNotify != nil { + f = w.h.CloseNotify(f) + } + return f() +} + +func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) { + f := w.w.(http.Hijacker).Hijack + if w.h.Hijack != nil { + f = w.h.Hijack(f) + } + return f() +} + +func (w *rw) ReadFrom(src io.Reader) (int64, error) { + f := w.w.(io.ReaderFrom).ReadFrom + if w.h.ReadFrom != nil { + f = w.h.ReadFrom(f) + } + return f(src) +} + +type Unwrapper interface { + Unwrap() http.ResponseWriter +} + +// Unwrap returns the underlying http.ResponseWriter from within zero or more +// layers of httpsnoop wrappers. +func Unwrap(w http.ResponseWriter) http.ResponseWriter { + if rw, ok := w.(Unwrapper); ok { + // recurse until rw.Unwrap() returns a non-Unwrapper + return Unwrap(rw.Unwrap()) + } else { + return w + } +} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/.gitignore b/plugins/traefik/vendor/github.com/francoispqt/gojay/.gitignore deleted file mode 100644 index 43ebdc4b9..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -vendor -*.out -*.log -*.test -.vscode diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/.travis.yml b/plugins/traefik/vendor/github.com/francoispqt/gojay/.travis.yml deleted file mode 100644 index df04aa240..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go - -go: - - "1.10.x" - - "1.11.x" - - "1.12.x" - -script: - - go get github.com/golang/dep/cmd/dep github.com/stretchr/testify - - dep ensure -v -vendor-only - - go test ./gojay/codegen/test/... -race - - go test -race -coverprofile=coverage.txt -covermode=atomic - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/Gopkg.lock b/plugins/traefik/vendor/github.com/francoispqt/gojay/Gopkg.lock deleted file mode 100644 index d642e9a75..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/Gopkg.lock +++ /dev/null @@ -1,163 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - digest = "1:1a37f9f2ae10d161d9688fb6008ffa14e1631e5068cc3e9698008b9e8d40d575" - name = "cloud.google.com/go" - packages = ["compute/metadata"] - pruneopts = "" - revision = "457ea5c15ccf3b87db582c450e80101989da35f7" - version = "v0.40.0" - -[[projects]] - digest = "1:968d8903d598e3fae738325d3410f33f07ea6a2b9ee5591e9c262ee37df6845a" - name = "github.com/go-errors/errors" - packages = ["."] - pruneopts = "" - revision = "a6af135bd4e28680facf08a3d206b454abc877a4" - version = "v1.0.1" - -[[projects]] - digest = "1:529d738b7976c3848cae5cf3a8036440166835e389c1f617af701eeb12a0518d" - name = "github.com/golang/protobuf" - packages = ["proto"] - pruneopts = "" - revision = "b5d812f8a3706043e23a9cd5babf2e5423744d30" - version = "v1.3.1" - -[[projects]] - branch = "master" - digest = "1:cae59d7b8243c671c9f544965522ba35c0fec48ee80adb9f1400cd2f33abbbec" - name = "github.com/mailru/easyjson" - packages = [ - ".", - "buffer", - "jlexer", - "jwriter", - ] - pruneopts = "" - revision = "1ea4449da9834f4d333f1cc461c374aea217d249" - -[[projects]] - digest = "1:1d7e1867c49a6dd9856598ef7c3123604ea3daabf5b83f303ff457bcbc410b1d" - name = "github.com/pkg/errors" - packages = ["."] - pruneopts = "" - revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4" - version = "v0.8.1" - -[[projects]] - digest = "1:8d4bbd8ab012efc77ab6b97286f2aff262bcdeac9803bb57d75cf7d0a5e6a877" - name = "github.com/viant/assertly" - packages = ["."] - pruneopts = "" - revision = "04f45e0aeb6f3455884877b047a97bcc95dc9493" - version = "v0.4.8" - -[[projects]] - digest = "1:5913451bc2d274673c0716efe226a137625740cd9380641f4d8300ff4f2d82a0" - name = "github.com/viant/toolbox" - packages = [ - ".", - "cred", - "data", - "storage", - "url", - ] - pruneopts = "" - revision = "1be8e4d172138324f40d55ea61a2aeab0c5ce864" - version = "v0.24.0" - -[[projects]] - branch = "master" - digest = "1:9d150270ca2c3356f2224a0878daa1652e4d0b25b345f18b4f6e156cc4b8ec5e" - name = "golang.org/x/crypto" - packages = [ - "blowfish", - "curve25519", - "ed25519", - "ed25519/internal/edwards25519", - "internal/chacha20", - "internal/subtle", - "poly1305", - "ssh", - ] - pruneopts = "" - revision = "f99c8df09eb5bff426315721bfa5f16a99cad32c" - -[[projects]] - branch = "master" - digest = "1:5a56f211e7c12a65c5585c629457a2fb91d8719844ee8fab92727ea8adb5721c" - name = "golang.org/x/net" - packages = [ - "context", - "context/ctxhttp", - "websocket", - ] - pruneopts = "" - revision = "461777fb6f67e8cb9d70cda16573678d085a74cf" - -[[projects]] - branch = "master" - digest = "1:01bdbbc604dcd5afb6f66a717f69ad45e9643c72d5bc11678d44ffa5c50f9e42" - name = "golang.org/x/oauth2" - packages = [ - ".", - "google", - "internal", - "jws", - "jwt", - ] - pruneopts = "" - revision = "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33" - -[[projects]] - branch = "master" - digest = "1:8ddb956f67d4c176abbbc42b7514aaeaf9ea30daa24e27d2cf30ad82f9334a2c" - name = "golang.org/x/sys" - packages = ["cpu"] - pruneopts = "" - revision = "1e42afee0f762ed3d76e6dd942e4181855fd1849" - -[[projects]] - digest = "1:47f391ee443f578f01168347818cb234ed819521e49e4d2c8dd2fb80d48ee41a" - name = "google.golang.org/appengine" - packages = [ - ".", - "internal", - "internal/app_identity", - "internal/base", - "internal/datastore", - "internal/log", - "internal/modules", - "internal/remote_api", - "internal/urlfetch", - "urlfetch", - ] - pruneopts = "" - revision = "b2f4a3cf3c67576a2ee09e1fe62656a5086ce880" - version = "v1.6.1" - -[[projects]] - digest = "1:cedccf16b71e86db87a24f8d4c70b0a855872eb967cb906a66b95de56aefbd0d" - name = "gopkg.in/yaml.v2" - packages = ["."] - pruneopts = "" - revision = "51d6538a90f86fe93ac480b35f37b2be17fef232" - version = "v2.2.2" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - input-imports = [ - "github.com/go-errors/errors", - "github.com/mailru/easyjson", - "github.com/mailru/easyjson/jlexer", - "github.com/mailru/easyjson/jwriter", - "github.com/viant/assertly", - "github.com/viant/toolbox", - "github.com/viant/toolbox/url", - "golang.org/x/net/websocket", - ] - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/Gopkg.toml b/plugins/traefik/vendor/github.com/francoispqt/gojay/Gopkg.toml deleted file mode 100644 index fa607923a..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/Gopkg.toml +++ /dev/null @@ -1,23 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" - - -ignored = ["github.com/francoispqt/benchmarks*","github.com/stretchr/testify*","github.com/stretchr/testify","github.com/json-iterator/go","github.com/buger/jsonparser"] diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/LICENSE b/plugins/traefik/vendor/github.com/francoispqt/gojay/LICENSE deleted file mode 100644 index df215964e..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 gojay - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/Makefile b/plugins/traefik/vendor/github.com/francoispqt/gojay/Makefile deleted file mode 100644 index ce9572391..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -.PHONY: test -test: - go test -race -run=^Test -v - -.PHONY: cover -cover: - go test -coverprofile=coverage.out -covermode=atomic - -.PHONY: coverhtml -coverhtml: - go tool cover -html=coverage.out \ No newline at end of file diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/README.md b/plugins/traefik/vendor/github.com/francoispqt/gojay/README.md deleted file mode 100644 index b2abd291d..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/README.md +++ /dev/null @@ -1,855 +0,0 @@ -[![Build Status](https://travis-ci.org/francoispqt/gojay.svg?branch=master)](https://travis-ci.org/francoispqt/gojay) -[![codecov](https://codecov.io/gh/francoispqt/gojay/branch/master/graph/badge.svg)](https://codecov.io/gh/francoispqt/gojay) -[![Go Report Card](https://goreportcard.com/badge/github.com/francoispqt/gojay)](https://goreportcard.com/report/github.com/francoispqt/gojay) -[![Go doc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square -)](https://godoc.org/github.com/francoispqt/gojay) -![MIT License](https://img.shields.io/badge/license-mit-blue.svg?style=flat-square) -[![Sourcegraph](https://sourcegraph.com/github.com/francoispqt/gojay/-/badge.svg)](https://sourcegraph.com/github.com/francoispqt/gojay) -![stability-stable](https://img.shields.io/badge/stability-stable-green.svg) - -# GoJay - - - -GoJay is a performant JSON encoder/decoder for Golang (currently the most performant, [see benchmarks](#benchmark-results)). - -It has a simple API and doesn't use reflection. It relies on small interfaces to decode/encode structures and slices. - -Gojay also comes with powerful stream decoding features and an even faster [Unsafe](#unsafe-api) API. - -There is also a [code generation tool](https://github.com/francoispqt/gojay/tree/master/gojay) to make usage easier and faster. - -# Why another JSON parser? - -I looked at other fast decoder/encoder and realised it was mostly hardly readable static code generation or a lot of reflection, poor streaming features, and not so fast in the end. - -Also, I wanted to build a decoder that could consume an io.Reader of line or comma delimited JSON, in a JIT way. To consume a flow of JSON objects from a TCP connection for example or from a standard output. Same way I wanted to build an encoder that could encode a flow of data to a io.Writer. - -This is how GoJay aims to be a very fast, JIT stream parser with 0 reflection, low allocation with a friendly API. - -# Get started - -```bash -go get github.com/francoispqt/gojay -``` - -* [Encoder](#encoding) -* [Decoder](#decoding) -* [Stream API](#stream-api) -* [Code Generation](https://github.com/francoispqt/gojay/tree/master/gojay) - -## Decoding - -Decoding is done through two different API similar to standard `encoding/json`: -* [Unmarshal](#unmarshal-api) -* [Decode](#decode-api) - - -Example of basic stucture decoding with Unmarshal: -```go -import "github.com/francoispqt/gojay" - -type user struct { - id int - name string - email string -} -// implement gojay.UnmarshalerJSONObject -func (u *user) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "id": - return dec.Int(&u.id) - case "name": - return dec.String(&u.name) - case "email": - return dec.String(&u.email) - } - return nil -} -func (u *user) NKeys() int { - return 3 -} - -func main() { - u := &user{} - d := []byte(`{"id":1,"name":"gojay","email":"gojay@email.com"}`) - err := gojay.UnmarshalJSONObject(d, u) - if err != nil { - log.Fatal(err) - } -} -``` - -with Decode: -```go -func main() { - u := &user{} - dec := gojay.NewDecoder(bytes.NewReader([]byte(`{"id":1,"name":"gojay","email":"gojay@email.com"}`))) - err := dec.DecodeObject(d, u) - if err != nil { - log.Fatal(err) - } -} -``` - -### Unmarshal API - -Unmarshal API decodes a `[]byte` to a given pointer with a single function. - -Behind the doors, Unmarshal API borrows a `*gojay.Decoder` resets its settings and decodes the data to the given pointer and releases the `*gojay.Decoder` to the pool when it finishes, whether it encounters an error or not. - -If it cannot find the right Decoding strategy for the type of the given pointer, it returns an `InvalidUnmarshalError`. You can test the error returned by doing `if ok := err.(InvalidUnmarshalError); ok {}`. - -Unmarshal API comes with three functions: -* Unmarshal -```go -func Unmarshal(data []byte, v interface{}) error -``` - -* UnmarshalJSONObject -```go -func UnmarshalJSONObject(data []byte, v gojay.UnmarshalerJSONObject) error -``` - -* UnmarshalJSONArray -```go -func UnmarshalJSONArray(data []byte, v gojay.UnmarshalerJSONArray) error -``` - - -### Decode API - -Decode API decodes a `[]byte` to a given pointer by creating or borrowing a `*gojay.Decoder` with an `io.Reader` and calling `Decode` methods. - -__Getting a *gojay.Decoder or Borrowing__ - -You can either get a fresh `*gojay.Decoder` calling `dec := gojay.NewDecoder(io.Reader)` or borrow one from the pool by calling `dec := gojay.BorrowDecoder(io.Reader)`. - -After using a decoder, you can release it by calling `dec.Release()`. Beware, if you reuse the decoder after releasing it, it will panic with an error of type `InvalidUsagePooledDecoderError`. If you want to fully benefit from the pooling, you must release your decoders after using. - -Example getting a fresh an releasing: -```go -str := "" -dec := gojay.NewDecoder(strings.NewReader(`"test"`)) -defer dec.Release() -if err := dec.Decode(&str); err != nil { - log.Fatal(err) -} -``` -Example borrowing a decoder and releasing: -```go -str := "" -dec := gojay.BorrowDecoder(strings.NewReader(`"test"`)) -defer dec.Release() -if err := dec.Decode(&str); err != nil { - log.Fatal(err) -} -``` - -`*gojay.Decoder` has multiple methods to decode to specific types: -* Decode -```go -func (dec *gojay.Decoder) Decode(v interface{}) error -``` -* DecodeObject -```go -func (dec *gojay.Decoder) DecodeObject(v gojay.UnmarshalerJSONObject) error -``` -* DecodeArray -```go -func (dec *gojay.Decoder) DecodeArray(v gojay.UnmarshalerJSONArray) error -``` -* DecodeInt -```go -func (dec *gojay.Decoder) DecodeInt(v *int) error -``` -* DecodeBool -```go -func (dec *gojay.Decoder) DecodeBool(v *bool) error -``` -* DecodeString -```go -func (dec *gojay.Decoder) DecodeString(v *string) error -``` - -All DecodeXxx methods are used to decode top level JSON values. If you are decoding keys or items of a JSON object or array, don't use the Decode methods. - -Example: -```go -reader := strings.NewReader(`"John Doe"`) -dec := NewDecoder(reader) - -var str string -err := dec.DecodeString(&str) -if err != nil { - log.Fatal(err) -} - -fmt.Println(str) // John Doe -``` - -### Structs and Maps -#### UnmarshalerJSONObject Interface - -To unmarshal a JSON object to a structure, the structure must implement the `UnmarshalerJSONObject` interface: -```go -type UnmarshalerJSONObject interface { - UnmarshalJSONObject(*gojay.Decoder, string) error - NKeys() int -} -``` -`UnmarshalJSONObject` method takes two arguments, the first one is a pointer to the Decoder (*gojay.Decoder) and the second one is the string value of the current key being parsed. If the JSON data is not an object, the UnmarshalJSONObject method will never be called. - -`NKeys` method must return the number of keys to Unmarshal in the JSON object or 0. If zero is returned, all keys will be parsed. - -Example of implementation for a struct: -```go -type user struct { - id int - name string - email string -} -// implement UnmarshalerJSONObject -func (u *user) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { - switch key { - case "id": - return dec.Int(&u.id) - case "name": - return dec.String(&u.name) - case "email": - return dec.String(&u.email) - } - return nil -} -func (u *user) NKeys() int { - return 3 -} -``` - -Example of implementation for a `map[string]string`: -```go -// define our custom map type implementing UnmarshalerJSONObject -type message map[string]string - -// Implementing Unmarshaler -func (m message) UnmarshalJSONObject(dec *gojay.Decoder, k string) error { - str := "" - err := dec.String(&str) - if err != nil { - return err - } - m[k] = str - return nil -} - -// we return 0, it tells the Decoder to decode all keys -func (m message) NKeys() int { - return 0 -} -``` - -### Arrays, Slices and Channels - -To unmarshal a JSON object to a slice an array or a channel, it must implement the UnmarshalerJSONArray interface: -```go -type UnmarshalerJSONArray interface { - UnmarshalJSONArray(*gojay.Decoder) error -} -``` -UnmarshalJSONArray method takes one argument, a pointer to the Decoder (*gojay.Decoder). If the JSON data is not an array, the Unmarshal method will never be called. - -Example of implementation with a slice: -```go -type testSlice []string -// implement UnmarshalerJSONArray -func (t *testSlice) UnmarshalJSONArray(dec *gojay.Decoder) error { - str := "" - if err := dec.String(&str); err != nil { - return err - } - *t = append(*t, str) - return nil -} - -func main() { - dec := gojay.BorrowDecoder(strings.NewReader(`["Tom", "Jim"]`)) - var slice testSlice - err := dec.DecodeArray(&slice) - if err != nil { - log.Fatal(err) - } - fmt.Println(slice) // [Tom Jim] - dec.Release() -} -``` - -Example of implementation with a channel: -```go -type testChannel chan string -// implement UnmarshalerJSONArray -func (c testChannel) UnmarshalJSONArray(dec *gojay.Decoder) error { - str := "" - if err := dec.String(&str); err != nil { - return err - } - c <- str - return nil -} - -func main() { - dec := gojay.BorrowDecoder(strings.NewReader(`["Tom", "Jim"]`)) - c := make(testChannel, 2) - err := dec.DecodeArray(c) - if err != nil { - log.Fatal(err) - } - for i := 0; i < 2; i++ { - fmt.Println(<-c) - } - close(c) - dec.Release() -} -``` - -Example of implementation with an array: -```go -type testArray [3]string -// implement UnmarshalerJSONArray -func (a *testArray) UnmarshalJSONArray(dec *Decoder) error { - var str string - if err := dec.String(&str); err != nil { - return err - } - a[dec.Index()] = str - return nil -} - -func main() { - dec := gojay.BorrowDecoder(strings.NewReader(`["Tom", "Jim", "Bob"]`)) - var a testArray - err := dec.DecodeArray(&a) - fmt.Println(a) // [Tom Jim Bob] - dec.Release() -} -``` - -### Other types -To decode other types (string, int, int32, int64, uint32, uint64, float, booleans), you don't need to implement any interface. - -Example of encoding strings: -```go -func main() { - json := []byte(`"Jay"`) - var v string - err := gojay.Unmarshal(json, &v) - if err != nil { - log.Fatal(err) - } - fmt.Println(v) // Jay -} -``` - -### Decode values methods -When decoding a JSON object of a JSON array using `UnmarshalerJSONObject` or `UnmarshalerJSONArray` interface, the `gojay.Decoder` provides dozens of methods to Decode multiple types. - -Non exhaustive list of methods available (to see all methods, check the godoc): -```go -dec.Int -dec.Int8 -dec.Int16 -dec.Int32 -dec.Int64 -dec.Uint8 -dec.Uint16 -dec.Uint32 -dec.Uint64 -dec.String -dec.Time -dec.Bool -dec.SQLNullString -dec.SQLNullInt64 -``` - - -## Encoding - -Encoding is done through two different API similar to standard `encoding/json`: -* [Marshal](#marshal-api) -* [Encode](#encode-api) - -Example of basic structure encoding with Marshal: -```go -import "github.com/francoispqt/gojay" - -type user struct { - id int - name string - email string -} - -// implement MarshalerJSONObject -func (u *user) MarshalJSONObject(enc *gojay.Encoder) { - enc.IntKey("id", u.id) - enc.StringKey("name", u.name) - enc.StringKey("email", u.email) -} -func (u *user) IsNil() bool { - return u == nil -} - -func main() { - u := &user{1, "gojay", "gojay@email.com"} - b, err := gojay.MarshalJSONObject(u) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(b)) // {"id":1,"name":"gojay","email":"gojay@email.com"} -} -``` - -with Encode: -```go -func main() { - u := &user{1, "gojay", "gojay@email.com"} - b := strings.Builder{} - enc := gojay.NewEncoder(&b) - if err := enc.Encode(u); err != nil { - log.Fatal(err) - } - fmt.Println(b.String()) // {"id":1,"name":"gojay","email":"gojay@email.com"} -} -``` - -### Marshal API - -Marshal API encodes a value to a JSON `[]byte` with a single function. - -Behind the doors, Marshal API borrows a `*gojay.Encoder` resets its settings and encodes the data to an internal byte buffer and releases the `*gojay.Encoder` to the pool when it finishes, whether it encounters an error or not. - -If it cannot find the right Encoding strategy for the type of the given value, it returns an `InvalidMarshalError`. You can test the error returned by doing `if ok := err.(InvalidMarshalError); ok {}`. - -Marshal API comes with three functions: -* Marshal -```go -func Marshal(v interface{}) ([]byte, error) -``` - -* MarshalJSONObject -```go -func MarshalJSONObject(v gojay.MarshalerJSONObject) ([]byte, error) -``` - -* MarshalJSONArray -```go -func MarshalJSONArray(v gojay.MarshalerJSONArray) ([]byte, error) -``` - -### Encode API - -Encode API decodes a value to JSON by creating or borrowing a `*gojay.Encoder` sending it to an `io.Writer` and calling `Encode` methods. - -__Getting a *gojay.Encoder or Borrowing__ - -You can either get a fresh `*gojay.Encoder` calling `enc := gojay.NewEncoder(io.Writer)` or borrow one from the pool by calling `enc := gojay.BorrowEncoder(io.Writer)`. - -After using an encoder, you can release it by calling `enc.Release()`. Beware, if you reuse the encoder after releasing it, it will panic with an error of type `InvalidUsagePooledEncoderError`. If you want to fully benefit from the pooling, you must release your encoders after using. - -Example getting a fresh encoder an releasing: -```go -str := "test" -b := strings.Builder{} -enc := gojay.NewEncoder(&b) -defer enc.Release() -if err := enc.Encode(str); err != nil { - log.Fatal(err) -} -``` -Example borrowing an encoder and releasing: -```go -str := "test" -b := strings.Builder{} -enc := gojay.BorrowEncoder(b) -defer enc.Release() -if err := enc.Encode(str); err != nil { - log.Fatal(err) -} -``` - -`*gojay.Encoder` has multiple methods to encoder specific types to JSON: -* Encode -```go -func (enc *gojay.Encoder) Encode(v interface{}) error -``` -* EncodeObject -```go -func (enc *gojay.Encoder) EncodeObject(v gojay.MarshalerJSONObject) error -``` -* EncodeArray -```go -func (enc *gojay.Encoder) EncodeArray(v gojay.MarshalerJSONArray) error -``` -* EncodeInt -```go -func (enc *gojay.Encoder) EncodeInt(n int) error -``` -* EncodeInt64 -```go -func (enc *gojay.Encoder) EncodeInt64(n int64) error -``` -* EncodeFloat -```go -func (enc *gojay.Encoder) EncodeFloat(n float64) error -``` -* EncodeBool -```go -func (enc *gojay.Encoder) EncodeBool(v bool) error -``` -* EncodeString -```go -func (enc *gojay.Encoder) EncodeString(s string) error -``` - -### Structs and Maps - -To encode a structure, the structure must implement the MarshalerJSONObject interface: -```go -type MarshalerJSONObject interface { - MarshalJSONObject(enc *gojay.Encoder) - IsNil() bool -} -``` -`MarshalJSONObject` method takes one argument, a pointer to the Encoder (*gojay.Encoder). The method must add all the keys in the JSON Object by calling Decoder's methods. - -IsNil method returns a boolean indicating if the interface underlying value is nil or not. It is used to safely ensure that the underlying value is not nil without using Reflection. - -Example of implementation for a struct: -```go -type user struct { - id int - name string - email string -} - -// implement MarshalerJSONObject -func (u *user) MarshalJSONObject(enc *gojay.Encoder) { - enc.IntKey("id", u.id) - enc.StringKey("name", u.name) - enc.StringKey("email", u.email) -} -func (u *user) IsNil() bool { - return u == nil -} -``` - -Example of implementation for a `map[string]string`: -```go -// define our custom map type implementing MarshalerJSONObject -type message map[string]string - -// Implementing Marshaler -func (m message) MarshalJSONObject(enc *gojay.Encoder) { - for k, v := range m { - enc.StringKey(k, v) - } -} - -func (m message) IsNil() bool { - return m == nil -} -``` - -### Arrays and Slices -To encode an array or a slice, the slice/array must implement the MarshalerJSONArray interface: -```go -type MarshalerJSONArray interface { - MarshalJSONArray(enc *gojay.Encoder) - IsNil() bool -} -``` -`MarshalJSONArray` method takes one argument, a pointer to the Encoder (*gojay.Encoder). The method must add all element in the JSON Array by calling Decoder's methods. - -`IsNil` method returns a boolean indicating if the interface underlying value is nil(empty) or not. It is used to safely ensure that the underlying value is not nil without using Reflection and also to in `OmitEmpty` feature. - -Example of implementation: -```go -type users []*user -// implement MarshalerJSONArray -func (u *users) MarshalJSONArray(enc *gojay.Encoder) { - for _, e := range u { - enc.Object(e) - } -} -func (u *users) IsNil() bool { - return len(u) == 0 -} -``` - -### Other types -To encode other types (string, int, float, booleans), you don't need to implement any interface. - -Example of encoding strings: -```go -func main() { - name := "Jay" - b, err := gojay.Marshal(name) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(b)) // "Jay" -} -``` - -# Stream API - -### Stream Decoding -GoJay ships with a powerful stream decoder. - -It allows to read continuously from an io.Reader stream and do JIT decoding writing unmarshalled JSON to a channel to allow async consuming. - -When using the Stream API, the Decoder implements context.Context to provide graceful cancellation. - -To decode a stream of JSON, you must call `gojay.Stream.DecodeStream` and pass it a `UnmarshalerStream` implementation. - -```go -type UnmarshalerStream interface { - UnmarshalStream(*StreamDecoder) error -} -``` - -Example of implementation of stream reading from a WebSocket connection: -```go -// implement UnmarshalerStream -type ChannelStream chan *user - -func (c ChannelStream) UnmarshalStream(dec *gojay.StreamDecoder) error { - u := &user{} - if err := dec.Object(u); err != nil { - return err - } - c <- u - return nil -} - -func main() { - // get our websocket connection - origin := "http://localhost/" - url := "ws://localhost:12345/ws" - ws, err := websocket.Dial(url, "", origin) - if err != nil { - log.Fatal(err) - } - // create our channel which will receive our objects - streamChan := ChannelStream(make(chan *user)) - // borrow a decoder - dec := gojay.Stream.BorrowDecoder(ws) - // start decoding, it will block until a JSON message is decoded from the WebSocket - // or until Done channel is closed - go dec.DecodeStream(streamChan) - for { - select { - case v := <-streamChan: - // Got something from my websocket! - log.Println(v) - case <-dec.Done(): - log.Println("finished reading from WebSocket") - os.Exit(0) - } - } -} -``` - -### Stream Encoding -GoJay ships with a powerful stream encoder part of the Stream API. - -It allows to write continuously to an io.Writer and do JIT encoding of data fed to a channel to allow async consuming. You can set multiple consumers on the channel to be as performant as possible. Consumers are non blocking and are scheduled individually in their own go routine. - -When using the Stream API, the Encoder implements context.Context to provide graceful cancellation. - -To encode a stream of data, you must call `EncodeStream` and pass it a `MarshalerStream` implementation. - -```go -type MarshalerStream interface { - MarshalStream(enc *gojay.StreamEncoder) -} -``` - -Example of implementation of stream writing to a WebSocket: -```go -// Our structure which will be pushed to our stream -type user struct { - id int - name string - email string -} - -func (u *user) MarshalJSONObject(enc *gojay.Encoder) { - enc.IntKey("id", u.id) - enc.StringKey("name", u.name) - enc.StringKey("email", u.email) -} -func (u *user) IsNil() bool { - return u == nil -} - -// Our MarshalerStream implementation -type StreamChan chan *user - -func (s StreamChan) MarshalStream(enc *gojay.StreamEncoder) { - select { - case <-enc.Done(): - return - case o := <-s: - enc.Object(o) - } -} - -// Our main function -func main() { - // get our websocket connection - origin := "http://localhost/" - url := "ws://localhost:12345/ws" - ws, err := websocket.Dial(url, "", origin) - if err != nil { - log.Fatal(err) - } - // we borrow an encoder set stdout as the writer, - // set the number of consumer to 10 - // and tell the encoder to separate each encoded element - // added to the channel by a new line character - enc := gojay.Stream.BorrowEncoder(ws).NConsumer(10).LineDelimited() - // instantiate our MarshalerStream - s := StreamChan(make(chan *user)) - // start the stream encoder - // will block its goroutine until enc.Cancel(error) is called - // or until something is written to the channel - go enc.EncodeStream(s) - // write to our MarshalerStream - for i := 0; i < 1000; i++ { - s <- &user{i, "username", "user@email.com"} - } - // Wait - <-enc.Done() -} -``` - -# Unsafe API - -Unsafe API has the same functions than the regular API, it only has `Unmarshal API` for now. It is unsafe because it makes assumptions on the quality of the given JSON. - -If you are not sure if your JSON is valid, don't use the Unsafe API. - -Also, the `Unsafe` API does not copy the buffer when using Unmarshal API, which, in case of string decoding, can lead to data corruption if a byte buffer is reused. Using the `Decode` API makes `Unsafe` API safer as the io.Reader relies on `copy` builtin method and `Decoder` will have its own internal buffer :) - -Access the `Unsafe` API this way: -```go -gojay.Unsafe.Unmarshal(b, v) -``` - - -# Benchmarks - -Benchmarks encode and decode three different data based on size (small, medium, large). - -To run benchmark for decoder: -```bash -cd $GOPATH/src/github.com/francoispqt/gojay/benchmarks/decoder && make bench -``` - -To run benchmark for encoder: -```bash -cd $GOPATH/src/github.com/francoispqt/gojay/benchmarks/encoder && make bench -``` - -# Benchmark Results -## Decode - - - -### Small Payload -[benchmark code is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/decoder/decoder_bench_small_test.go) - -[benchmark data is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/benchmarks_small.go) - -| | ns/op | bytes/op | allocs/op | -|-----------------|-----------|--------------|-----------| -| Std Library | 2547 | 496 | 4 | -| JsonIter | 2046 | 312 | 12 | -| JsonParser | 1408 | 0 | 0 | -| EasyJson | 929 | 240 | 2 | -| **GoJay** | **807** | **256** | **2** | -| **GoJay-unsafe**| **712** | **112** | **1** | - -### Medium Payload -[benchmark code is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/decoder/decoder_bench_medium_test.go) - -[benchmark data is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/benchmarks_medium.go) - -| | ns/op | bytes/op | allocs/op | -|-----------------|-----------|----------|-----------| -| Std Library | 30148 | 2152 | 496 | -| JsonIter | 16309 | 2976 | 80 | -| JsonParser | 7793 | 0 | 0 | -| EasyJson | 7957 | 232 | 6 | -| **GoJay** | **4984** | **2448** | **8** | -| **GoJay-unsafe**| **4809** | **144** | **7** | - -### Large Payload -[benchmark code is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/decoder/decoder_bench_large_test.go) - -[benchmark data is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/benchmarks_large.go) - -| | ns/op | bytes/op | allocs/op | -|-----------------|-----------|-------------|-----------| -| JsonIter | 210078 | 41712 | 1136 | -| EasyJson | 106626 | 160 | 2 | -| JsonParser | 66813 | 0 | 0 | -| **GoJay** | **52153** | **31241** | **77** | -| **GoJay-unsafe**| **48277** | **2561** | **76** | - -## Encode - - - -### Small Struct -[benchmark code is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/encoder/encoder_bench_small_test.go) - -[benchmark data is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/benchmarks_small.go) - -| | ns/op | bytes/op | allocs/op | -|----------------|----------|--------------|-----------| -| Std Library | 1280 | 464 | 3 | -| EasyJson | 871 | 944 | 6 | -| JsonIter | 866 | 272 | 3 | -| **GoJay** | **543** | **112** | **1** | -| **GoJay-func** | **347** | **0** | **0** | - -### Medium Struct -[benchmark code is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/encoder/encoder_bench_medium_test.go) - -[benchmark data is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/benchmarks_medium.go) - -| | ns/op | bytes/op | allocs/op | -|-------------|----------|--------------|-----------| -| Std Library | 5006 | 1496 | 25 | -| JsonIter | 2232 | 1544 | 20 | -| EasyJson | 1997 | 1544 | 19 | -| **GoJay** | **1522** | **312** | **14** | - -### Large Struct -[benchmark code is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/encoder/encoder_bench_large_test.go) - -[benchmark data is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/benchmarks_large.go) - -| | ns/op | bytes/op | allocs/op | -|-------------|-----------|--------------|-----------| -| Std Library | 66441 | 20576 | 332 | -| JsonIter | 35247 | 20255 | 328 | -| EasyJson | 32053 | 15474 | 327 | -| **GoJay** | **27847** | **9802** | **318** | - -# Contributing - -Contributions are welcome :) - -If you encounter issues please report it in Github and/or send an email at [francois@parquet.ninja](mailto:francois@parquet.ninja) - diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode.go deleted file mode 100644 index fbd07f76c..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode.go +++ /dev/null @@ -1,386 +0,0 @@ -package gojay - -import ( - "fmt" - "io" -) - -// UnmarshalJSONArray parses the JSON-encoded data and stores the result in the value pointed to by v. -// -// v must implement UnmarshalerJSONArray. -// -// If a JSON value is not appropriate for a given target type, or if a JSON number -// overflows the target type, UnmarshalJSONArray skips that field and completes the unmarshaling as best it can. -func UnmarshalJSONArray(data []byte, v UnmarshalerJSONArray) error { - dec := borrowDecoder(nil, 0) - defer dec.Release() - dec.data = make([]byte, len(data)) - copy(dec.data, data) - dec.length = len(data) - _, err := dec.decodeArray(v) - if err != nil { - return err - } - if dec.err != nil { - return dec.err - } - return nil -} - -// UnmarshalJSONObject parses the JSON-encoded data and stores the result in the value pointed to by v. -// -// v must implement UnmarshalerJSONObject. -// -// If a JSON value is not appropriate for a given target type, or if a JSON number -// overflows the target type, UnmarshalJSONObject skips that field and completes the unmarshaling as best it can. -func UnmarshalJSONObject(data []byte, v UnmarshalerJSONObject) error { - dec := borrowDecoder(nil, 0) - defer dec.Release() - dec.data = make([]byte, len(data)) - copy(dec.data, data) - dec.length = len(data) - _, err := dec.decodeObject(v) - if err != nil { - return err - } - if dec.err != nil { - return dec.err - } - return nil -} - -// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. -// If v is nil, not an implementation of UnmarshalerJSONObject or UnmarshalerJSONArray or not one of the following types: -// *string, **string, *int, **int, *int8, **int8, *int16, **int16, *int32, **int32, *int64, **int64, *uint8, **uint8, *uint16, **uint16, -// *uint32, **uint32, *uint64, **uint64, *float64, **float64, *float32, **float32, *bool, **bool -// Unmarshal returns an InvalidUnmarshalError. -// -// -// If a JSON value is not appropriate for a given target type, or if a JSON number -// overflows the target type, Unmarshal skips that field and completes the unmarshaling as best it can. -// If no more serious errors are encountered, Unmarshal returns an UnmarshalTypeError describing the earliest such error. -// In any case, it's not guaranteed that all the remaining fields following the problematic one will be unmarshaled into the target object. -func Unmarshal(data []byte, v interface{}) error { - var err error - var dec *Decoder - switch vt := v.(type) { - case *string: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeString(vt) - case **string: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeStringNull(vt) - case *int: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt(vt) - case **int: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeIntNull(vt) - case *int8: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt8(vt) - case **int8: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt8Null(vt) - case *int16: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt16(vt) - case **int16: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt16Null(vt) - case *int32: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt32(vt) - case **int32: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt32Null(vt) - case *int64: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt64(vt) - case **int64: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt64Null(vt) - case *uint8: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeUint8(vt) - case **uint8: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeUint8Null(vt) - case *uint16: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeUint16(vt) - case **uint16: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeUint16Null(vt) - case *uint32: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeUint32(vt) - case **uint32: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeUint32Null(vt) - case *uint64: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeUint64(vt) - case **uint64: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeUint64Null(vt) - case *float64: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeFloat64(vt) - case **float64: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeFloat64Null(vt) - case *float32: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeFloat32(vt) - case **float32: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeFloat32Null(vt) - case *bool: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeBool(vt) - case **bool: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeBoolNull(vt) - case UnmarshalerJSONObject: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = make([]byte, len(data)) - copy(dec.data, data) - _, err = dec.decodeObject(vt) - case UnmarshalerJSONArray: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = make([]byte, len(data)) - copy(dec.data, data) - _, err = dec.decodeArray(vt) - case *interface{}: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = make([]byte, len(data)) - copy(dec.data, data) - err = dec.decodeInterface(vt) - default: - return InvalidUnmarshalError(fmt.Sprintf(invalidUnmarshalErrorMsg, vt)) - } - defer dec.Release() - if err != nil { - return err - } - return dec.err -} - -// UnmarshalerJSONObject is the interface to implement to decode a JSON Object. -type UnmarshalerJSONObject interface { - UnmarshalJSONObject(*Decoder, string) error - NKeys() int -} - -// UnmarshalerJSONArray is the interface to implement to decode a JSON Array. -type UnmarshalerJSONArray interface { - UnmarshalJSONArray(*Decoder) error -} - -// A Decoder reads and decodes JSON values from an input stream. -type Decoder struct { - r io.Reader - data []byte - err error - isPooled byte - called byte - child byte - cursor int - length int - keysDone int - arrayIndex int -} - -// Decode reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -// The differences between Decode and Unmarshal are: -// - Decode reads from an io.Reader in the Decoder, whereas Unmarshal reads from a []byte -// - Decode leaves to the user the option of borrowing and releasing a Decoder, whereas Unmarshal internally always borrows a Decoder and releases it when the unmarshaling is completed -func (dec *Decoder) Decode(v interface{}) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - var err error - switch vt := v.(type) { - case *string: - err = dec.decodeString(vt) - case **string: - err = dec.decodeStringNull(vt) - case *int: - err = dec.decodeInt(vt) - case **int: - err = dec.decodeIntNull(vt) - case *int8: - err = dec.decodeInt8(vt) - case **int8: - err = dec.decodeInt8Null(vt) - case *int16: - err = dec.decodeInt16(vt) - case **int16: - err = dec.decodeInt16Null(vt) - case *int32: - err = dec.decodeInt32(vt) - case **int32: - err = dec.decodeInt32Null(vt) - case *int64: - err = dec.decodeInt64(vt) - case **int64: - err = dec.decodeInt64Null(vt) - case *uint8: - err = dec.decodeUint8(vt) - case **uint8: - err = dec.decodeUint8Null(vt) - case *uint16: - err = dec.decodeUint16(vt) - case **uint16: - err = dec.decodeUint16Null(vt) - case *uint32: - err = dec.decodeUint32(vt) - case **uint32: - err = dec.decodeUint32Null(vt) - case *uint64: - err = dec.decodeUint64(vt) - case **uint64: - err = dec.decodeUint64Null(vt) - case *float64: - err = dec.decodeFloat64(vt) - case **float64: - err = dec.decodeFloat64Null(vt) - case *float32: - err = dec.decodeFloat32(vt) - case **float32: - err = dec.decodeFloat32Null(vt) - case *bool: - err = dec.decodeBool(vt) - case **bool: - err = dec.decodeBoolNull(vt) - case UnmarshalerJSONObject: - _, err = dec.decodeObject(vt) - case UnmarshalerJSONArray: - _, err = dec.decodeArray(vt) - case *EmbeddedJSON: - err = dec.decodeEmbeddedJSON(vt) - case *interface{}: - err = dec.decodeInterface(vt) - default: - return InvalidUnmarshalError(fmt.Sprintf(invalidUnmarshalErrorMsg, vt)) - } - if err != nil { - return err - } - return dec.err -} - -// Non exported - -func isDigit(b byte) bool { - switch b { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - return true - default: - return false - } -} - -func (dec *Decoder) read() bool { - if dec.r != nil { - // if we reach the end, double the buffer to ensure there's always more space - if len(dec.data) == dec.length { - nLen := dec.length * 2 - if nLen == 0 { - nLen = 512 - } - Buf := make([]byte, nLen, nLen) - copy(Buf, dec.data) - dec.data = Buf - } - var n int - var err error - for n == 0 { - n, err = dec.r.Read(dec.data[dec.length:]) - if err != nil { - if err != io.EOF { - dec.err = err - return false - } - if n == 0 { - return false - } - dec.length = dec.length + n - return true - } - } - dec.length = dec.length + n - return true - } - return false -} - -func (dec *Decoder) nextChar() byte { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - continue - } - d := dec.data[dec.cursor] - return d - } - return 0 -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_array.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_array.go deleted file mode 100644 index 297f2ee74..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_array.go +++ /dev/null @@ -1,247 +0,0 @@ -package gojay - -import "reflect" - -// DecodeArray reads the next JSON-encoded value from the decoder's input (io.Reader) -// and stores it in the value pointed to by v. -// -// v must implement UnmarshalerJSONArray. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeArray(v UnmarshalerJSONArray) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - _, err := dec.decodeArray(v) - return err -} -func (dec *Decoder) decodeArray(arr UnmarshalerJSONArray) (int, error) { - // remember last array index in case of nested arrays - lastArrayIndex := dec.arrayIndex - dec.arrayIndex = 0 - defer func() { - dec.arrayIndex = lastArrayIndex - }() - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - continue - case '[': - dec.cursor = dec.cursor + 1 - // array is open, char is not space start readings - for dec.nextChar() != 0 { - // closing array - if dec.data[dec.cursor] == ']' { - dec.cursor = dec.cursor + 1 - return dec.cursor, nil - } - // calling unmarshall function for each element of the slice - err := arr.UnmarshalJSONArray(dec) - if err != nil { - return 0, err - } - dec.arrayIndex++ - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) - case 'n': - // is null - dec.cursor++ - err := dec.assertNull() - if err != nil { - return 0, err - } - return dec.cursor, nil - case '{', '"', 'f', 't', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - // can't unmarshall to struct - // we skip array and set Error - dec.err = dec.makeInvalidUnmarshalErr(arr) - err := dec.skipData() - if err != nil { - return 0, err - } - return dec.cursor, nil - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} -func (dec *Decoder) decodeArrayNull(v interface{}) (int, error) { - // remember last array index in case of nested arrays - lastArrayIndex := dec.arrayIndex - dec.arrayIndex = 0 - defer func() { - dec.arrayIndex = lastArrayIndex - }() - vv := reflect.ValueOf(v) - vvt := vv.Type() - if vvt.Kind() != reflect.Ptr || vvt.Elem().Kind() != reflect.Ptr { - dec.err = ErrUnmarshalPtrExpected - return 0, dec.err - } - // not an array not an error, but do not know what to do - // do not check syntax - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - continue - case '[': - dec.cursor = dec.cursor + 1 - // create our new type - elt := vv.Elem() - n := reflect.New(elt.Type().Elem()) - var arr UnmarshalerJSONArray - var ok bool - if arr, ok = n.Interface().(UnmarshalerJSONArray); !ok { - dec.err = dec.makeInvalidUnmarshalErr((UnmarshalerJSONArray)(nil)) - return 0, dec.err - } - // array is open, char is not space start readings - for dec.nextChar() != 0 { - // closing array - if dec.data[dec.cursor] == ']' { - elt.Set(n) - dec.cursor = dec.cursor + 1 - return dec.cursor, nil - } - // calling unmarshall function for each element of the slice - err := arr.UnmarshalJSONArray(dec) - if err != nil { - return 0, err - } - dec.arrayIndex++ - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) - case 'n': - // is null - dec.cursor++ - err := dec.assertNull() - if err != nil { - return 0, err - } - return dec.cursor, nil - case '{', '"', 'f', 't', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - // can't unmarshall to struct - // we skip array and set Error - dec.err = dec.makeInvalidUnmarshalErr((UnmarshalerJSONArray)(nil)) - err := dec.skipData() - if err != nil { - return 0, err - } - return dec.cursor, nil - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) skipArray() (int, error) { - var arraysOpen = 1 - var arraysClosed = 0 - // var stringOpen byte = 0 - for j := dec.cursor; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case ']': - arraysClosed++ - // everything is closed return - if arraysOpen == arraysClosed { - // add char to object data - return j + 1, nil - } - case '[': - arraysOpen++ - case '"': - j++ - var isInEscapeSeq bool - var isFirstQuote = true - for ; j < dec.length || dec.read(); j++ { - if dec.data[j] != '"' { - continue - } - if dec.data[j-1] != '\\' || (!isInEscapeSeq && !isFirstQuote) { - break - } else { - isInEscapeSeq = false - } - if isFirstQuote { - isFirstQuote = false - } - // loop backward and count how many anti slash found - // to see if string is effectively escaped - ct := 0 - for i := j - 1; i > 0; i-- { - if dec.data[i] != '\\' { - break - } - ct++ - } - // is pair number of slashes, quote is not escaped - if ct&1 == 0 { - break - } - isInEscapeSeq = true - } - default: - continue - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -// DecodeArrayFunc is a func type implementing UnmarshalerJSONArray. -// Use it to cast a `func(*Decoder) error` to Unmarshal an array on the fly. - -type DecodeArrayFunc func(*Decoder) error - -// UnmarshalJSONArray implements UnmarshalerJSONArray. -func (f DecodeArrayFunc) UnmarshalJSONArray(dec *Decoder) error { - return f(dec) -} - -// IsNil implements UnmarshalerJSONArray. -func (f DecodeArrayFunc) IsNil() bool { - return f == nil -} - -// Add Values functions - -// AddArray decodes the JSON value within an object or an array to a UnmarshalerJSONArray. -func (dec *Decoder) AddArray(v UnmarshalerJSONArray) error { - return dec.Array(v) -} - -// AddArrayNull decodes the JSON value within an object or an array to a UnmarshalerJSONArray. -func (dec *Decoder) AddArrayNull(v interface{}) error { - return dec.ArrayNull(v) -} - -// Array decodes the JSON value within an object or an array to a UnmarshalerJSONArray. -func (dec *Decoder) Array(v UnmarshalerJSONArray) error { - newCursor, err := dec.decodeArray(v) - if err != nil { - return err - } - dec.cursor = newCursor - dec.called |= 1 - return nil -} - -// ArrayNull decodes the JSON value within an object or an array to a UnmarshalerJSONArray. -// v should be a pointer to an UnmarshalerJSONArray, -// if `null` value is encountered in JSON, it will leave the value v untouched, -// else it will create a new instance of the UnmarshalerJSONArray behind v. -func (dec *Decoder) ArrayNull(v interface{}) error { - newCursor, err := dec.decodeArrayNull(v) - if err != nil { - return err - } - dec.cursor = newCursor - dec.called |= 1 - return nil -} - -// Index returns the index of an array being decoded. -func (dec *Decoder) Index() int { - return dec.arrayIndex -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_bool.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_bool.go deleted file mode 100644 index 1dc304ba7..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_bool.go +++ /dev/null @@ -1,241 +0,0 @@ -package gojay - -// DecodeBool reads the next JSON-encoded value from the decoder's input (io.Reader) -// and stores it in the boolean pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeBool(v *bool) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeBool(v) -} -func (dec *Decoder) decodeBool(v *bool) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - continue - case 't': - dec.cursor++ - err := dec.assertTrue() - if err != nil { - return err - } - *v = true - return nil - case 'f': - dec.cursor++ - err := dec.assertFalse() - if err != nil { - return err - } - *v = false - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - *v = false - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return nil -} -func (dec *Decoder) decodeBoolNull(v **bool) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - continue - case 't': - dec.cursor++ - err := dec.assertTrue() - if err != nil { - return err - } - if *v == nil { - *v = new(bool) - } - **v = true - return nil - case 'f': - dec.cursor++ - err := dec.assertFalse() - if err != nil { - return err - } - if *v == nil { - *v = new(bool) - } - **v = false - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return nil -} - -func (dec *Decoder) assertTrue() error { - i := 0 - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch i { - case 0: - if dec.data[dec.cursor] != 'r' { - return dec.raiseInvalidJSONErr(dec.cursor) - } - case 1: - if dec.data[dec.cursor] != 'u' { - return dec.raiseInvalidJSONErr(dec.cursor) - } - case 2: - if dec.data[dec.cursor] != 'e' { - return dec.raiseInvalidJSONErr(dec.cursor) - } - case 3: - switch dec.data[dec.cursor] { - case ' ', '\b', '\t', '\n', ',', ']', '}': - // dec.cursor-- - return nil - default: - return dec.raiseInvalidJSONErr(dec.cursor) - } - } - i++ - } - if i == 3 { - return nil - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) assertNull() error { - i := 0 - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch i { - case 0: - if dec.data[dec.cursor] != 'u' { - return dec.raiseInvalidJSONErr(dec.cursor) - } - case 1: - if dec.data[dec.cursor] != 'l' { - return dec.raiseInvalidJSONErr(dec.cursor) - } - case 2: - if dec.data[dec.cursor] != 'l' { - return dec.raiseInvalidJSONErr(dec.cursor) - } - case 3: - switch dec.data[dec.cursor] { - case ' ', '\t', '\n', ',', ']', '}': - // dec.cursor-- - return nil - default: - return dec.raiseInvalidJSONErr(dec.cursor) - } - } - i++ - } - if i == 3 { - return nil - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) assertFalse() error { - i := 0 - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch i { - case 0: - if dec.data[dec.cursor] != 'a' { - return dec.raiseInvalidJSONErr(dec.cursor) - } - case 1: - if dec.data[dec.cursor] != 'l' { - return dec.raiseInvalidJSONErr(dec.cursor) - } - case 2: - if dec.data[dec.cursor] != 's' { - return dec.raiseInvalidJSONErr(dec.cursor) - } - case 3: - if dec.data[dec.cursor] != 'e' { - return dec.raiseInvalidJSONErr(dec.cursor) - } - case 4: - switch dec.data[dec.cursor] { - case ' ', '\t', '\n', ',', ']', '}': - // dec.cursor-- - return nil - default: - return dec.raiseInvalidJSONErr(dec.cursor) - } - } - i++ - } - if i == 4 { - return nil - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -// Add Values functions - -// AddBool decodes the JSON value within an object or an array to a *bool. -// If next key is neither null nor a JSON boolean, an InvalidUnmarshalError will be returned. -// If next key is null, bool will be false. -func (dec *Decoder) AddBool(v *bool) error { - return dec.Bool(v) -} - -// AddBoolNull decodes the JSON value within an object or an array to a *bool. -// If next key is neither null nor a JSON boolean, an InvalidUnmarshalError will be returned. -// If next key is null, bool will be false. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddBoolNull(v **bool) error { - return dec.BoolNull(v) -} - -// Bool decodes the JSON value within an object or an array to a *bool. -// If next key is neither null nor a JSON boolean, an InvalidUnmarshalError will be returned. -// If next key is null, bool will be false. -func (dec *Decoder) Bool(v *bool) error { - err := dec.decodeBool(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// BoolNull decodes the JSON value within an object or an array to a *bool. -// If next key is neither null nor a JSON boolean, an InvalidUnmarshalError will be returned. -// If next key is null, bool will be false. -func (dec *Decoder) BoolNull(v **bool) error { - err := dec.decodeBoolNull(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_embedded_json.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_embedded_json.go deleted file mode 100644 index 67fcc2eae..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_embedded_json.go +++ /dev/null @@ -1,85 +0,0 @@ -package gojay - -// EmbeddedJSON is a raw encoded JSON value. -// It can be used to delay JSON decoding or precompute a JSON encoding. -type EmbeddedJSON []byte - -func (dec *Decoder) decodeEmbeddedJSON(ej *EmbeddedJSON) error { - var err error - if ej == nil { - return InvalidUnmarshalError("Invalid nil pointer given") - } - var beginOfEmbeddedJSON int - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - continue - // is null - case 'n': - beginOfEmbeddedJSON = dec.cursor - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - case 't': - beginOfEmbeddedJSON = dec.cursor - dec.cursor++ - err := dec.assertTrue() - if err != nil { - return err - } - // is false - case 'f': - beginOfEmbeddedJSON = dec.cursor - dec.cursor++ - err := dec.assertFalse() - if err != nil { - return err - } - // is an object - case '{': - beginOfEmbeddedJSON = dec.cursor - dec.cursor = dec.cursor + 1 - dec.cursor, err = dec.skipObject() - // is string - case '"': - beginOfEmbeddedJSON = dec.cursor - dec.cursor = dec.cursor + 1 - err = dec.skipString() // why no new dec.cursor in result? - // is array - case '[': - beginOfEmbeddedJSON = dec.cursor - dec.cursor = dec.cursor + 1 - dec.cursor, err = dec.skipArray() - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': - beginOfEmbeddedJSON = dec.cursor - dec.cursor, err = dec.skipNumber() - } - break - } - if err == nil { - if dec.cursor-1 >= beginOfEmbeddedJSON { - *ej = append(*ej, dec.data[beginOfEmbeddedJSON:dec.cursor]...) - } - dec.called |= 1 - } - return err -} - -// AddEmbeddedJSON adds an EmbeddedsJSON to the value pointed by v. -// It can be used to delay JSON decoding or precompute a JSON encoding. -func (dec *Decoder) AddEmbeddedJSON(v *EmbeddedJSON) error { - return dec.EmbeddedJSON(v) -} - -// EmbeddedJSON adds an EmbeddedsJSON to the value pointed by v. -// It can be used to delay JSON decoding or precompute a JSON encoding. -func (dec *Decoder) EmbeddedJSON(v *EmbeddedJSON) error { - err := dec.decodeEmbeddedJSON(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_interface.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_interface.go deleted file mode 100644 index 015790d85..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_interface.go +++ /dev/null @@ -1,130 +0,0 @@ -package gojay - -// TODO @afiune for now we are using the standard json unmarshaling but in -// the future it would be great to implement one here inside this repo -import "encoding/json" - -// DecodeInterface reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by i. -// -// i must be an interface poiter -func (dec *Decoder) DecodeInterface(i *interface{}) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - err := dec.decodeInterface(i) - return err -} - -func (dec *Decoder) decodeInterface(i *interface{}) error { - start, end, err := dec.getObject() - if err != nil { - dec.cursor = start - return err - } - - // if start & end are equal the object is a null, don't unmarshal - if start == end { - return nil - } - - object := dec.data[start:end] - if err = json.Unmarshal(object, i); err != nil { - return err - } - - dec.cursor = end - return nil -} - -// @afiune Maybe return the type as well? -func (dec *Decoder) getObject() (start int, end int, err error) { - // start cursor - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - continue - // is null - case 'n': - dec.cursor++ - err = dec.assertNull() - if err != nil { - return - } - // Set start & end to the same cursor to indicate the object - // is a null and should not be unmarshal - start = dec.cursor - end = dec.cursor - return - case 't': - start = dec.cursor - dec.cursor++ - err = dec.assertTrue() - if err != nil { - return - } - end = dec.cursor - dec.cursor++ - return - // is false - case 'f': - start = dec.cursor - dec.cursor++ - err = dec.assertFalse() - if err != nil { - return - } - end = dec.cursor - dec.cursor++ - return - // is an object - case '{': - start = dec.cursor - dec.cursor++ - end, err = dec.skipObject() - dec.cursor = end - return - // is string - case '"': - start = dec.cursor - dec.cursor++ - start, end, err = dec.getString() - start-- - dec.cursor = end - return - // is array - case '[': - start = dec.cursor - dec.cursor++ - end, err = dec.skipArray() - dec.cursor = end - return - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': - start = dec.cursor - end, err = dec.skipNumber() - dec.cursor = end - return - default: - err = dec.raiseInvalidJSONErr(dec.cursor) - return - } - } - err = dec.raiseInvalidJSONErr(dec.cursor) - return -} - -// Add Values functions - -// AddInterface decodes the JSON value within an object or an array to a interface{}. -func (dec *Decoder) AddInterface(v *interface{}) error { - return dec.Interface(v) -} - -// Interface decodes the JSON value within an object or an array to an interface{}. -func (dec *Decoder) Interface(value *interface{}) error { - err := dec.decodeInterface(value) - if err != nil { - return err - } - dec.called |= 1 - return nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number.go deleted file mode 100644 index 0042b471e..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number.go +++ /dev/null @@ -1,118 +0,0 @@ -package gojay - -import ( - "math" -) - -var digits []int8 - -const maxInt64toMultiply = math.MaxInt64 / 10 -const maxInt32toMultiply = math.MaxInt32 / 10 -const maxInt16toMultiply = math.MaxInt16 / 10 -const maxInt8toMultiply = math.MaxInt8 / 10 -const maxUint8toMultiply = math.MaxUint8 / 10 -const maxUint16toMultiply = math.MaxUint16 / 10 -const maxUint32toMultiply = math.MaxUint32 / 10 -const maxUint64toMultiply = math.MaxUint64 / 10 -const maxUint32Length = 10 -const maxUint64Length = 20 -const maxUint16Length = 5 -const maxUint8Length = 3 -const maxInt32Length = 10 -const maxInt64Length = 19 -const maxInt16Length = 5 -const maxInt8Length = 3 -const invalidNumber = int8(-1) - -var pow10uint64 = [21]uint64{ - 0, - 1, - 10, - 100, - 1000, - 10000, - 100000, - 1000000, - 10000000, - 100000000, - 1000000000, - 10000000000, - 100000000000, - 1000000000000, - 10000000000000, - 100000000000000, - 1000000000000000, - 10000000000000000, - 100000000000000000, - 1000000000000000000, - 10000000000000000000, -} - -var skipNumberEndCursorIncrement [256]int - -func init() { - digits = make([]int8, 256) - for i := 0; i < len(digits); i++ { - digits[i] = invalidNumber - } - for i := int8('0'); i <= int8('9'); i++ { - digits[i] = i - int8('0') - } - - for i := 0; i < 256; i++ { - switch i { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'e', 'E', '+', '-': - skipNumberEndCursorIncrement[i] = 1 - } - } -} - -func (dec *Decoder) skipNumber() (int, error) { - end := dec.cursor + 1 - // look for following numbers - for j := dec.cursor + 1; j < dec.length || dec.read(); j++ { - end += skipNumberEndCursorIncrement[dec.data[j]] - - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'e', 'E', '+', '-', ' ', '\n', '\t', '\r': - continue - case ',', '}', ']': - return end, nil - default: - // invalid json we expect numbers, dot (single one), comma, or spaces - return end, dec.raiseInvalidJSONErr(dec.cursor) - } - } - - return end, nil -} - -func (dec *Decoder) getExponent() (int64, error) { - start := dec.cursor - end := dec.cursor - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { // is positive - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - end = dec.cursor + 1 - case '-': - dec.cursor++ - exp, err := dec.getExponent() - return -exp, err - case '+': - dec.cursor++ - return dec.getExponent() - default: - // if nothing return 0 - // could raise error - if start == end { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - return dec.atoi64(start, end-1), nil - } - } - if start == end { - - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - return dec.atoi64(start, end-1), nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number_float.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number_float.go deleted file mode 100644 index f76c5861e..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number_float.go +++ /dev/null @@ -1,516 +0,0 @@ -package gojay - -// DecodeFloat64 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the float64 pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeFloat64(v *float64) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeFloat64(v) -} -func (dec *Decoder) decodeFloat64(v *float64) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getFloat() - if err != nil { - return err - } - *v = val - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getFloatNegative() - if err != nil { - return err - } - *v = -val - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} -func (dec *Decoder) decodeFloat64Null(v **float64) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getFloat() - if err != nil { - return err - } - if *v == nil { - *v = new(float64) - } - **v = val - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getFloatNegative() - if err != nil { - return err - } - if *v == nil { - *v = new(float64) - } - **v = -val - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getFloatNegative() (float64, error) { - // look for following numbers - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - return dec.getFloat() - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getFloat() (float64, error) { - var end = dec.cursor - var start = dec.cursor - // look for following numbers - for j := dec.cursor + 1; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - end = j - continue - case '.': - // we get part before decimal as integer - beforeDecimal := dec.atoi64(start, end) - // then we get part after decimal as integer - start = j + 1 - // get number after the decimal point - for i := j + 1; i < dec.length || dec.read(); i++ { - c := dec.data[i] - if isDigit(c) { - end = i - // multiply the before decimal point portion by 10 using bitwise - // make sure it doesn't overflow - if end-start < 18 { - beforeDecimal = (beforeDecimal << 3) + (beforeDecimal << 1) - } - continue - } else if (c == 'e' || c == 'E') && j < i-1 { - // we have an exponent, convert first the value we got before the exponent - var afterDecimal int64 - expI := end - start + 2 - // if exp is too long, it means number is too long, just truncate the number - if expI >= len(pow10uint64) || expI < 0 { - expI = len(pow10uint64) - 2 - afterDecimal = dec.atoi64(start, start+expI-2) - } else { - // then we add both integers - // then we divide the number by the power found - afterDecimal = dec.atoi64(start, end) - } - dec.cursor = i + 1 - pow := pow10uint64[expI] - floatVal := float64(beforeDecimal+afterDecimal) / float64(pow) - exp, err := dec.getExponent() - if err != nil { - return 0, err - } - pExp := (exp + (exp >> 31)) ^ (exp >> 31) + 1 // absolute exponent - if pExp >= int64(len(pow10uint64)) || pExp < 0 { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - // if exponent is negative - if exp < 0 { - return float64(floatVal) * (1 / float64(pow10uint64[pExp])), nil - } - return float64(floatVal) * float64(pow10uint64[pExp]), nil - } - dec.cursor = i - break - } - if end >= dec.length || end < start { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - var afterDecimal int64 - expI := end - start + 2 - // if exp is too long, it means number is too long, just truncate the number - if expI >= len(pow10uint64) || expI < 0 { - expI = 19 - afterDecimal = dec.atoi64(start, start+expI-2) - } else { - afterDecimal = dec.atoi64(start, end) - } - - pow := pow10uint64[expI] - // then we add both integers - // then we divide the number by the power found - return float64(beforeDecimal+afterDecimal) / float64(pow), nil - case 'e', 'E': - dec.cursor = j + 1 - // we get part before decimal as integer - beforeDecimal := uint64(dec.atoi64(start, end)) - // get exponent - exp, err := dec.getExponent() - if err != nil { - return 0, err - } - pExp := (exp + (exp >> 31)) ^ (exp >> 31) + 1 // abs - if pExp >= int64(len(pow10uint64)) || pExp < 0 { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - // if exponent is negative - if exp < 0 { - return float64(beforeDecimal) * (1 / float64(pow10uint64[pExp])), nil - } - return float64(beforeDecimal) * float64(pow10uint64[pExp]), nil - case ' ', '\n', '\t', '\r', ',', '}', ']': // does not have decimal - dec.cursor = j - return float64(dec.atoi64(start, end)), nil - } - // invalid json we expect numbers, dot (single one), comma, or spaces - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - return float64(dec.atoi64(start, end)), nil -} - -// DecodeFloat32 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the float32 pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeFloat32(v *float32) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeFloat32(v) -} -func (dec *Decoder) decodeFloat32(v *float32) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getFloat32() - if err != nil { - return err - } - *v = val - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getFloat32Negative() - if err != nil { - return err - } - *v = -val - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} -func (dec *Decoder) decodeFloat32Null(v **float32) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getFloat32() - if err != nil { - return err - } - if *v == nil { - *v = new(float32) - } - **v = val - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getFloat32Negative() - if err != nil { - return err - } - if *v == nil { - *v = new(float32) - } - **v = -val - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getFloat32Negative() (float32, error) { - // look for following numbers - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - return dec.getFloat32() - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getFloat32() (float32, error) { - var end = dec.cursor - var start = dec.cursor - // look for following numbers - for j := dec.cursor + 1; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - end = j - continue - case '.': - // we get part before decimal as integer - beforeDecimal := dec.atoi64(start, end) - // then we get part after decimal as integer - start = j + 1 - // get number after the decimal point - // multiple the before decimal point portion by 10 using bitwise - for i := j + 1; i < dec.length || dec.read(); i++ { - c := dec.data[i] - if isDigit(c) { - end = i - // multiply the before decimal point portion by 10 using bitwise - // make sure it desn't overflow - if end-start < 9 { - beforeDecimal = (beforeDecimal << 3) + (beforeDecimal << 1) - } - continue - } else if (c == 'e' || c == 'E') && j < i-1 { - // we get the number before decimal - var afterDecimal int64 - expI := end - start + 2 - // if exp is too long, it means number is too long, just truncate the number - if expI >= 12 || expI < 0 { - expI = 10 - afterDecimal = dec.atoi64(start, start+expI-2) - } else { - afterDecimal = dec.atoi64(start, end) - } - dec.cursor = i + 1 - pow := pow10uint64[expI] - // then we add both integers - // then we divide the number by the power found - floatVal := float32(beforeDecimal+afterDecimal) / float32(pow) - exp, err := dec.getExponent() - if err != nil { - return 0, err - } - pExp := (exp + (exp >> 31)) ^ (exp >> 31) + 1 // abs - if pExp >= int64(len(pow10uint64)) || pExp < 0 { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - // if exponent is negative - if exp < 0 { - return float32(floatVal) * (1 / float32(pow10uint64[pExp])), nil - } - return float32(floatVal) * float32(pow10uint64[pExp]), nil - } - dec.cursor = i - break - } - if end >= dec.length || end < start { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - // then we add both integers - // then we divide the number by the power found - var afterDecimal int64 - expI := end - start + 2 - // if exp is too long, it means number is too long, just truncate the number - if expI >= 12 || expI < 0 { - expI = 10 - afterDecimal = dec.atoi64(start, start+expI-2) - } else { - // then we add both integers - // then we divide the number by the power found - afterDecimal = dec.atoi64(start, end) - } - pow := pow10uint64[expI] - return float32(beforeDecimal+afterDecimal) / float32(pow), nil - case 'e', 'E': - dec.cursor = j + 1 - // we get part before decimal as integer - beforeDecimal := dec.atoi64(start, end) - // get exponent - exp, err := dec.getExponent() - if err != nil { - return 0, err - } - pExp := (exp + (exp >> 31)) ^ (exp >> 31) + 1 - if pExp >= int64(len(pow10uint64)) || pExp < 0 { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - // if exponent is negative - if exp < 0 { - return float32(beforeDecimal) * (1 / float32(pow10uint64[pExp])), nil - } - return float32(beforeDecimal) * float32(pow10uint64[pExp]), nil - case ' ', '\n', '\t', '\r', ',', '}', ']': // does not have decimal - dec.cursor = j - return float32(dec.atoi64(start, end)), nil - } - // invalid json we expect numbers, dot (single one), comma, or spaces - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - return float32(dec.atoi64(start, end)), nil -} - -// Add Values functions - -// AddFloat decodes the JSON value within an object or an array to a *float64. -// If next key value overflows float64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) AddFloat(v *float64) error { - return dec.Float64(v) -} - -// AddFloatNull decodes the JSON value within an object or an array to a *float64. -// If next key value overflows float64, an InvalidUnmarshalError error will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddFloatNull(v **float64) error { - return dec.Float64Null(v) -} - -// AddFloat64 decodes the JSON value within an object or an array to a *float64. -// If next key value overflows float64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) AddFloat64(v *float64) error { - return dec.Float64(v) -} - -// AddFloat64Null decodes the JSON value within an object or an array to a *float64. -// If next key value overflows float64, an InvalidUnmarshalError error will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddFloat64Null(v **float64) error { - return dec.Float64Null(v) -} - -// AddFloat32 decodes the JSON value within an object or an array to a *float64. -// If next key value overflows float64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) AddFloat32(v *float32) error { - return dec.Float32(v) -} - -// AddFloat32Null decodes the JSON value within an object or an array to a *float64. -// If next key value overflows float64, an InvalidUnmarshalError error will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddFloat32Null(v **float32) error { - return dec.Float32Null(v) -} - -// Float decodes the JSON value within an object or an array to a *float64. -// If next key value overflows float64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Float(v *float64) error { - return dec.Float64(v) -} - -// FloatNull decodes the JSON value within an object or an array to a *float64. -// If next key value overflows float64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) FloatNull(v **float64) error { - return dec.Float64Null(v) -} - -// Float64 decodes the JSON value within an object or an array to a *float64. -// If next key value overflows float64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Float64(v *float64) error { - err := dec.decodeFloat64(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Float64Null decodes the JSON value within an object or an array to a *float64. -// If next key value overflows float64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Float64Null(v **float64) error { - err := dec.decodeFloat64Null(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Float32 decodes the JSON value within an object or an array to a *float64. -// If next key value overflows float64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Float32(v *float32) error { - err := dec.decodeFloat32(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Float32Null decodes the JSON value within an object or an array to a *float64. -// If next key value overflows float64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Float32Null(v **float32) error { - err := dec.decodeFloat32Null(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number_int.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number_int.go deleted file mode 100644 index 8429049fb..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number_int.go +++ /dev/null @@ -1,1338 +0,0 @@ -package gojay - -import ( - "fmt" - "math" -) - -// DecodeInt reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the int pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeInt(v *int) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeInt(v) -} -func (dec *Decoder) decodeInt(v *int) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - // we don't look for 0 as leading zeros are invalid per RFC - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt64() - if err != nil { - return err - } - *v = int(val) - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getInt64Negative() - if err != nil { - return err - } - *v = -int(val) - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = InvalidUnmarshalError( - fmt.Sprintf( - "Cannot unmarshall to int, wrong char '%s' found at pos %d", - string(dec.data[dec.cursor]), - dec.cursor, - ), - ) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) decodeIntNull(v **int) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - // we don't look for 0 as leading zeros are invalid per RFC - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt64() - if err != nil { - return err - } - if *v == nil { - *v = new(int) - } - **v = int(val) - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getInt64Negative() - if err != nil { - return err - } - if *v == nil { - *v = new(int) - } - **v = -int(val) - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = InvalidUnmarshalError( - fmt.Sprintf( - "Cannot unmarshall to int, wrong char '%s' found at pos %d", - string(dec.data[dec.cursor]), - dec.cursor, - ), - ) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -// DecodeInt16 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the int16 pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeInt16(v *int16) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeInt16(v) -} -func (dec *Decoder) decodeInt16(v *int16) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - // we don't look for 0 as leading zeros are invalid per RFC - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt16() - if err != nil { - return err - } - *v = val - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getInt16Negative() - if err != nil { - return err - } - *v = -val - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} -func (dec *Decoder) decodeInt16Null(v **int16) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - // we don't look for 0 as leading zeros are invalid per RFC - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt16() - if err != nil { - return err - } - if *v == nil { - *v = new(int16) - } - **v = val - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getInt16Negative() - if err != nil { - return err - } - if *v == nil { - *v = new(int16) - } - **v = -val - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getInt16Negative() (int16, error) { - // look for following numbers - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '1', '2', '3', '4', '5', '6', '7', '8', '9': - return dec.getInt16() - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getInt16() (int16, error) { - var end = dec.cursor - var start = dec.cursor - // look for following numbers - for j := dec.cursor + 1; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - end = j - continue - case '.': - // if dot is found - // look for exponent (e,E) as exponent can change the - // way number should be parsed to int. - // if no exponent found, just unmarshal the number before decimal point - j++ - startDecimal := j - endDecimal := j - 1 - for ; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - endDecimal = j - continue - case 'e', 'E': - if startDecimal > endDecimal { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - dec.cursor = j + 1 - // can try unmarshalling to int as Exponent might change decimal number to non decimal - // let's get the float value first - // we get part before decimal as integer - beforeDecimal := dec.atoi16(start, end) - // get number after the decimal point - // multiple the before decimal point portion by 10 using bitwise - for i := startDecimal; i <= endDecimal; i++ { - beforeDecimal = (beforeDecimal << 3) + (beforeDecimal << 1) - } - // then we add both integers - // then we divide the number by the power found - afterDecimal := dec.atoi16(startDecimal, endDecimal) - expI := endDecimal - startDecimal + 2 - if expI >= len(pow10uint64) || expI < 0 { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - pow := pow10uint64[expI] - floatVal := float64(beforeDecimal+afterDecimal) / float64(pow) - // we have the floating value, now multiply by the exponent - exp, err := dec.getExponent() - if err != nil { - return 0, err - } - pExp := (exp + (exp >> 31)) ^ (exp >> 31) + 1 // abs - if pExp >= int64(len(pow10uint64)) || pExp < 0 { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - val := floatVal * float64(pow10uint64[pExp]) - return int16(val), nil - case ' ', '\t', '\n', ',', ']', '}': - dec.cursor = j - return dec.atoi16(start, end), nil - default: - dec.cursor = j - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return dec.atoi16(start, end), nil - case 'e', 'E': - // get init n - dec.cursor = j + 1 - return dec.getInt16WithExp(dec.atoi16(start, end)) - case ' ', '\n', '\t', '\r', ',', '}', ']': - dec.cursor = j - return dec.atoi16(start, end), nil - } - // invalid json we expect numbers, dot (single one), comma, or spaces - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - return dec.atoi16(start, end), nil -} - -func (dec *Decoder) getInt16WithExp(init int16) (int16, error) { - var exp uint16 - var sign = int16(1) - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '+': - continue - case '-': - sign = -1 - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint16(digits[dec.data[dec.cursor]]) - exp = (exp << 3) + (exp << 1) + uintv - dec.cursor++ - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint16(digits[dec.data[dec.cursor]]) - exp = (exp << 3) + (exp << 1) + uintv - case ' ', '\t', '\n', '}', ',', ']': - exp = exp + 1 - if exp >= uint16(len(pow10uint64)) { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - if sign == -1 { - return init * (1 / int16(pow10uint64[exp])), nil - } - return init * int16(pow10uint64[exp]), nil - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - exp = exp + 1 - if exp >= uint16(len(pow10uint64)) { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - if sign == -1 { - return init * (1 / int16(pow10uint64[exp])), nil - } - return init * int16(pow10uint64[exp]), nil - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -// DecodeInt8 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the int8 pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeInt8(v *int8) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeInt8(v) -} -func (dec *Decoder) decodeInt8(v *int8) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - // we don't look for 0 as leading zeros are invalid per RFC - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt8() - if err != nil { - return err - } - *v = val - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getInt8Negative() - if err != nil { - return err - } - *v = -val - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} -func (dec *Decoder) decodeInt8Null(v **int8) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - // we don't look for 0 as leading zeros are invalid per RFC - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt8() - if err != nil { - return err - } - if *v == nil { - *v = new(int8) - } - **v = val - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getInt8Negative() - if err != nil { - return err - } - if *v == nil { - *v = new(int8) - } - **v = -val - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getInt8Negative() (int8, error) { - // look for following numbers - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '1', '2', '3', '4', '5', '6', '7', '8', '9': - return dec.getInt8() - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getInt8() (int8, error) { - var end = dec.cursor - var start = dec.cursor - // look for following numbers - for j := dec.cursor + 1; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - end = j - continue - case '.': - // if dot is found - // look for exponent (e,E) as exponent can change the - // way number should be parsed to int. - // if no exponent found, just unmarshal the number before decimal point - j++ - startDecimal := j - endDecimal := j - 1 - for ; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - endDecimal = j - continue - case 'e', 'E': - if startDecimal > endDecimal { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - dec.cursor = j + 1 - // can try unmarshalling to int as Exponent might change decimal number to non decimal - // let's get the float value first - // we get part before decimal as integer - beforeDecimal := dec.atoi8(start, end) - // get number after the decimal point - // multiple the before decimal point portion by 10 using bitwise - for i := startDecimal; i <= endDecimal; i++ { - beforeDecimal = (beforeDecimal << 3) + (beforeDecimal << 1) - } - // then we add both integers - // then we divide the number by the power found - afterDecimal := dec.atoi8(startDecimal, endDecimal) - expI := endDecimal - startDecimal + 2 - if expI >= len(pow10uint64) || expI < 0 { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - pow := pow10uint64[expI] - floatVal := float64(beforeDecimal+afterDecimal) / float64(pow) - // we have the floating value, now multiply by the exponent - exp, err := dec.getExponent() - if err != nil { - return 0, err - } - pExp := (exp + (exp >> 31)) ^ (exp >> 31) + 1 // abs - if pExp >= int64(len(pow10uint64)) || pExp < 0 { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - val := floatVal * float64(pow10uint64[pExp]) - return int8(val), nil - case ' ', '\t', '\n', ',', ']', '}': - dec.cursor = j - return dec.atoi8(start, end), nil - default: - dec.cursor = j - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return dec.atoi8(start, end), nil - case 'e', 'E': - // get init n - dec.cursor = j + 1 - return dec.getInt8WithExp(dec.atoi8(start, end)) - case ' ', '\n', '\t', '\r', ',', '}', ']': - dec.cursor = j - return dec.atoi8(start, end), nil - } - // invalid json we expect numbers, dot (single one), comma, or spaces - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - return dec.atoi8(start, end), nil -} - -func (dec *Decoder) getInt8WithExp(init int8) (int8, error) { - var exp uint8 - var sign = int8(1) - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '+': - continue - case '-': - sign = -1 - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint8(digits[dec.data[dec.cursor]]) - exp = (exp << 3) + (exp << 1) + uintv - dec.cursor++ - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint8(digits[dec.data[dec.cursor]]) - exp = (exp << 3) + (exp << 1) + uintv - case ' ', '\t', '\n', '}', ',', ']': - if exp+1 >= uint8(len(pow10uint64)) { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - if sign == -1 { - return init * (1 / int8(pow10uint64[exp+1])), nil - } - return init * int8(pow10uint64[exp+1]), nil - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - if exp+1 >= uint8(len(pow10uint64)) { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - if sign == -1 { - return init * (1 / int8(pow10uint64[exp+1])), nil - } - return init * int8(pow10uint64[exp+1]), nil - default: - dec.err = dec.raiseInvalidJSONErr(dec.cursor) - return 0, dec.err - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -// DecodeInt32 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the int32 pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeInt32(v *int32) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeInt32(v) -} -func (dec *Decoder) decodeInt32(v *int32) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt32() - if err != nil { - return err - } - *v = val - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getInt32Negative() - if err != nil { - return err - } - *v = -val - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} -func (dec *Decoder) decodeInt32Null(v **int32) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt32() - if err != nil { - return err - } - if *v == nil { - *v = new(int32) - } - **v = val - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getInt32Negative() - if err != nil { - return err - } - if *v == nil { - *v = new(int32) - } - **v = -val - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getInt32Negative() (int32, error) { - // look for following numbers - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '1', '2', '3', '4', '5', '6', '7', '8', '9': - return dec.getInt32() - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getInt32() (int32, error) { - var end = dec.cursor - var start = dec.cursor - // look for following numbers - for j := dec.cursor + 1; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - end = j - continue - case '.': - // if dot is found - // look for exponent (e,E) as exponent can change the - // way number should be parsed to int. - // if no exponent found, just unmarshal the number before decimal point - j++ - startDecimal := j - endDecimal := j - 1 - for ; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - endDecimal = j - continue - case 'e', 'E': - // if eg 1.E - if startDecimal > endDecimal { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - dec.cursor = j + 1 - // can try unmarshalling to int as Exponent might change decimal number to non decimal - // let's get the float value first - // we get part before decimal as integer - beforeDecimal := dec.atoi64(start, end) - // get number after the decimal point - // multiple the before decimal point portion by 10 using bitwise - for i := startDecimal; i <= endDecimal; i++ { - beforeDecimal = (beforeDecimal << 3) + (beforeDecimal << 1) - } - // then we add both integers - // then we divide the number by the power found - afterDecimal := dec.atoi64(startDecimal, endDecimal) - expI := endDecimal - startDecimal + 2 - if expI >= len(pow10uint64) || expI < 0 { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - pow := pow10uint64[expI] - floatVal := float64(beforeDecimal+afterDecimal) / float64(pow) - // we have the floating value, now multiply by the exponent - exp, err := dec.getExponent() - if err != nil { - return 0, err - } - pExp := (exp + (exp >> 31)) ^ (exp >> 31) + 1 // abs - if pExp >= int64(len(pow10uint64)) || pExp < 0 { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - val := floatVal * float64(pow10uint64[pExp]) - return int32(val), nil - case ' ', '\t', '\n', ',', ']', '}': - dec.cursor = j - return dec.atoi32(start, end), nil - default: - dec.cursor = j - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return dec.atoi32(start, end), nil - case 'e', 'E': - // get init n - dec.cursor = j + 1 - return dec.getInt32WithExp(dec.atoi32(start, end)) - case ' ', '\n', '\t', '\r', ',', '}', ']': - dec.cursor = j - return dec.atoi32(start, end), nil - } - // invalid json we expect numbers, dot (single one), comma, or spaces - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - return dec.atoi32(start, end), nil -} - -func (dec *Decoder) getInt32WithExp(init int32) (int32, error) { - var exp uint32 - var sign = int32(1) - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '+': - continue - case '-': - sign = -1 - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint32(digits[dec.data[dec.cursor]]) - exp = (exp << 3) + (exp << 1) + uintv - dec.cursor++ - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint32(digits[dec.data[dec.cursor]]) - exp = (exp << 3) + (exp << 1) + uintv - case ' ', '\t', '\n', '}', ',', ']': - if exp+1 >= uint32(len(pow10uint64)) { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - if sign == -1 { - return init * (1 / int32(pow10uint64[exp+1])), nil - } - return init * int32(pow10uint64[exp+1]), nil - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - if exp+1 >= uint32(len(pow10uint64)) { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - if sign == -1 { - return init * (1 / int32(pow10uint64[exp+1])), nil - } - return init * int32(pow10uint64[exp+1]), nil - default: - dec.err = dec.raiseInvalidJSONErr(dec.cursor) - return 0, dec.err - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -// DecodeInt64 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the int64 pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeInt64(v *int64) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeInt64(v) -} - -func (dec *Decoder) decodeInt64(v *int64) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt64() - if err != nil { - return err - } - *v = val - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getInt64Negative() - if err != nil { - return err - } - *v = -val - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} -func (dec *Decoder) decodeInt64Null(v **int64) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getInt64() - if err != nil { - return err - } - if *v == nil { - *v = new(int64) - } - **v = val - return nil - case '-': - dec.cursor = dec.cursor + 1 - val, err := dec.getInt64Negative() - if err != nil { - return err - } - if *v == nil { - *v = new(int64) - } - **v = -val - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getInt64Negative() (int64, error) { - // look for following numbers - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '1', '2', '3', '4', '5', '6', '7', '8', '9': - return dec.getInt64() - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getInt64() (int64, error) { - var end = dec.cursor - var start = dec.cursor - // look for following numbers - for j := dec.cursor + 1; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - end = j - continue - case ' ', '\t', '\n', ',', '}', ']': - dec.cursor = j - return dec.atoi64(start, end), nil - case '.': - // if dot is found - // look for exponent (e,E) as exponent can change the - // way number should be parsed to int. - // if no exponent found, just unmarshal the number before decimal point - j++ - startDecimal := j - endDecimal := j - 1 - for ; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - endDecimal = j - continue - case 'e', 'E': - // if eg 1.E - if startDecimal > endDecimal { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - dec.cursor = j + 1 - // can try unmarshalling to int as Exponent might change decimal number to non decimal - // let's get the float value first - // we get part before decimal as integer - beforeDecimal := dec.atoi64(start, end) - // get number after the decimal point - // multiple the before decimal point portion by 10 using bitwise - for i := startDecimal; i <= endDecimal; i++ { - beforeDecimal = (beforeDecimal << 3) + (beforeDecimal << 1) - } - // then we add both integers - // then we divide the number by the power found - afterDecimal := dec.atoi64(startDecimal, endDecimal) - expI := endDecimal - startDecimal + 2 - if expI >= len(pow10uint64) || expI < 0 { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - pow := pow10uint64[expI] - floatVal := float64(beforeDecimal+afterDecimal) / float64(pow) - // we have the floating value, now multiply by the exponent - exp, err := dec.getExponent() - if err != nil { - return 0, err - } - pExp := (exp + (exp >> 31)) ^ (exp >> 31) + 1 // abs - if pExp >= int64(len(pow10uint64)) || pExp < 0 { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - val := floatVal * float64(pow10uint64[pExp]) - return int64(val), nil - case ' ', '\t', '\n', ',', ']', '}': - dec.cursor = j - return dec.atoi64(start, end), nil - default: - dec.cursor = j - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return dec.atoi64(start, end), nil - case 'e', 'E': - // get init n - dec.cursor = j + 1 - return dec.getInt64WithExp(dec.atoi64(start, end)) - } - // invalid json we expect numbers, dot (single one), comma, or spaces - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - return dec.atoi64(start, end), nil -} - -func (dec *Decoder) getInt64WithExp(init int64) (int64, error) { - var exp uint64 - var sign = int64(1) - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '+': - continue - case '-': - sign = -1 - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint64(digits[dec.data[dec.cursor]]) - exp = (exp << 3) + (exp << 1) + uintv - dec.cursor++ - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - uintv := uint64(digits[dec.data[dec.cursor]]) - exp = (exp << 3) + (exp << 1) + uintv - case ' ', '\t', '\n', '}', ',', ']': - if exp+1 >= uint64(len(pow10uint64)) { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - if sign == -1 { - return init * (1 / int64(pow10uint64[exp+1])), nil - } - return init * int64(pow10uint64[exp+1]), nil - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - if exp+1 >= uint64(len(pow10uint64)) { - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - if sign == -1 { - return init * (1 / int64(pow10uint64[exp+1])), nil - } - return init * int64(pow10uint64[exp+1]), nil - default: - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) atoi64(start, end int) int64 { - var ll = end + 1 - start - var val = int64(digits[dec.data[start]]) - end = end + 1 - if ll < maxInt64Length { - for i := start + 1; i < end; i++ { - intv := int64(digits[dec.data[i]]) - val = (val << 3) + (val << 1) + intv - } - return val - } else if ll == maxInt64Length { - for i := start + 1; i < end; i++ { - intv := int64(digits[dec.data[i]]) - if val > maxInt64toMultiply { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val = (val << 3) + (val << 1) - if math.MaxInt64-val < intv { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val += intv - } - } else { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - return val -} - -func (dec *Decoder) atoi32(start, end int) int32 { - var ll = end + 1 - start - var val = int32(digits[dec.data[start]]) - end = end + 1 - - // overflowing - if ll < maxInt32Length { - for i := start + 1; i < end; i++ { - intv := int32(digits[dec.data[i]]) - val = (val << 3) + (val << 1) + intv - } - } else if ll == maxInt32Length { - for i := start + 1; i < end; i++ { - intv := int32(digits[dec.data[i]]) - if val > maxInt32toMultiply { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val = (val << 3) + (val << 1) - if math.MaxInt32-val < intv { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val += intv - } - } else { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - return val -} - -func (dec *Decoder) atoi16(start, end int) int16 { - var ll = end + 1 - start - var val = int16(digits[dec.data[start]]) - end = end + 1 - // overflowing - if ll < maxInt16Length { - for i := start + 1; i < end; i++ { - intv := int16(digits[dec.data[i]]) - val = (val << 3) + (val << 1) + intv - } - } else if ll == maxInt16Length { - for i := start + 1; i < end; i++ { - intv := int16(digits[dec.data[i]]) - if val > maxInt16toMultiply { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val = (val << 3) + (val << 1) - if math.MaxInt16-val < intv { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val += intv - } - } else { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - return val -} - -func (dec *Decoder) atoi8(start, end int) int8 { - var ll = end + 1 - start - var val = int8(digits[dec.data[start]]) - end = end + 1 - // overflowing - if ll < maxInt8Length { - for i := start + 1; i < end; i++ { - intv := int8(digits[dec.data[i]]) - val = (val << 3) + (val << 1) + intv - } - } else if ll == maxInt8Length { - for i := start + 1; i < end; i++ { - intv := int8(digits[dec.data[i]]) - if val > maxInt8toMultiply { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val = (val << 3) + (val << 1) - if math.MaxInt8-val < intv { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val += intv - } - } else { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - return val -} - -// Add Values functions - -// AddInt decodes the JSON value within an object or an array to an *int. -// If next key value overflows int, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) AddInt(v *int) error { - return dec.Int(v) -} - -// AddIntNull decodes the JSON value within an object or an array to an *int. -// If next key value overflows int, an InvalidUnmarshalError error will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddIntNull(v **int) error { - return dec.IntNull(v) -} - -// AddInt8 decodes the JSON value within an object or an array to an *int. -// If next key value overflows int8, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) AddInt8(v *int8) error { - return dec.Int8(v) -} - -// AddInt8Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows int8, an InvalidUnmarshalError error will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddInt8Null(v **int8) error { - return dec.Int8Null(v) -} - -// AddInt16 decodes the JSON value within an object or an array to an *int. -// If next key value overflows int16, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) AddInt16(v *int16) error { - return dec.Int16(v) -} - -// AddInt16Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows int16, an InvalidUnmarshalError error will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddInt16Null(v **int16) error { - return dec.Int16Null(v) -} - -// AddInt32 decodes the JSON value within an object or an array to an *int. -// If next key value overflows int32, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) AddInt32(v *int32) error { - return dec.Int32(v) -} - -// AddInt32Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows int32, an InvalidUnmarshalError error will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddInt32Null(v **int32) error { - return dec.Int32Null(v) -} - -// AddInt64 decodes the JSON value within an object or an array to an *int. -// If next key value overflows int64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) AddInt64(v *int64) error { - return dec.Int64(v) -} - -// AddInt64Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows int64, an InvalidUnmarshalError error will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddInt64Null(v **int64) error { - return dec.Int64Null(v) -} - -// Int decodes the JSON value within an object or an array to an *int. -// If next key value overflows int, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Int(v *int) error { - err := dec.decodeInt(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// IntNull decodes the JSON value within an object or an array to an *int. -// If next key value overflows int, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) IntNull(v **int) error { - err := dec.decodeIntNull(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Int8 decodes the JSON value within an object or an array to an *int. -// If next key value overflows int8, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Int8(v *int8) error { - err := dec.decodeInt8(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Int8Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows int8, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Int8Null(v **int8) error { - err := dec.decodeInt8Null(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Int16 decodes the JSON value within an object or an array to an *int. -// If next key value overflows int16, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Int16(v *int16) error { - err := dec.decodeInt16(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Int16Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows int16, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Int16Null(v **int16) error { - err := dec.decodeInt16Null(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Int32 decodes the JSON value within an object or an array to an *int. -// If next key value overflows int32, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Int32(v *int32) error { - err := dec.decodeInt32(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Int32Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows int32, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Int32Null(v **int32) error { - err := dec.decodeInt32Null(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Int64 decodes the JSON value within an object or an array to an *int. -// If next key value overflows int64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Int64(v *int64) error { - err := dec.decodeInt64(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Int64Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows int64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Int64Null(v **int64) error { - err := dec.decodeInt64Null(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number_uint.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number_uint.go deleted file mode 100644 index b57ef7ab6..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_number_uint.go +++ /dev/null @@ -1,715 +0,0 @@ -package gojay - -import ( - "math" -) - -// DecodeUint8 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the uint8 pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeUint8(v *uint8) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeUint8(v) -} - -func (dec *Decoder) decodeUint8(v *uint8) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getUint8() - if err != nil { - return err - } - *v = val - return nil - case '-': // if negative, we just set it to 0 and set error - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} -func (dec *Decoder) decodeUint8Null(v **uint8) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getUint8() - if err != nil { - return err - } - if *v == nil { - *v = new(uint8) - } - **v = val - return nil - case '-': // if negative, we just set it to 0 and set error - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - if *v == nil { - *v = new(uint8) - } - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getUint8() (uint8, error) { - var end = dec.cursor - var start = dec.cursor - // look for following numbers - for j := dec.cursor + 1; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - end = j - continue - case ' ', '\n', '\t', '\r': - continue - case '.', ',', '}', ']': - dec.cursor = j - return dec.atoui8(start, end), nil - } - // invalid json we expect numbers, dot (single one), comma, or spaces - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - return dec.atoui8(start, end), nil -} - -// DecodeUint16 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the uint16 pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeUint16(v *uint16) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeUint16(v) -} - -func (dec *Decoder) decodeUint16(v *uint16) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getUint16() - if err != nil { - return err - } - *v = val - return nil - case '-': - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} -func (dec *Decoder) decodeUint16Null(v **uint16) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getUint16() - if err != nil { - return err - } - if *v == nil { - *v = new(uint16) - } - **v = val - return nil - case '-': - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - if *v == nil { - *v = new(uint16) - } - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getUint16() (uint16, error) { - var end = dec.cursor - var start = dec.cursor - // look for following numbers - for j := dec.cursor + 1; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - end = j - continue - case ' ', '\n', '\t', '\r': - continue - case '.', ',', '}', ']': - dec.cursor = j - return dec.atoui16(start, end), nil - } - // invalid json we expect numbers, dot (single one), comma, or spaces - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - return dec.atoui16(start, end), nil -} - -// DecodeUint32 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the uint32 pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeUint32(v *uint32) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeUint32(v) -} - -func (dec *Decoder) decodeUint32(v *uint32) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getUint32() - if err != nil { - return err - } - *v = val - return nil - case '-': - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} -func (dec *Decoder) decodeUint32Null(v **uint32) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getUint32() - if err != nil { - return err - } - if *v == nil { - *v = new(uint32) - } - **v = val - return nil - case '-': - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - if *v == nil { - *v = new(uint32) - } - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getUint32() (uint32, error) { - var end = dec.cursor - var start = dec.cursor - // look for following numbers - for j := dec.cursor + 1; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - end = j - continue - case ' ', '\n', '\t', '\r': - continue - case '.', ',', '}', ']': - dec.cursor = j - return dec.atoui32(start, end), nil - } - // invalid json we expect numbers, dot (single one), comma, or spaces - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - return dec.atoui32(start, end), nil -} - -// DecodeUint64 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the uint64 pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeUint64(v *uint64) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeUint64(v) -} -func (dec *Decoder) decodeUint64(v *uint64) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getUint64() - if err != nil { - return err - } - *v = val - return nil - case '-': - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} -func (dec *Decoder) decodeUint64Null(v **uint64) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch c := dec.data[dec.cursor]; c { - case ' ', '\n', '\t', '\r', ',': - continue - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, err := dec.getUint64() - if err != nil { - return err - } - if *v == nil { - *v = new(uint64) - } - **v = val - return nil - case '-': - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - if *v == nil { - *v = new(uint64) - } - return nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) getUint64() (uint64, error) { - var end = dec.cursor - var start = dec.cursor - // look for following numbers - for j := dec.cursor + 1; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - end = j - continue - case ' ', '\n', '\t', '\r', '.', ',', '}', ']': - dec.cursor = j - return dec.atoui64(start, end), nil - } - // invalid json we expect numbers, dot (single one), comma, or spaces - return 0, dec.raiseInvalidJSONErr(dec.cursor) - } - return dec.atoui64(start, end), nil -} - -func (dec *Decoder) atoui64(start, end int) uint64 { - var ll = end + 1 - start - var val = uint64(digits[dec.data[start]]) - end = end + 1 - if ll < maxUint64Length { - for i := start + 1; i < end; i++ { - uintv := uint64(digits[dec.data[i]]) - val = (val << 3) + (val << 1) + uintv - } - } else if ll == maxUint64Length { - for i := start + 1; i < end; i++ { - uintv := uint64(digits[dec.data[i]]) - if val > maxUint64toMultiply { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val = (val << 3) + (val << 1) - if math.MaxUint64-val < uintv { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val += uintv - } - } else { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - return val -} - -func (dec *Decoder) atoui32(start, end int) uint32 { - var ll = end + 1 - start - var val uint32 - val = uint32(digits[dec.data[start]]) - end = end + 1 - if ll < maxUint32Length { - for i := start + 1; i < end; i++ { - uintv := uint32(digits[dec.data[i]]) - val = (val << 3) + (val << 1) + uintv - } - } else if ll == maxUint32Length { - for i := start + 1; i < end; i++ { - uintv := uint32(digits[dec.data[i]]) - if val > maxUint32toMultiply { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val = (val << 3) + (val << 1) - if math.MaxUint32-val < uintv { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val += uintv - } - } else if ll > maxUint32Length { - dec.err = dec.makeInvalidUnmarshalErr(val) - val = 0 - } - return val -} - -func (dec *Decoder) atoui16(start, end int) uint16 { - var ll = end + 1 - start - var val uint16 - val = uint16(digits[dec.data[start]]) - end = end + 1 - if ll < maxUint16Length { - for i := start + 1; i < end; i++ { - uintv := uint16(digits[dec.data[i]]) - val = (val << 3) + (val << 1) + uintv - } - } else if ll == maxUint16Length { - for i := start + 1; i < end; i++ { - uintv := uint16(digits[dec.data[i]]) - if val > maxUint16toMultiply { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val = (val << 3) + (val << 1) - if math.MaxUint16-val < uintv { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val += uintv - } - } else if ll > maxUint16Length { - dec.err = dec.makeInvalidUnmarshalErr(val) - val = 0 - } - return val -} - -func (dec *Decoder) atoui8(start, end int) uint8 { - var ll = end + 1 - start - var val uint8 - val = uint8(digits[dec.data[start]]) - end = end + 1 - if ll < maxUint8Length { - for i := start + 1; i < end; i++ { - uintv := uint8(digits[dec.data[i]]) - val = (val << 3) + (val << 1) + uintv - } - } else if ll == maxUint8Length { - for i := start + 1; i < end; i++ { - uintv := uint8(digits[dec.data[i]]) - if val > maxUint8toMultiply { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val = (val << 3) + (val << 1) - if math.MaxUint8-val < uintv { - dec.err = dec.makeInvalidUnmarshalErr(val) - return 0 - } - val += uintv - } - } else if ll > maxUint8Length { - dec.err = dec.makeInvalidUnmarshalErr(val) - val = 0 - } - return val -} - -// Add Values functions - -// AddUint8 decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint8, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) AddUint8(v *uint8) error { - return dec.Uint8(v) -} - -// AddUint8Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint8, an InvalidUnmarshalError error will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddUint8Null(v **uint8) error { - return dec.Uint8Null(v) -} - -// AddUint16 decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint16, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) AddUint16(v *uint16) error { - return dec.Uint16(v) -} - -// AddUint16Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint16, an InvalidUnmarshalError error will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddUint16Null(v **uint16) error { - return dec.Uint16Null(v) -} - -// AddUint32 decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint32, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) AddUint32(v *uint32) error { - return dec.Uint32(v) -} - -// AddUint32Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint32, an InvalidUnmarshalError error will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddUint32Null(v **uint32) error { - return dec.Uint32Null(v) -} - -// AddUint64 decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) AddUint64(v *uint64) error { - return dec.Uint64(v) -} - -// AddUint64Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint64, an InvalidUnmarshalError error will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddUint64Null(v **uint64) error { - return dec.Uint64Null(v) -} - -// Uint8 decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint8, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Uint8(v *uint8) error { - err := dec.decodeUint8(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Uint8Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint8, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Uint8Null(v **uint8) error { - err := dec.decodeUint8Null(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Uint16 decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint16, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Uint16(v *uint16) error { - err := dec.decodeUint16(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Uint16Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint16, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Uint16Null(v **uint16) error { - err := dec.decodeUint16Null(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Uint32 decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint32, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Uint32(v *uint32) error { - err := dec.decodeUint32(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Uint32Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint32, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Uint32Null(v **uint32) error { - err := dec.decodeUint32Null(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Uint64 decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Uint64(v *uint64) error { - err := dec.decodeUint64(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// Uint64Null decodes the JSON value within an object or an array to an *int. -// If next key value overflows uint64, an InvalidUnmarshalError error will be returned. -func (dec *Decoder) Uint64Null(v **uint64) error { - err := dec.decodeUint64Null(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_object.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_object.go deleted file mode 100644 index 0fec9d24e..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_object.go +++ /dev/null @@ -1,407 +0,0 @@ -package gojay - -import ( - "reflect" - "unsafe" -) - -// DecodeObject reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by v. -// -// v must implement UnmarshalerJSONObject. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeObject(j UnmarshalerJSONObject) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - _, err := dec.decodeObject(j) - return err -} -func (dec *Decoder) decodeObject(j UnmarshalerJSONObject) (int, error) { - keys := j.NKeys() - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - case '{': - dec.cursor = dec.cursor + 1 - // if keys is zero we will parse all keys - // we run two loops for micro optimization - if keys == 0 { - for dec.cursor < dec.length || dec.read() { - k, done, err := dec.nextKey() - if err != nil { - return 0, err - } else if done { - return dec.cursor, nil - } - err = j.UnmarshalJSONObject(dec, k) - if err != nil { - dec.err = err - return 0, err - } else if dec.called&1 == 0 { - err := dec.skipData() - if err != nil { - return 0, err - } - } else { - dec.keysDone++ - } - dec.called &= 0 - } - } else { - for (dec.cursor < dec.length || dec.read()) && dec.keysDone < keys { - k, done, err := dec.nextKey() - if err != nil { - return 0, err - } else if done { - return dec.cursor, nil - } - err = j.UnmarshalJSONObject(dec, k) - if err != nil { - dec.err = err - return 0, err - } else if dec.called&1 == 0 { - err := dec.skipData() - if err != nil { - return 0, err - } - } else { - dec.keysDone++ - } - dec.called &= 0 - } - } - // will get to that point when keysDone is not lower than keys anymore - // in that case, we make sure cursor goes to the end of object, but we skip - // unmarshalling - if dec.child&1 != 0 { - end, err := dec.skipObject() - dec.cursor = end - return dec.cursor, err - } - return dec.cursor, nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return 0, err - } - return dec.cursor, nil - default: - // can't unmarshal to struct - dec.err = dec.makeInvalidUnmarshalErr(j) - err := dec.skipData() - if err != nil { - return 0, err - } - return dec.cursor, nil - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) decodeObjectNull(v interface{}) (int, error) { - // make sure the value is a pointer - vv := reflect.ValueOf(v) - vvt := vv.Type() - if vvt.Kind() != reflect.Ptr || vvt.Elem().Kind() != reflect.Ptr { - dec.err = ErrUnmarshalPtrExpected - return 0, dec.err - } - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - case '{': - elt := vv.Elem() - n := reflect.New(elt.Type().Elem()) - elt.Set(n) - var j UnmarshalerJSONObject - var ok bool - if j, ok = n.Interface().(UnmarshalerJSONObject); !ok { - dec.err = dec.makeInvalidUnmarshalErr((UnmarshalerJSONObject)(nil)) - return 0, dec.err - } - keys := j.NKeys() - dec.cursor = dec.cursor + 1 - // if keys is zero we will parse all keys - // we run two loops for micro optimization - if keys == 0 { - for dec.cursor < dec.length || dec.read() { - k, done, err := dec.nextKey() - if err != nil { - return 0, err - } else if done { - return dec.cursor, nil - } - err = j.UnmarshalJSONObject(dec, k) - if err != nil { - dec.err = err - return 0, err - } else if dec.called&1 == 0 { - err := dec.skipData() - if err != nil { - return 0, err - } - } else { - dec.keysDone++ - } - dec.called &= 0 - } - } else { - for (dec.cursor < dec.length || dec.read()) && dec.keysDone < keys { - k, done, err := dec.nextKey() - if err != nil { - return 0, err - } else if done { - return dec.cursor, nil - } - err = j.UnmarshalJSONObject(dec, k) - if err != nil { - dec.err = err - return 0, err - } else if dec.called&1 == 0 { - err := dec.skipData() - if err != nil { - return 0, err - } - } else { - dec.keysDone++ - } - dec.called &= 0 - } - } - // will get to that point when keysDone is not lower than keys anymore - // in that case, we make sure cursor goes to the end of object, but we skip - // unmarshalling - if dec.child&1 != 0 { - end, err := dec.skipObject() - dec.cursor = end - return dec.cursor, err - } - return dec.cursor, nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return 0, err - } - return dec.cursor, nil - default: - // can't unmarshal to struct - dec.err = dec.makeInvalidUnmarshalErr((UnmarshalerJSONObject)(nil)) - err := dec.skipData() - if err != nil { - return 0, err - } - return dec.cursor, nil - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) skipObject() (int, error) { - var objectsOpen = 1 - var objectsClosed = 0 - for j := dec.cursor; j < dec.length || dec.read(); j++ { - switch dec.data[j] { - case '}': - objectsClosed++ - // everything is closed return - if objectsOpen == objectsClosed { - // add char to object data - return j + 1, nil - } - case '{': - objectsOpen++ - case '"': - j++ - var isInEscapeSeq bool - var isFirstQuote = true - for ; j < dec.length || dec.read(); j++ { - if dec.data[j] != '"' { - continue - } - if dec.data[j-1] != '\\' || (!isInEscapeSeq && !isFirstQuote) { - break - } else { - isInEscapeSeq = false - } - if isFirstQuote { - isFirstQuote = false - } - // loop backward and count how many anti slash found - // to see if string is effectively escaped - ct := 0 - for i := j - 1; i > 0; i-- { - if dec.data[i] != '\\' { - break - } - ct++ - } - // is pair number of slashes, quote is not escaped - if ct&1 == 0 { - break - } - isInEscapeSeq = true - } - default: - continue - } - } - return 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) nextKey() (string, bool, error) { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - continue - case '"': - dec.cursor = dec.cursor + 1 - start, end, err := dec.getString() - if err != nil { - return "", false, err - } - var found byte - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - if dec.data[dec.cursor] == ':' { - found |= 1 - break - } - } - if found&1 != 0 { - dec.cursor++ - d := dec.data[start : end-1] - return *(*string)(unsafe.Pointer(&d)), false, nil - } - return "", false, dec.raiseInvalidJSONErr(dec.cursor) - case '}': - dec.cursor = dec.cursor + 1 - return "", true, nil - default: - // can't unmarshall to struct - return "", false, dec.raiseInvalidJSONErr(dec.cursor) - } - } - return "", false, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) skipData() error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - continue - // is null - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - case 't': - dec.cursor++ - err := dec.assertTrue() - if err != nil { - return err - } - return nil - // is false - case 'f': - dec.cursor++ - err := dec.assertFalse() - if err != nil { - return err - } - return nil - // is an object - case '{': - dec.cursor = dec.cursor + 1 - end, err := dec.skipObject() - dec.cursor = end - return err - // is string - case '"': - dec.cursor = dec.cursor + 1 - err := dec.skipString() - return err - // is array - case '[': - dec.cursor = dec.cursor + 1 - end, err := dec.skipArray() - dec.cursor = end - return err - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': - end, err := dec.skipNumber() - dec.cursor = end - return err - } - return dec.raiseInvalidJSONErr(dec.cursor) - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -// DecodeObjectFunc is a func type implementing UnmarshalerJSONObject. -// Use it to cast a `func(*Decoder, k string) error` to Unmarshal an object on the fly. -type DecodeObjectFunc func(*Decoder, string) error - -// UnmarshalJSONObject implements UnmarshalerJSONObject. -func (f DecodeObjectFunc) UnmarshalJSONObject(dec *Decoder, k string) error { - return f(dec, k) -} - -// NKeys implements UnmarshalerJSONObject. -func (f DecodeObjectFunc) NKeys() int { - return 0 -} - -// Add Values functions - -// AddObject decodes the JSON value within an object or an array to a UnmarshalerJSONObject. -func (dec *Decoder) AddObject(v UnmarshalerJSONObject) error { - return dec.Object(v) -} - -// AddObjectNull decodes the JSON value within an object or an array to a UnmarshalerJSONObject. -func (dec *Decoder) AddObjectNull(v interface{}) error { - return dec.ObjectNull(v) -} - -// Object decodes the JSON value within an object or an array to a UnmarshalerJSONObject. -func (dec *Decoder) Object(value UnmarshalerJSONObject) error { - initialKeysDone := dec.keysDone - initialChild := dec.child - dec.keysDone = 0 - dec.called = 0 - dec.child |= 1 - newCursor, err := dec.decodeObject(value) - if err != nil { - return err - } - dec.cursor = newCursor - dec.keysDone = initialKeysDone - dec.child = initialChild - dec.called |= 1 - return nil -} - -// ObjectNull decodes the JSON value within an object or an array to a UnmarshalerJSONObject. -// v should be a pointer to an UnmarshalerJSONObject, -// if `null` value is encountered in JSON, it will leave the value v untouched, -// else it will create a new instance of the UnmarshalerJSONObject behind v. -func (dec *Decoder) ObjectNull(v interface{}) error { - initialKeysDone := dec.keysDone - initialChild := dec.child - dec.keysDone = 0 - dec.called = 0 - dec.child |= 1 - newCursor, err := dec.decodeObjectNull(v) - if err != nil { - return err - } - dec.cursor = newCursor - dec.keysDone = initialKeysDone - dec.child = initialChild - dec.called |= 1 - return nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_pool.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_pool.go deleted file mode 100644 index 68c57138a..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_pool.go +++ /dev/null @@ -1,64 +0,0 @@ -package gojay - -import ( - "io" - "sync" -) - -var decPool = sync.Pool{ - New: newDecoderPool, -} - -func init() { - for i := 0; i < 32; i++ { - decPool.Put(NewDecoder(nil)) - } -} - -// NewDecoder returns a new decoder. -// It takes an io.Reader implementation as data input. -func NewDecoder(r io.Reader) *Decoder { - return &Decoder{ - called: 0, - cursor: 0, - keysDone: 0, - err: nil, - r: r, - data: make([]byte, 512), - length: 0, - isPooled: 0, - } -} -func newDecoderPool() interface{} { - return NewDecoder(nil) -} - -// BorrowDecoder borrows a Decoder from the pool. -// It takes an io.Reader implementation as data input. -// -// In order to benefit from the pool, a borrowed decoder must be released after usage. -func BorrowDecoder(r io.Reader) *Decoder { - return borrowDecoder(r, 512) -} -func borrowDecoder(r io.Reader, bufSize int) *Decoder { - dec := decPool.Get().(*Decoder) - dec.called = 0 - dec.keysDone = 0 - dec.cursor = 0 - dec.err = nil - dec.r = r - dec.length = 0 - dec.isPooled = 0 - if bufSize > 0 { - dec.data = make([]byte, bufSize) - } - return dec -} - -// Release sends back a Decoder to the pool. -// If a decoder is used after calling Release -// a panic will be raised with an InvalidUsagePooledDecoderError error. -func (dec *Decoder) Release() { - dec.isPooled = 1 - decPool.Put(dec) -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_slice.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_slice.go deleted file mode 100644 index dbbb4bf3a..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_slice.go +++ /dev/null @@ -1,89 +0,0 @@ -package gojay - -// AddSliceString unmarshals the next JSON array of strings to the given *[]string s -func (dec *Decoder) AddSliceString(s *[]string) error { - return dec.SliceString(s) -} - -// SliceString unmarshals the next JSON array of strings to the given *[]string s -func (dec *Decoder) SliceString(s *[]string) error { - err := dec.Array(DecodeArrayFunc(func(dec *Decoder) error { - var str string - if err := dec.String(&str); err != nil { - return err - } - *s = append(*s, str) - return nil - })) - - if err != nil { - return err - } - return nil -} - -// AddSliceInt unmarshals the next JSON array of integers to the given *[]int s -func (dec *Decoder) AddSliceInt(s *[]int) error { - return dec.SliceInt(s) -} - -// SliceInt unmarshals the next JSON array of integers to the given *[]int s -func (dec *Decoder) SliceInt(s *[]int) error { - err := dec.Array(DecodeArrayFunc(func(dec *Decoder) error { - var i int - if err := dec.Int(&i); err != nil { - return err - } - *s = append(*s, i) - return nil - })) - - if err != nil { - return err - } - return nil -} - -// AddFloat64 unmarshals the next JSON array of floats to the given *[]float64 s -func (dec *Decoder) AddSliceFloat64(s *[]float64) error { - return dec.SliceFloat64(s) -} - -// SliceFloat64 unmarshals the next JSON array of floats to the given *[]float64 s -func (dec *Decoder) SliceFloat64(s *[]float64) error { - err := dec.Array(DecodeArrayFunc(func(dec *Decoder) error { - var i float64 - if err := dec.Float64(&i); err != nil { - return err - } - *s = append(*s, i) - return nil - })) - - if err != nil { - return err - } - return nil -} - -// AddBool unmarshals the next JSON array of boolegers to the given *[]bool s -func (dec *Decoder) AddSliceBool(s *[]bool) error { - return dec.SliceBool(s) -} - -// SliceBool unmarshals the next JSON array of boolegers to the given *[]bool s -func (dec *Decoder) SliceBool(s *[]bool) error { - err := dec.Array(DecodeArrayFunc(func(dec *Decoder) error { - var b bool - if err := dec.Bool(&b); err != nil { - return err - } - *s = append(*s, b) - return nil - })) - - if err != nil { - return err - } - return nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_sqlnull.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_sqlnull.go deleted file mode 100644 index c25549f52..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_sqlnull.go +++ /dev/null @@ -1,157 +0,0 @@ -package gojay - -import "database/sql" - -// DecodeSQLNullString decodes a sql.NullString -func (dec *Decoder) DecodeSQLNullString(v *sql.NullString) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeSQLNullString(v) -} - -func (dec *Decoder) decodeSQLNullString(v *sql.NullString) error { - var str string - if err := dec.decodeString(&str); err != nil { - return err - } - v.String = str - v.Valid = true - return nil -} - -// DecodeSQLNullInt64 decodes a sql.NullInt64 -func (dec *Decoder) DecodeSQLNullInt64(v *sql.NullInt64) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeSQLNullInt64(v) -} - -func (dec *Decoder) decodeSQLNullInt64(v *sql.NullInt64) error { - var i int64 - if err := dec.decodeInt64(&i); err != nil { - return err - } - v.Int64 = i - v.Valid = true - return nil -} - -// DecodeSQLNullFloat64 decodes a sql.NullString with the given format -func (dec *Decoder) DecodeSQLNullFloat64(v *sql.NullFloat64) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeSQLNullFloat64(v) -} - -func (dec *Decoder) decodeSQLNullFloat64(v *sql.NullFloat64) error { - var i float64 - if err := dec.decodeFloat64(&i); err != nil { - return err - } - v.Float64 = i - v.Valid = true - return nil -} - -// DecodeSQLNullBool decodes a sql.NullString with the given format -func (dec *Decoder) DecodeSQLNullBool(v *sql.NullBool) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeSQLNullBool(v) -} - -func (dec *Decoder) decodeSQLNullBool(v *sql.NullBool) error { - var b bool - if err := dec.decodeBool(&b); err != nil { - return err - } - v.Bool = b - v.Valid = true - return nil -} - -// Add Values functions - -// AddSQLNullString decodes the JSON value within an object or an array to qn *sql.NullString -func (dec *Decoder) AddSQLNullString(v *sql.NullString) error { - return dec.SQLNullString(v) -} - -// SQLNullString decodes the JSON value within an object or an array to an *sql.NullString -func (dec *Decoder) SQLNullString(v *sql.NullString) error { - var b *string - if err := dec.StringNull(&b); err != nil { - return err - } - if b == nil { - v.Valid = false - } else { - v.String = *b - v.Valid = true - } - return nil -} - -// AddSQLNullInt64 decodes the JSON value within an object or an array to qn *sql.NullInt64 -func (dec *Decoder) AddSQLNullInt64(v *sql.NullInt64) error { - return dec.SQLNullInt64(v) -} - -// SQLNullInt64 decodes the JSON value within an object or an array to an *sql.NullInt64 -func (dec *Decoder) SQLNullInt64(v *sql.NullInt64) error { - var b *int64 - if err := dec.Int64Null(&b); err != nil { - return err - } - if b == nil { - v.Valid = false - } else { - v.Int64 = *b - v.Valid = true - } - return nil -} - -// AddSQLNullFloat64 decodes the JSON value within an object or an array to qn *sql.NullFloat64 -func (dec *Decoder) AddSQLNullFloat64(v *sql.NullFloat64) error { - return dec.SQLNullFloat64(v) -} - -// SQLNullFloat64 decodes the JSON value within an object or an array to an *sql.NullFloat64 -func (dec *Decoder) SQLNullFloat64(v *sql.NullFloat64) error { - var b *float64 - if err := dec.Float64Null(&b); err != nil { - return err - } - if b == nil { - v.Valid = false - } else { - v.Float64 = *b - v.Valid = true - } - return nil -} - -// AddSQLNullBool decodes the JSON value within an object or an array to an *sql.NullBool -func (dec *Decoder) AddSQLNullBool(v *sql.NullBool) error { - return dec.SQLNullBool(v) -} - -// SQLNullBool decodes the JSON value within an object or an array to an *sql.NullBool -func (dec *Decoder) SQLNullBool(v *sql.NullBool) error { - var b *bool - if err := dec.BoolNull(&b); err != nil { - return err - } - if b == nil { - v.Valid = false - } else { - v.Bool = *b - v.Valid = true - } - return nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_stream.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_stream.go deleted file mode 100644 index 74beee4d7..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_stream.go +++ /dev/null @@ -1,115 +0,0 @@ -package gojay - -import ( - "sync" - "time" -) - -// UnmarshalerStream is the interface to implement for a slice, an array or a slice -// to decode a line delimited JSON to. -type UnmarshalerStream interface { - UnmarshalStream(*StreamDecoder) error -} - -// Stream is a struct holding the Stream api -var Stream = stream{} - -type stream struct{} - -// A StreamDecoder reads and decodes JSON values from an input stream. -// -// It implements conext.Context and provide a channel to notify interruption. -type StreamDecoder struct { - mux sync.RWMutex - *Decoder - done chan struct{} - deadline *time.Time -} - -// DecodeStream reads the next line delimited JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by c. -// -// c must implement UnmarshalerStream. Ideally c is a channel. See example for implementation. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *StreamDecoder) DecodeStream(c UnmarshalerStream) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - if dec.r == nil { - dec.err = NoReaderError("No reader given to decode stream") - close(dec.done) - return dec.err - } - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - continue - default: - // char is not space start reading - for dec.nextChar() != 0 { - // calling unmarshal stream - err := c.UnmarshalStream(dec) - if err != nil { - dec.err = err - close(dec.done) - return err - } - // garbage collects buffer - // we don't want the buffer to grow extensively - dec.data = dec.data[dec.cursor:] - dec.length = dec.length - dec.cursor - dec.cursor = 0 - } - // close the done channel to signal the end of the job - close(dec.done) - return nil - } - } - close(dec.done) - dec.mux.Lock() - err := dec.raiseInvalidJSONErr(dec.cursor) - dec.mux.Unlock() - return err -} - -// context.Context implementation - -// Done returns a channel that's closed when work is done. -// It implements context.Context -func (dec *StreamDecoder) Done() <-chan struct{} { - return dec.done -} - -// Deadline returns the time when work done on behalf of this context -// should be canceled. Deadline returns ok==false when no deadline is -// set. Successive calls to Deadline return the same results. -func (dec *StreamDecoder) Deadline() (time.Time, bool) { - if dec.deadline != nil { - return *dec.deadline, true - } - return time.Time{}, false -} - -// SetDeadline sets the deadline -func (dec *StreamDecoder) SetDeadline(t time.Time) { - dec.deadline = &t -} - -// Err returns nil if Done is not yet closed. -// If Done is closed, Err returns a non-nil error explaining why. -// It implements context.Context -func (dec *StreamDecoder) Err() error { - select { - case <-dec.done: - dec.mux.RLock() - defer dec.mux.RUnlock() - return dec.err - default: - return nil - } -} - -// Value implements context.Context -func (dec *StreamDecoder) Value(key interface{}) interface{} { - return nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_stream_pool.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_stream_pool.go deleted file mode 100644 index 8e1863b92..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_stream_pool.go +++ /dev/null @@ -1,59 +0,0 @@ -package gojay - -import ( - "io" - "sync" -) - -var streamDecPool = sync.Pool{ - New: newStreamDecoderPool, -} - -// NewDecoder returns a new StreamDecoder. -// It takes an io.Reader implementation as data input. -// It initiates the done channel returned by Done(). -func (s stream) NewDecoder(r io.Reader) *StreamDecoder { - dec := NewDecoder(r) - streamDec := &StreamDecoder{ - Decoder: dec, - done: make(chan struct{}, 1), - mux: sync.RWMutex{}, - } - return streamDec -} -func newStreamDecoderPool() interface{} { - return Stream.NewDecoder(nil) -} - -// BorrowDecoder borrows a StreamDecoder from the pool. -// It takes an io.Reader implementation as data input. -// It initiates the done channel returned by Done(). -// -// If no StreamEncoder is available in the pool, it returns a fresh one -func (s stream) BorrowDecoder(r io.Reader) *StreamDecoder { - return s.borrowDecoder(r, 512) -} - -func (s stream) borrowDecoder(r io.Reader, bufSize int) *StreamDecoder { - streamDec := streamDecPool.Get().(*StreamDecoder) - streamDec.called = 0 - streamDec.keysDone = 0 - streamDec.cursor = 0 - streamDec.err = nil - streamDec.r = r - streamDec.length = 0 - streamDec.isPooled = 0 - streamDec.done = make(chan struct{}, 1) - if bufSize > 0 { - streamDec.data = make([]byte, bufSize) - } - return streamDec -} - -// Release sends back a Decoder to the pool. -// If a decoder is used after calling Release -// a panic will be raised with an InvalidUsagePooledDecoderError error. -func (dec *StreamDecoder) Release() { - dec.isPooled = 1 - streamDecPool.Put(dec) -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_string.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_string.go deleted file mode 100644 index 694359c7b..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_string.go +++ /dev/null @@ -1,260 +0,0 @@ -package gojay - -import ( - "unsafe" -) - -// DecodeString reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the string pointed to by v. -// -// See the documentation for Unmarshal for details about the conversion of JSON into a Go value. -func (dec *Decoder) DecodeString(v *string) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeString(v) -} -func (dec *Decoder) decodeString(v *string) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - // is string - continue - case '"': - dec.cursor++ - start, end, err := dec.getString() - if err != nil { - return err - } - // we do minus one to remove the last quote - d := dec.data[start : end-1] - *v = *(*string)(unsafe.Pointer(&d)) - dec.cursor = end - return nil - // is nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return nil -} - -func (dec *Decoder) decodeStringNull(v **string) error { - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - switch dec.data[dec.cursor] { - case ' ', '\n', '\t', '\r', ',': - // is string - continue - case '"': - dec.cursor++ - start, end, err := dec.getString() - - if err != nil { - return err - } - if *v == nil { - *v = new(string) - } - // we do minus one to remove the last quote - d := dec.data[start : end-1] - **v = *(*string)(unsafe.Pointer(&d)) - dec.cursor = end - return nil - // is nil - case 'n': - dec.cursor++ - err := dec.assertNull() - if err != nil { - return err - } - return nil - default: - dec.err = dec.makeInvalidUnmarshalErr(v) - err := dec.skipData() - if err != nil { - return err - } - return nil - } - } - return nil -} - -func (dec *Decoder) parseEscapedString() error { - if dec.cursor >= dec.length && !dec.read() { - return dec.raiseInvalidJSONErr(dec.cursor) - } - switch dec.data[dec.cursor] { - case '"': - dec.data[dec.cursor] = '"' - case '\\': - dec.data[dec.cursor] = '\\' - case '/': - dec.data[dec.cursor] = '/' - case 'b': - dec.data[dec.cursor] = '\b' - case 'f': - dec.data[dec.cursor] = '\f' - case 'n': - dec.data[dec.cursor] = '\n' - case 'r': - dec.data[dec.cursor] = '\r' - case 't': - dec.data[dec.cursor] = '\t' - case 'u': - start := dec.cursor - dec.cursor++ - str, err := dec.parseUnicode() - if err != nil { - return err - } - diff := dec.cursor - start - dec.data = append(append(dec.data[:start-1], str...), dec.data[dec.cursor:]...) - dec.length = len(dec.data) - dec.cursor += len(str) - diff - 1 - - return nil - default: - return dec.raiseInvalidJSONErr(dec.cursor) - } - - dec.data = append(dec.data[:dec.cursor-1], dec.data[dec.cursor:]...) - dec.length-- - - // Since we've lost a character, our dec.cursor offset is now - // 1 past the escaped character which is precisely where we - // want it. - - return nil -} - -func (dec *Decoder) getString() (int, int, error) { - // extract key - var keyStart = dec.cursor - // var str *Builder - for dec.cursor < dec.length || dec.read() { - switch dec.data[dec.cursor] { - // string found - case '"': - dec.cursor = dec.cursor + 1 - return keyStart, dec.cursor, nil - // slash found - case '\\': - dec.cursor = dec.cursor + 1 - err := dec.parseEscapedString() - if err != nil { - return 0, 0, err - } - default: - dec.cursor = dec.cursor + 1 - continue - } - } - return 0, 0, dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) skipEscapedString() error { - start := dec.cursor - for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { - if dec.data[dec.cursor] != '\\' { - d := dec.data[dec.cursor] - dec.cursor = dec.cursor + 1 - nSlash := dec.cursor - start - switch d { - case '"': - // nSlash must be odd - if nSlash&1 != 1 { - return dec.raiseInvalidJSONErr(dec.cursor) - } - return nil - case 'u': // is unicode, we skip the following characters and place the cursor one one byte backward to avoid it breaking when returning to skipString - if err := dec.skipString(); err != nil { - return err - } - dec.cursor-- - return nil - case 'n', 'r', 't', '/', 'f', 'b': - return nil - default: - // nSlash must be even - if nSlash&1 == 1 { - return dec.raiseInvalidJSONErr(dec.cursor) - } - return nil - } - } - } - return dec.raiseInvalidJSONErr(dec.cursor) -} - -func (dec *Decoder) skipString() error { - for dec.cursor < dec.length || dec.read() { - switch dec.data[dec.cursor] { - // found the closing quote - // let's return - case '"': - dec.cursor = dec.cursor + 1 - return nil - // solidus found start parsing an escaped string - case '\\': - dec.cursor = dec.cursor + 1 - err := dec.skipEscapedString() - if err != nil { - return err - } - default: - dec.cursor = dec.cursor + 1 - continue - } - } - return dec.raiseInvalidJSONErr(len(dec.data) - 1) -} - -// Add Values functions - -// AddString decodes the JSON value within an object or an array to a *string. -// If next key is not a JSON string nor null, InvalidUnmarshalError will be returned. -func (dec *Decoder) AddString(v *string) error { - return dec.String(v) -} - -// AddStringNull decodes the JSON value within an object or an array to a *string. -// If next key is not a JSON string nor null, InvalidUnmarshalError will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) AddStringNull(v **string) error { - return dec.StringNull(v) -} - -// String decodes the JSON value within an object or an array to a *string. -// If next key is not a JSON string nor null, InvalidUnmarshalError will be returned. -func (dec *Decoder) String(v *string) error { - err := dec.decodeString(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} - -// StringNull decodes the JSON value within an object or an array to a **string. -// If next key is not a JSON string nor null, InvalidUnmarshalError will be returned. -// If a `null` is encountered, gojay does not change the value of the pointer. -func (dec *Decoder) StringNull(v **string) error { - err := dec.decodeStringNull(v) - if err != nil { - return err - } - dec.called |= 1 - return nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_string_unicode.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_string_unicode.go deleted file mode 100644 index 9e14d52b0..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_string_unicode.go +++ /dev/null @@ -1,98 +0,0 @@ -package gojay - -import ( - "unicode/utf16" - "unicode/utf8" -) - -func (dec *Decoder) getUnicode() (rune, error) { - i := 0 - r := rune(0) - for ; (dec.cursor < dec.length || dec.read()) && i < 4; dec.cursor++ { - c := dec.data[dec.cursor] - if c >= '0' && c <= '9' { - r = r*16 + rune(c-'0') - } else if c >= 'a' && c <= 'f' { - r = r*16 + rune(c-'a'+10) - } else if c >= 'A' && c <= 'F' { - r = r*16 + rune(c-'A'+10) - } else { - return 0, InvalidJSONError("Invalid unicode code point") - } - i++ - } - return r, nil -} - -func (dec *Decoder) appendEscapeChar(str []byte, c byte) ([]byte, error) { - switch c { - case 't': - str = append(str, '\t') - case 'n': - str = append(str, '\n') - case 'r': - str = append(str, '\r') - case 'b': - str = append(str, '\b') - case 'f': - str = append(str, '\f') - case '\\': - str = append(str, '\\') - default: - return nil, InvalidJSONError("Invalid JSON") - } - return str, nil -} - -func (dec *Decoder) parseUnicode() ([]byte, error) { - // get unicode after u - r, err := dec.getUnicode() - if err != nil { - return nil, err - } - // no error start making new string - str := make([]byte, 16, 16) - i := 0 - // check if code can be a surrogate utf16 - if utf16.IsSurrogate(r) { - if dec.cursor >= dec.length && !dec.read() { - return nil, dec.raiseInvalidJSONErr(dec.cursor) - } - c := dec.data[dec.cursor] - if c != '\\' { - i += utf8.EncodeRune(str, r) - return str[:i], nil - } - dec.cursor++ - if dec.cursor >= dec.length && !dec.read() { - return nil, dec.raiseInvalidJSONErr(dec.cursor) - } - c = dec.data[dec.cursor] - if c != 'u' { - i += utf8.EncodeRune(str, r) - str, err = dec.appendEscapeChar(str[:i], c) - if err != nil { - dec.err = err - return nil, err - } - i++ - dec.cursor++ - return str[:i], nil - } - dec.cursor++ - r2, err := dec.getUnicode() - if err != nil { - return nil, err - } - combined := utf16.DecodeRune(r, r2) - if combined == '\uFFFD' { - i += utf8.EncodeRune(str, r) - i += utf8.EncodeRune(str, r2) - } else { - i += utf8.EncodeRune(str, combined) - } - return str[:i], nil - } - i += utf8.EncodeRune(str, r) - return str[:i], nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_time.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_time.go deleted file mode 100644 index 68f906d7f..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_time.go +++ /dev/null @@ -1,53 +0,0 @@ -package gojay - -import ( - "time" -) - -// DecodeTime decodes time with the given format -func (dec *Decoder) DecodeTime(v *time.Time, format string) error { - if dec.isPooled == 1 { - panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) - } - return dec.decodeTime(v, format) -} - -func (dec *Decoder) decodeTime(v *time.Time, format string) error { - if format == time.RFC3339 { - var ej = make(EmbeddedJSON, 0, 20) - if err := dec.decodeEmbeddedJSON(&ej); err != nil { - return err - } - if err := v.UnmarshalJSON(ej); err != nil { - return err - } - return nil - } - var str string - if err := dec.decodeString(&str); err != nil { - return err - } - tt, err := time.Parse(format, str) - if err != nil { - return err - } - *v = tt - return nil -} - -// Add Values functions - -// AddTime decodes the JSON value within an object or an array to a *time.Time with the given format -func (dec *Decoder) AddTime(v *time.Time, format string) error { - return dec.Time(v, format) -} - -// Time decodes the JSON value within an object or an array to a *time.Time with the given format -func (dec *Decoder) Time(v *time.Time, format string) error { - err := dec.decodeTime(v, format) - if err != nil { - return err - } - dec.called |= 1 - return nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_unsafe.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_unsafe.go deleted file mode 100644 index 54448fba7..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/decode_unsafe.go +++ /dev/null @@ -1,120 +0,0 @@ -package gojay - -import ( - "fmt" -) - -// Unsafe is the structure holding the unsafe version of the API. -// The difference between unsafe api and regular api is that the regular API -// copies the buffer passed to Unmarshal functions to a new internal buffer. -// Making it safer because internally GoJay uses unsafe.Pointer to transform slice of bytes into a string. -var Unsafe = decUnsafe{} - -type decUnsafe struct{} - -func (u decUnsafe) UnmarshalJSONArray(data []byte, v UnmarshalerJSONArray) error { - dec := borrowDecoder(nil, 0) - defer dec.Release() - dec.data = data - dec.length = len(data) - _, err := dec.decodeArray(v) - return err -} - -func (u decUnsafe) UnmarshalJSONObject(data []byte, v UnmarshalerJSONObject) error { - dec := borrowDecoder(nil, 0) - defer dec.Release() - dec.data = data - dec.length = len(data) - _, err := dec.decodeObject(v) - return err -} - -func (u decUnsafe) Unmarshal(data []byte, v interface{}) error { - var err error - var dec *Decoder - switch vt := v.(type) { - case *string: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeString(vt) - case *int: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt(vt) - case *int8: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt8(vt) - case *int16: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt16(vt) - case *int32: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt32(vt) - case *int64: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeInt64(vt) - case *uint8: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeUint8(vt) - case *uint16: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeUint16(vt) - case *uint32: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeUint32(vt) - case *uint64: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeUint64(vt) - case *float64: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeFloat64(vt) - case *float32: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeFloat32(vt) - case *bool: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - err = dec.decodeBool(vt) - case UnmarshalerJSONObject: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - _, err = dec.decodeObject(vt) - case UnmarshalerJSONArray: - dec = borrowDecoder(nil, 0) - dec.length = len(data) - dec.data = data - _, err = dec.decodeArray(vt) - default: - return InvalidUnmarshalError(fmt.Sprintf(invalidUnmarshalErrorMsg, vt)) - } - defer dec.Release() - if err != nil { - return err - } - return dec.err -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode.go deleted file mode 100644 index 92edaafa0..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode.go +++ /dev/null @@ -1,202 +0,0 @@ -package gojay - -import ( - "encoding/json" - "fmt" - "io" -) - -var nullBytes = []byte("null") - -// MarshalJSONArray returns the JSON encoding of v, an implementation of MarshalerJSONArray. -// -// -// Example: -// type TestSlice []*TestStruct -// -// func (t TestSlice) MarshalJSONArray(enc *Encoder) { -// for _, e := range t { -// enc.AddObject(e) -// } -// } -// -// func main() { -// test := &TestSlice{ -// &TestStruct{123456}, -// &TestStruct{7890}, -// } -// b, _ := Marshal(test) -// fmt.Println(b) // [{"id":123456},{"id":7890}] -// } -func MarshalJSONArray(v MarshalerJSONArray) ([]byte, error) { - enc := BorrowEncoder(nil) - enc.grow(512) - enc.writeByte('[') - v.(MarshalerJSONArray).MarshalJSONArray(enc) - enc.writeByte(']') - - defer func() { - enc.buf = make([]byte, 0, 512) - enc.Release() - }() - - return enc.buf, nil -} - -// MarshalJSONObject returns the JSON encoding of v, an implementation of MarshalerJSONObject. -// -// Example: -// type Object struct { -// id int -// } -// func (s *Object) MarshalJSONObject(enc *gojay.Encoder) { -// enc.IntKey("id", s.id) -// } -// func (s *Object) IsNil() bool { -// return s == nil -// } -// -// func main() { -// test := &Object{ -// id: 123456, -// } -// b, _ := gojay.Marshal(test) -// fmt.Println(b) // {"id":123456} -// } -func MarshalJSONObject(v MarshalerJSONObject) ([]byte, error) { - enc := BorrowEncoder(nil) - enc.grow(512) - - defer func() { - enc.buf = make([]byte, 0, 512) - enc.Release() - }() - - return enc.encodeObject(v) -} - -// Marshal returns the JSON encoding of v. -// -// If v is nil, not an implementation MarshalerJSONObject or MarshalerJSONArray or not one of the following types: -// string, int, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float64, float32, bool -// Marshal returns an InvalidMarshalError. -func Marshal(v interface{}) ([]byte, error) { - return marshal(v, false) -} - -// MarshalAny returns the JSON encoding of v. -// -// If v is nil, not an implementation MarshalerJSONObject or MarshalerJSONArray or not one of the following types: -// string, int, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float64, float32, bool -// MarshalAny falls back to "json/encoding" package to marshal the value. -func MarshalAny(v interface{}) ([]byte, error) { - return marshal(v, true) -} - -func marshal(v interface{}, any bool) ([]byte, error) { - var ( - enc = BorrowEncoder(nil) - - buf []byte - err error - ) - - defer func() { - enc.buf = make([]byte, 0, 512) - enc.Release() - }() - - buf, err = func() ([]byte, error) { - switch vt := v.(type) { - case MarshalerJSONObject: - return enc.encodeObject(vt) - case MarshalerJSONArray: - return enc.encodeArray(vt) - case string: - return enc.encodeString(vt) - case bool: - return enc.encodeBool(vt) - case int: - return enc.encodeInt(vt) - case int64: - return enc.encodeInt64(vt) - case int32: - return enc.encodeInt(int(vt)) - case int16: - return enc.encodeInt(int(vt)) - case int8: - return enc.encodeInt(int(vt)) - case uint64: - return enc.encodeInt(int(vt)) - case uint32: - return enc.encodeInt(int(vt)) - case uint16: - return enc.encodeInt(int(vt)) - case uint8: - return enc.encodeInt(int(vt)) - case float64: - return enc.encodeFloat(vt) - case float32: - return enc.encodeFloat32(vt) - case *EmbeddedJSON: - return enc.encodeEmbeddedJSON(vt) - default: - if any { - return json.Marshal(vt) - } - - return nil, InvalidMarshalError(fmt.Sprintf(invalidMarshalErrorMsg, vt)) - } - }() - return buf, err -} - -// MarshalerJSONObject is the interface to implement for struct to be encoded -type MarshalerJSONObject interface { - MarshalJSONObject(enc *Encoder) - IsNil() bool -} - -// MarshalerJSONArray is the interface to implement -// for a slice or an array to be encoded -type MarshalerJSONArray interface { - MarshalJSONArray(enc *Encoder) - IsNil() bool -} - -// An Encoder writes JSON values to an output stream. -type Encoder struct { - buf []byte - isPooled byte - w io.Writer - err error - hasKeys bool - keys []string -} - -// AppendBytes allows a modular usage by appending bytes manually to the current state of the buffer. -func (enc *Encoder) AppendBytes(b []byte) { - enc.writeBytes(b) -} - -// AppendByte allows a modular usage by appending a single byte manually to the current state of the buffer. -func (enc *Encoder) AppendByte(b byte) { - enc.writeByte(b) -} - -// Buf returns the Encoder's buffer. -func (enc *Encoder) Buf() []byte { - return enc.buf -} - -// Write writes to the io.Writer and resets the buffer. -func (enc *Encoder) Write() (int, error) { - i, err := enc.w.Write(enc.buf) - enc.buf = enc.buf[:0] - return i, err -} - -func (enc *Encoder) getPreviousRune() byte { - last := len(enc.buf) - 1 - return enc.buf[last] -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_array.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_array.go deleted file mode 100644 index 5e9d49e82..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_array.go +++ /dev/null @@ -1,212 +0,0 @@ -package gojay - -// EncodeArray encodes an implementation of MarshalerJSONArray to JSON -func (enc *Encoder) EncodeArray(v MarshalerJSONArray) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeArray(v) - _, err := enc.Write() - if err != nil { - enc.err = err - return err - } - return nil -} -func (enc *Encoder) encodeArray(v MarshalerJSONArray) ([]byte, error) { - enc.grow(200) - enc.writeByte('[') - v.MarshalJSONArray(enc) - enc.writeByte(']') - return enc.buf, enc.err -} - -// AddArray adds an implementation of MarshalerJSONArray to be encoded, must be used inside a slice or array encoding (does not encode a key) -// value must implement Marshaler -func (enc *Encoder) AddArray(v MarshalerJSONArray) { - enc.Array(v) -} - -// AddArrayOmitEmpty adds an array or slice to be encoded, must be used inside a slice or array encoding (does not encode a key) -// value must implement MarshalerAddArrayOmitEmpty -func (enc *Encoder) AddArrayOmitEmpty(v MarshalerJSONArray) { - enc.ArrayOmitEmpty(v) -} - -// AddArrayNullEmpty adds an array or slice to be encoded, must be used inside a slice or array encoding (does not encode a key) -// value must implement Marshaler, if v is empty, `null` will be encoded` -func (enc *Encoder) AddArrayNullEmpty(v MarshalerJSONArray) { - enc.ArrayNullEmpty(v) -} - -// AddArrayKey adds an array or slice to be encoded, must be used inside an object as it will encode a key -// value must implement Marshaler -func (enc *Encoder) AddArrayKey(key string, v MarshalerJSONArray) { - enc.ArrayKey(key, v) -} - -// AddArrayKeyOmitEmpty adds an array or slice to be encoded and skips it if it is nil. -// Must be called inside an object as it will encode a key. -func (enc *Encoder) AddArrayKeyOmitEmpty(key string, v MarshalerJSONArray) { - enc.ArrayKeyOmitEmpty(key, v) -} - -// AddArrayKeyNullEmpty adds an array or slice to be encoded and skips it if it is nil. -// Must be called inside an object as it will encode a key. `null` will be encoded` -func (enc *Encoder) AddArrayKeyNullEmpty(key string, v MarshalerJSONArray) { - enc.ArrayKeyNullEmpty(key, v) -} - -// Array adds an implementation of MarshalerJSONArray to be encoded, must be used inside a slice or array encoding (does not encode a key) -// value must implement Marshaler -func (enc *Encoder) Array(v MarshalerJSONArray) { - if v.IsNil() { - enc.grow(3) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.writeByte('[') - enc.writeByte(']') - return - } - enc.grow(100) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.writeByte('[') - v.MarshalJSONArray(enc) - enc.writeByte(']') -} - -// ArrayOmitEmpty adds an array or slice to be encoded, must be used inside a slice or array encoding (does not encode a key) -// value must implement Marshaler -func (enc *Encoder) ArrayOmitEmpty(v MarshalerJSONArray) { - if v.IsNil() { - return - } - enc.grow(4) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.writeByte('[') - v.MarshalJSONArray(enc) - enc.writeByte(']') -} - -// ArrayNullEmpty adds an array or slice to be encoded, must be used inside a slice or array encoding (does not encode a key) -// value must implement Marshaler -func (enc *Encoder) ArrayNullEmpty(v MarshalerJSONArray) { - enc.grow(4) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - if v.IsNil() { - enc.writeBytes(nullBytes) - return - } - enc.writeByte('[') - v.MarshalJSONArray(enc) - enc.writeByte(']') -} - -// ArrayKey adds an array or slice to be encoded, must be used inside an object as it will encode a key -// value must implement Marshaler -func (enc *Encoder) ArrayKey(key string, v MarshalerJSONArray) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - if v.IsNil() { - enc.grow(2 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKeyArr) - enc.writeByte(']') - return - } - enc.grow(5 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKeyArr) - v.MarshalJSONArray(enc) - enc.writeByte(']') -} - -// ArrayKeyOmitEmpty adds an array or slice to be encoded and skips if it is nil. -// Must be called inside an object as it will encode a key. -func (enc *Encoder) ArrayKeyOmitEmpty(key string, v MarshalerJSONArray) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - if v.IsNil() { - return - } - enc.grow(5 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKeyArr) - v.MarshalJSONArray(enc) - enc.writeByte(']') -} - -// ArrayKeyNullEmpty adds an array or slice to be encoded and encodes `null`` if it is nil. -// Must be called inside an object as it will encode a key. -func (enc *Encoder) ArrayKeyNullEmpty(key string, v MarshalerJSONArray) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(5 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - if v.IsNil() { - enc.writeBytes(nullBytes) - return - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKeyArr) - v.MarshalJSONArray(enc) - enc.writeByte(']') -} - -// EncodeArrayFunc is a custom func type implementing MarshaleArray. -// Use it to cast a func(*Encoder) to Marshal an object. -// -// enc := gojay.NewEncoder(io.Writer) -// enc.EncodeArray(gojay.EncodeArrayFunc(func(enc *gojay.Encoder) { -// enc.AddStringKey("hello", "world") -// })) -type EncodeArrayFunc func(*Encoder) - -// MarshalJSONArray implements MarshalerJSONArray. -func (f EncodeArrayFunc) MarshalJSONArray(enc *Encoder) { - f(enc) -} - -// IsNil implements MarshalerJSONArray. -func (f EncodeArrayFunc) IsNil() bool { - return f == nil -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_bool.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_bool.go deleted file mode 100644 index 253e03789..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_bool.go +++ /dev/null @@ -1,164 +0,0 @@ -package gojay - -import "strconv" - -// EncodeBool encodes a bool to JSON -func (enc *Encoder) EncodeBool(v bool) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeBool(v) - _, err := enc.Write() - if err != nil { - enc.err = err - return err - } - return nil -} - -// encodeBool encodes a bool to JSON -func (enc *Encoder) encodeBool(v bool) ([]byte, error) { - enc.grow(5) - if v { - enc.writeString("true") - } else { - enc.writeString("false") - } - return enc.buf, enc.err -} - -// AddBool adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddBool(v bool) { - enc.Bool(v) -} - -// AddBoolOmitEmpty adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddBoolOmitEmpty(v bool) { - enc.BoolOmitEmpty(v) -} - -// AddBoolNullEmpty adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddBoolNullEmpty(v bool) { - enc.BoolNullEmpty(v) -} - -// AddBoolKey adds a bool to be encoded, must be used inside an object as it will encode a key. -func (enc *Encoder) AddBoolKey(key string, v bool) { - enc.BoolKey(key, v) -} - -// AddBoolKeyOmitEmpty adds a bool to be encoded and skips if it is zero value. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddBoolKeyOmitEmpty(key string, v bool) { - enc.BoolKeyOmitEmpty(key, v) -} - -// AddBoolKeyNullEmpty adds a bool to be encoded and encodes `null` if it is zero value. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddBoolKeyNullEmpty(key string, v bool) { - enc.BoolKeyNullEmpty(key, v) -} - -// Bool adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Bool(v bool) { - enc.grow(5) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - if v { - enc.writeString("true") - } else { - enc.writeString("false") - } -} - -// BoolOmitEmpty adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) BoolOmitEmpty(v bool) { - if v == false { - return - } - enc.grow(5) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.writeString("true") -} - -// BoolNullEmpty adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) BoolNullEmpty(v bool) { - enc.grow(5) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - if v == false { - enc.writeBytes(nullBytes) - return - } - enc.writeString("true") -} - -// BoolKey adds a bool to be encoded, must be used inside an object as it will encode a key. -func (enc *Encoder) BoolKey(key string, value bool) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(5 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendBool(enc.buf, value) -} - -// BoolKeyOmitEmpty adds a bool to be encoded and skips it if it is zero value. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) BoolKeyOmitEmpty(key string, v bool) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - if v == false { - return - } - enc.grow(5 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendBool(enc.buf, v) -} - -// BoolKeyNullEmpty adds a bool to be encoded and skips it if it is zero value. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) BoolKeyNullEmpty(key string, v bool) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(5 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - if v == false { - enc.writeBytes(nullBytes) - return - } - enc.buf = strconv.AppendBool(enc.buf, v) -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_builder.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_builder.go deleted file mode 100644 index 2895ba34a..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_builder.go +++ /dev/null @@ -1,65 +0,0 @@ -package gojay - -const hex = "0123456789abcdef" - -// grow grows b's capacity, if necessary, to guarantee space for -// another n bytes. After grow(n), at least n bytes can be written to b -// without another allocation. If n is negative, grow panics. -func (enc *Encoder) grow(n int) { - if cap(enc.buf)-len(enc.buf) < n { - Buf := make([]byte, len(enc.buf), 2*cap(enc.buf)+n) - copy(Buf, enc.buf) - enc.buf = Buf - } -} - -// Write appends the contents of p to b's Buffer. -// Write always returns len(p), nil. -func (enc *Encoder) writeBytes(p []byte) { - enc.buf = append(enc.buf, p...) -} - -func (enc *Encoder) writeTwoBytes(b1 byte, b2 byte) { - enc.buf = append(enc.buf, b1, b2) -} - -// WriteByte appends the byte c to b's Buffer. -// The returned error is always nil. -func (enc *Encoder) writeByte(c byte) { - enc.buf = append(enc.buf, c) -} - -// WriteString appends the contents of s to b's Buffer. -// It returns the length of s and a nil error. -func (enc *Encoder) writeString(s string) { - enc.buf = append(enc.buf, s...) -} - -func (enc *Encoder) writeStringEscape(s string) { - l := len(s) - for i := 0; i < l; i++ { - c := s[i] - if c >= 0x20 && c != '\\' && c != '"' { - enc.writeByte(c) - continue - } - switch c { - case '\\', '"': - enc.writeTwoBytes('\\', c) - case '\n': - enc.writeTwoBytes('\\', 'n') - case '\f': - enc.writeTwoBytes('\\', 'f') - case '\b': - enc.writeTwoBytes('\\', 'b') - case '\r': - enc.writeTwoBytes('\\', 'r') - case '\t': - enc.writeTwoBytes('\\', 't') - default: - enc.writeString(`\u00`) - enc.writeTwoBytes(hex[c>>4], hex[c&0xF]) - } - continue - } -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_embedded_json.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_embedded_json.go deleted file mode 100644 index 4c99a0578..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_embedded_json.go +++ /dev/null @@ -1,93 +0,0 @@ -package gojay - -// EncodeEmbeddedJSON encodes an embedded JSON. -// is basically sets the internal buf as the value pointed by v and calls the io.Writer.Write() -func (enc *Encoder) EncodeEmbeddedJSON(v *EmbeddedJSON) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - enc.buf = *v - _, err := enc.Write() - if err != nil { - return err - } - return nil -} - -func (enc *Encoder) encodeEmbeddedJSON(v *EmbeddedJSON) ([]byte, error) { - enc.writeBytes(*v) - return enc.buf, nil -} - -// AddEmbeddedJSON adds an EmbeddedJSON to be encoded. -// -// It basically blindly writes the bytes to the final buffer. Therefore, -// it expects the JSON to be of proper format. -func (enc *Encoder) AddEmbeddedJSON(v *EmbeddedJSON) { - enc.grow(len(*v) + 4) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.writeBytes(*v) -} - -// AddEmbeddedJSONOmitEmpty adds an EmbeddedJSON to be encoded or skips it if nil pointer or empty. -// -// It basically blindly writes the bytes to the final buffer. Therefore, -// it expects the JSON to be of proper format. -func (enc *Encoder) AddEmbeddedJSONOmitEmpty(v *EmbeddedJSON) { - if v == nil || len(*v) == 0 { - return - } - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.writeBytes(*v) -} - -// AddEmbeddedJSONKey adds an EmbeddedJSON and a key to be encoded. -// -// It basically blindly writes the bytes to the final buffer. Therefore, -// it expects the JSON to be of proper format. -func (enc *Encoder) AddEmbeddedJSONKey(key string, v *EmbeddedJSON) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(len(key) + len(*v) + 5) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.writeBytes(*v) -} - -// AddEmbeddedJSONKeyOmitEmpty adds an EmbeddedJSON and a key to be encoded or skips it if nil pointer or empty. -// -// It basically blindly writes the bytes to the final buffer. Therefore, -// it expects the JSON to be of proper format. -func (enc *Encoder) AddEmbeddedJSONKeyOmitEmpty(key string, v *EmbeddedJSON) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - if v == nil || len(*v) == 0 { - return - } - enc.grow(len(key) + len(*v) + 5) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.writeBytes(*v) -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_interface.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_interface.go deleted file mode 100644 index c4692e5fc..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_interface.go +++ /dev/null @@ -1,173 +0,0 @@ -package gojay - -import ( - "fmt" -) - -// Encode encodes a value to JSON. -// -// If Encode cannot find a way to encode the type to JSON -// it will return an InvalidMarshalError. -func (enc *Encoder) Encode(v interface{}) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - switch vt := v.(type) { - case string: - return enc.EncodeString(vt) - case bool: - return enc.EncodeBool(vt) - case MarshalerJSONArray: - return enc.EncodeArray(vt) - case MarshalerJSONObject: - return enc.EncodeObject(vt) - case int: - return enc.EncodeInt(vt) - case int64: - return enc.EncodeInt64(vt) - case int32: - return enc.EncodeInt(int(vt)) - case int8: - return enc.EncodeInt(int(vt)) - case uint64: - return enc.EncodeUint64(vt) - case uint32: - return enc.EncodeInt(int(vt)) - case uint16: - return enc.EncodeInt(int(vt)) - case uint8: - return enc.EncodeInt(int(vt)) - case float64: - return enc.EncodeFloat(vt) - case float32: - return enc.EncodeFloat32(vt) - case *EmbeddedJSON: - return enc.EncodeEmbeddedJSON(vt) - default: - return InvalidMarshalError(fmt.Sprintf(invalidMarshalErrorMsg, vt)) - } -} - -// AddInterface adds an interface{} to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddInterface(value interface{}) { - switch vt := value.(type) { - case string: - enc.AddString(vt) - case bool: - enc.AddBool(vt) - case MarshalerJSONArray: - enc.AddArray(vt) - case MarshalerJSONObject: - enc.AddObject(vt) - case int: - enc.AddInt(vt) - case int64: - enc.AddInt(int(vt)) - case int32: - enc.AddInt(int(vt)) - case int8: - enc.AddInt(int(vt)) - case uint64: - enc.AddUint64(vt) - case uint32: - enc.AddInt(int(vt)) - case uint16: - enc.AddInt(int(vt)) - case uint8: - enc.AddInt(int(vt)) - case float64: - enc.AddFloat(vt) - case float32: - enc.AddFloat32(vt) - default: - if vt != nil { - enc.err = InvalidMarshalError(fmt.Sprintf(invalidMarshalErrorMsg, vt)) - return - } - return - } -} - -// AddInterfaceKey adds an interface{} to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddInterfaceKey(key string, value interface{}) { - switch vt := value.(type) { - case string: - enc.AddStringKey(key, vt) - case bool: - enc.AddBoolKey(key, vt) - case MarshalerJSONArray: - enc.AddArrayKey(key, vt) - case MarshalerJSONObject: - enc.AddObjectKey(key, vt) - case int: - enc.AddIntKey(key, vt) - case int64: - enc.AddIntKey(key, int(vt)) - case int32: - enc.AddIntKey(key, int(vt)) - case int16: - enc.AddIntKey(key, int(vt)) - case int8: - enc.AddIntKey(key, int(vt)) - case uint64: - enc.AddIntKey(key, int(vt)) - case uint32: - enc.AddIntKey(key, int(vt)) - case uint16: - enc.AddIntKey(key, int(vt)) - case uint8: - enc.AddIntKey(key, int(vt)) - case float64: - enc.AddFloatKey(key, vt) - case float32: - enc.AddFloat32Key(key, vt) - default: - if vt != nil { - enc.err = InvalidMarshalError(fmt.Sprintf(invalidMarshalErrorMsg, vt)) - return - } - return - } -} - -// AddInterfaceKeyOmitEmpty adds an interface{} to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddInterfaceKeyOmitEmpty(key string, v interface{}) { - switch vt := v.(type) { - case string: - enc.AddStringKeyOmitEmpty(key, vt) - case bool: - enc.AddBoolKeyOmitEmpty(key, vt) - case MarshalerJSONArray: - enc.AddArrayKeyOmitEmpty(key, vt) - case MarshalerJSONObject: - enc.AddObjectKeyOmitEmpty(key, vt) - case int: - enc.AddIntKeyOmitEmpty(key, vt) - case int64: - enc.AddIntKeyOmitEmpty(key, int(vt)) - case int32: - enc.AddIntKeyOmitEmpty(key, int(vt)) - case int16: - enc.AddIntKeyOmitEmpty(key, int(vt)) - case int8: - enc.AddIntKeyOmitEmpty(key, int(vt)) - case uint64: - enc.AddIntKeyOmitEmpty(key, int(vt)) - case uint32: - enc.AddIntKeyOmitEmpty(key, int(vt)) - case uint16: - enc.AddIntKeyOmitEmpty(key, int(vt)) - case uint8: - enc.AddIntKeyOmitEmpty(key, int(vt)) - case float64: - enc.AddFloatKeyOmitEmpty(key, vt) - case float32: - enc.AddFloat32KeyOmitEmpty(key, vt) - default: - if vt != nil { - enc.err = InvalidMarshalError(fmt.Sprintf(invalidMarshalErrorMsg, vt)) - return - } - return - } -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_null.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_null.go deleted file mode 100644 index cec4e639a..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_null.go +++ /dev/null @@ -1,39 +0,0 @@ -package gojay - -// AddNull adds a `null` to be encoded. Must be used while encoding an array.` -func (enc *Encoder) AddNull() { - enc.Null() -} - -// Null adds a `null` to be encoded. Must be used while encoding an array.` -func (enc *Encoder) Null() { - enc.grow(5) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.writeBytes(nullBytes) -} - -// AddNullKey adds a `null` to be encoded. Must be used while encoding an array.` -func (enc *Encoder) AddNullKey(key string) { - enc.NullKey(key) -} - -// NullKey adds a `null` to be encoded. Must be used while encoding an array.` -func (enc *Encoder) NullKey(key string) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(5 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.writeBytes(nullBytes) -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number.go deleted file mode 100644 index 53affb903..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number.go +++ /dev/null @@ -1 +0,0 @@ -package gojay diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number_float.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number_float.go deleted file mode 100644 index b45f8442a..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number_float.go +++ /dev/null @@ -1,368 +0,0 @@ -package gojay - -import "strconv" - -// EncodeFloat encodes a float64 to JSON -func (enc *Encoder) EncodeFloat(n float64) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeFloat(n) - _, err := enc.Write() - if err != nil { - return err - } - return nil -} - -// encodeFloat encodes a float64 to JSON -func (enc *Encoder) encodeFloat(n float64) ([]byte, error) { - enc.buf = strconv.AppendFloat(enc.buf, n, 'f', -1, 64) - return enc.buf, nil -} - -// EncodeFloat32 encodes a float32 to JSON -func (enc *Encoder) EncodeFloat32(n float32) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeFloat32(n) - _, err := enc.Write() - if err != nil { - return err - } - return nil -} - -func (enc *Encoder) encodeFloat32(n float32) ([]byte, error) { - enc.buf = strconv.AppendFloat(enc.buf, float64(n), 'f', -1, 32) - return enc.buf, nil -} - -// AddFloat adds a float64 to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddFloat(v float64) { - enc.Float64(v) -} - -// AddFloatOmitEmpty adds a float64 to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddFloatOmitEmpty(v float64) { - enc.Float64OmitEmpty(v) -} - -// AddFloatNullEmpty adds a float64 to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddFloatNullEmpty(v float64) { - enc.Float64NullEmpty(v) -} - -// Float adds a float64 to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Float(v float64) { - enc.Float64(v) -} - -// FloatOmitEmpty adds a float64 to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) FloatOmitEmpty(v float64) { - enc.Float64OmitEmpty(v) -} - -// FloatNullEmpty adds a float64 to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) FloatNullEmpty(v float64) { - enc.Float64NullEmpty(v) -} - -// AddFloatKey adds a float64 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddFloatKey(key string, v float64) { - enc.Float64Key(key, v) -} - -// AddFloatKeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddFloatKeyOmitEmpty(key string, v float64) { - enc.Float64KeyOmitEmpty(key, v) -} - -// AddFloatKeyNullEmpty adds a float64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddFloatKeyNullEmpty(key string, v float64) { - enc.Float64KeyNullEmpty(key, v) -} - -// FloatKey adds a float64 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) FloatKey(key string, v float64) { - enc.Float64Key(key, v) -} - -// FloatKeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key -func (enc *Encoder) FloatKeyOmitEmpty(key string, v float64) { - enc.Float64KeyOmitEmpty(key, v) -} - -// FloatKeyNullEmpty adds a float64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key -func (enc *Encoder) FloatKeyNullEmpty(key string, v float64) { - enc.Float64KeyNullEmpty(key, v) -} - -// AddFloat64 adds a float64 to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddFloat64(v float64) { - enc.Float(v) -} - -// AddFloat64OmitEmpty adds a float64 to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddFloat64OmitEmpty(v float64) { - enc.FloatOmitEmpty(v) -} - -// Float64 adds a float64 to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Float64(v float64) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64) -} - -// Float64OmitEmpty adds a float64 to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Float64OmitEmpty(v float64) { - if v == 0 { - return - } - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64) -} - -// Float64NullEmpty adds a float64 to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Float64NullEmpty(v float64) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - if v == 0 { - enc.writeBytes(nullBytes) - return - } - enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64) -} - -// AddFloat64Key adds a float64 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddFloat64Key(key string, v float64) { - enc.FloatKey(key, v) -} - -// AddFloat64KeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddFloat64KeyOmitEmpty(key string, v float64) { - enc.FloatKeyOmitEmpty(key, v) -} - -// Float64Key adds a float64 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) Float64Key(key string, value float64) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.grow(10) - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendFloat(enc.buf, value, 'f', -1, 64) -} - -// Float64KeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key -func (enc *Encoder) Float64KeyOmitEmpty(key string, v float64) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - if v == 0 { - return - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64) -} - -// Float64KeyNullEmpty adds a float64 to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Float64KeyNullEmpty(key string, v float64) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - if v == 0 { - enc.writeBytes(nullBytes) - return - } - enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64) -} - -// AddFloat32 adds a float32 to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddFloat32(v float32) { - enc.Float32(v) -} - -// AddFloat32OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddFloat32OmitEmpty(v float32) { - enc.Float32OmitEmpty(v) -} - -// AddFloat32NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddFloat32NullEmpty(v float32) { - enc.Float32NullEmpty(v) -} - -// Float32 adds a float32 to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Float32(v float32) { - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) -} - -// Float32OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Float32OmitEmpty(v float32) { - if v == 0 { - return - } - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) -} - -// Float32NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Float32NullEmpty(v float32) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - if v == 0 { - enc.writeBytes(nullBytes) - return - } - enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) -} - -// AddFloat32Key adds a float32 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddFloat32Key(key string, v float32) { - enc.Float32Key(key, v) -} - -// AddFloat32KeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddFloat32KeyOmitEmpty(key string, v float32) { - enc.Float32KeyOmitEmpty(key, v) -} - -// AddFloat32KeyNullEmpty adds a float64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddFloat32KeyNullEmpty(key string, v float32) { - enc.Float32KeyNullEmpty(key, v) -} - -// Float32Key adds a float32 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) Float32Key(key string, v float32) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeByte('"') - enc.writeByte(':') - enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) -} - -// Float32KeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key -func (enc *Encoder) Float32KeyOmitEmpty(key string, v float32) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - if v == 0 { - return - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) -} - -// Float32KeyNullEmpty adds a float64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key -func (enc *Encoder) Float32KeyNullEmpty(key string, v float32) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - if v == 0 { - enc.writeBytes(nullBytes) - return - } - enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32) -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number_int.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number_int.go deleted file mode 100644 index 2c4bbe343..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number_int.go +++ /dev/null @@ -1,500 +0,0 @@ -package gojay - -import "strconv" - -// EncodeInt encodes an int to JSON -func (enc *Encoder) EncodeInt(n int) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeInt(n) - _, err := enc.Write() - if err != nil { - return err - } - return nil -} - -// encodeInt encodes an int to JSON -func (enc *Encoder) encodeInt(n int) ([]byte, error) { - enc.buf = strconv.AppendInt(enc.buf, int64(n), 10) - return enc.buf, nil -} - -// EncodeInt64 encodes an int64 to JSON -func (enc *Encoder) EncodeInt64(n int64) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeInt64(n) - _, err := enc.Write() - if err != nil { - return err - } - return nil -} - -// encodeInt64 encodes an int to JSON -func (enc *Encoder) encodeInt64(n int64) ([]byte, error) { - enc.buf = strconv.AppendInt(enc.buf, n, 10) - return enc.buf, nil -} - -// AddInt adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddInt(v int) { - enc.Int(v) -} - -// AddIntOmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddIntOmitEmpty(v int) { - enc.IntOmitEmpty(v) -} - -// AddIntNullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddIntNullEmpty(v int) { - enc.IntNullEmpty(v) -} - -// Int adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Int(v int) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) -} - -// IntOmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) IntOmitEmpty(v int) { - if v == 0 { - return - } - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) -} - -// IntNullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) IntNullEmpty(v int) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - if v == 0 { - enc.writeBytes(nullBytes) - return - } - enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) -} - -// AddIntKey adds an int to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddIntKey(key string, v int) { - enc.IntKey(key, v) -} - -// AddIntKeyOmitEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddIntKeyOmitEmpty(key string, v int) { - enc.IntKeyOmitEmpty(key, v) -} - -// AddIntKeyNullEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddIntKeyNullEmpty(key string, v int) { - enc.IntKeyNullEmpty(key, v) -} - -// IntKey adds an int to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) IntKey(key string, v int) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) -} - -// IntKeyOmitEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) IntKeyOmitEmpty(key string, v int) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - if v == 0 { - return - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' && r != '[' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) -} - -// IntKeyNullEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) IntKeyNullEmpty(key string, v int) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' && r != '[' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - if v == 0 { - enc.writeBytes(nullBytes) - return - } - enc.buf = strconv.AppendInt(enc.buf, int64(v), 10) -} - -// AddInt64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddInt64(v int64) { - enc.Int64(v) -} - -// AddInt64OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddInt64OmitEmpty(v int64) { - enc.Int64OmitEmpty(v) -} - -// AddInt64NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddInt64NullEmpty(v int64) { - enc.Int64NullEmpty(v) -} - -// Int64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Int64(v int64) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendInt(enc.buf, v, 10) -} - -// Int64OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Int64OmitEmpty(v int64) { - if v == 0 { - return - } - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendInt(enc.buf, v, 10) -} - -// Int64NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Int64NullEmpty(v int64) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - if v == 0 { - enc.writeBytes(nullBytes) - return - } - enc.buf = strconv.AppendInt(enc.buf, v, 10) -} - -// AddInt64Key adds an int64 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddInt64Key(key string, v int64) { - enc.Int64Key(key, v) -} - -// AddInt64KeyOmitEmpty adds an int64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddInt64KeyOmitEmpty(key string, v int64) { - enc.Int64KeyOmitEmpty(key, v) -} - -// AddInt64KeyNullEmpty adds an int64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddInt64KeyNullEmpty(key string, v int64) { - enc.Int64KeyNullEmpty(key, v) -} - -// Int64Key adds an int64 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) Int64Key(key string, v int64) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendInt(enc.buf, v, 10) -} - -// Int64KeyOmitEmpty adds an int64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Int64KeyOmitEmpty(key string, v int64) { - if v == 0 { - return - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendInt(enc.buf, v, 10) -} - -// Int64KeyNullEmpty adds an int64 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Int64KeyNullEmpty(key string, v int64) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - if v == 0 { - enc.writeBytes(nullBytes) - return - } - enc.buf = strconv.AppendInt(enc.buf, v, 10) -} - -// AddInt32 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddInt32(v int32) { - enc.Int64(int64(v)) -} - -// AddInt32OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddInt32OmitEmpty(v int32) { - enc.Int64OmitEmpty(int64(v)) -} - -// AddInt32NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddInt32NullEmpty(v int32) { - enc.Int64NullEmpty(int64(v)) -} - -// Int32 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Int32(v int32) { - enc.Int64(int64(v)) -} - -// Int32OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Int32OmitEmpty(v int32) { - enc.Int64OmitEmpty(int64(v)) -} - -// Int32NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Int32NullEmpty(v int32) { - enc.Int64NullEmpty(int64(v)) -} - -// AddInt32Key adds an int32 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddInt32Key(key string, v int32) { - enc.Int64Key(key, int64(v)) -} - -// AddInt32KeyOmitEmpty adds an int32 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddInt32KeyOmitEmpty(key string, v int32) { - enc.Int64KeyOmitEmpty(key, int64(v)) -} - -// Int32Key adds an int32 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) Int32Key(key string, v int32) { - enc.Int64Key(key, int64(v)) -} - -// Int32KeyOmitEmpty adds an int32 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Int32KeyOmitEmpty(key string, v int32) { - enc.Int64KeyOmitEmpty(key, int64(v)) -} - -// Int32KeyNullEmpty adds an int32 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Int32KeyNullEmpty(key string, v int32) { - enc.Int64KeyNullEmpty(key, int64(v)) -} - -// AddInt16 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddInt16(v int16) { - enc.Int64(int64(v)) -} - -// AddInt16OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddInt16OmitEmpty(v int16) { - enc.Int64OmitEmpty(int64(v)) -} - -// Int16 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Int16(v int16) { - enc.Int64(int64(v)) -} - -// Int16OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Int16OmitEmpty(v int16) { - enc.Int64OmitEmpty(int64(v)) -} - -// Int16NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Int16NullEmpty(v int16) { - enc.Int64NullEmpty(int64(v)) -} - -// AddInt16Key adds an int16 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddInt16Key(key string, v int16) { - enc.Int64Key(key, int64(v)) -} - -// AddInt16KeyOmitEmpty adds an int16 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddInt16KeyOmitEmpty(key string, v int16) { - enc.Int64KeyOmitEmpty(key, int64(v)) -} - -// AddInt16KeyNullEmpty adds an int16 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddInt16KeyNullEmpty(key string, v int16) { - enc.Int64KeyNullEmpty(key, int64(v)) -} - -// Int16Key adds an int16 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) Int16Key(key string, v int16) { - enc.Int64Key(key, int64(v)) -} - -// Int16KeyOmitEmpty adds an int16 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Int16KeyOmitEmpty(key string, v int16) { - enc.Int64KeyOmitEmpty(key, int64(v)) -} - -// Int16KeyNullEmpty adds an int16 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Int16KeyNullEmpty(key string, v int16) { - enc.Int64KeyNullEmpty(key, int64(v)) -} - -// AddInt8 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddInt8(v int8) { - enc.Int64(int64(v)) -} - -// AddInt8OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddInt8OmitEmpty(v int8) { - enc.Int64OmitEmpty(int64(v)) -} - -// AddInt8NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddInt8NullEmpty(v int8) { - enc.Int64NullEmpty(int64(v)) -} - -// Int8 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Int8(v int8) { - enc.Int64(int64(v)) -} - -// Int8OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Int8OmitEmpty(v int8) { - enc.Int64OmitEmpty(int64(v)) -} - -// Int8NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Int8NullEmpty(v int8) { - enc.Int64NullEmpty(int64(v)) -} - -// AddInt8Key adds an int8 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddInt8Key(key string, v int8) { - enc.Int64Key(key, int64(v)) -} - -// AddInt8KeyOmitEmpty adds an int8 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddInt8KeyOmitEmpty(key string, v int8) { - enc.Int64KeyOmitEmpty(key, int64(v)) -} - -// AddInt8KeyNullEmpty adds an int8 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddInt8KeyNullEmpty(key string, v int8) { - enc.Int64KeyNullEmpty(key, int64(v)) -} - -// Int8Key adds an int8 to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) Int8Key(key string, v int8) { - enc.Int64Key(key, int64(v)) -} - -// Int8KeyOmitEmpty adds an int8 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Int8KeyOmitEmpty(key string, v int8) { - enc.Int64KeyOmitEmpty(key, int64(v)) -} - -// Int8KeyNullEmpty adds an int8 to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Int8KeyNullEmpty(key string, v int8) { - enc.Int64KeyNullEmpty(key, int64(v)) -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number_uint.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number_uint.go deleted file mode 100644 index cd69b13fd..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_number_uint.go +++ /dev/null @@ -1,362 +0,0 @@ -package gojay - -import "strconv" - -// EncodeUint64 encodes an int64 to JSON -func (enc *Encoder) EncodeUint64(n uint64) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeUint64(n) - _, err := enc.Write() - if err != nil { - return err - } - return nil -} - -// encodeUint64 encodes an int to JSON -func (enc *Encoder) encodeUint64(n uint64) ([]byte, error) { - enc.buf = strconv.AppendUint(enc.buf, n, 10) - return enc.buf, nil -} - -// AddUint64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddUint64(v uint64) { - enc.Uint64(v) -} - -// AddUint64OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddUint64OmitEmpty(v uint64) { - enc.Uint64OmitEmpty(v) -} - -// AddUint64NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddUint64NullEmpty(v uint64) { - enc.Uint64NullEmpty(v) -} - -// Uint64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Uint64(v uint64) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendUint(enc.buf, v, 10) -} - -// Uint64OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Uint64OmitEmpty(v uint64) { - if v == 0 { - return - } - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.buf = strconv.AppendUint(enc.buf, v, 10) -} - -// Uint64NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Uint64NullEmpty(v uint64) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - if v == 0 { - enc.writeBytes(nullBytes) - return - } - enc.buf = strconv.AppendUint(enc.buf, v, 10) -} - -// AddUint64Key adds an int to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddUint64Key(key string, v uint64) { - enc.Uint64Key(key, v) -} - -// AddUint64KeyOmitEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddUint64KeyOmitEmpty(key string, v uint64) { - enc.Uint64KeyOmitEmpty(key, v) -} - -// AddUint64KeyNullEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddUint64KeyNullEmpty(key string, v uint64) { - enc.Uint64KeyNullEmpty(key, v) -} - -// Uint64Key adds an int to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) Uint64Key(key string, v uint64) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendUint(enc.buf, v, 10) -} - -// Uint64KeyOmitEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Uint64KeyOmitEmpty(key string, v uint64) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - if v == 0 { - return - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' && r != '[' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - enc.buf = strconv.AppendUint(enc.buf, v, 10) -} - -// Uint64KeyNullEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Uint64KeyNullEmpty(key string, v uint64) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' && r != '[' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - if v == 0 { - enc.writeBytes(nullBytes) - return - } - enc.buf = strconv.AppendUint(enc.buf, v, 10) -} - -// AddUint32 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddUint32(v uint32) { - enc.Uint64(uint64(v)) -} - -// AddUint32OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddUint32OmitEmpty(v uint32) { - enc.Uint64OmitEmpty(uint64(v)) -} - -// AddUint32NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddUint32NullEmpty(v uint32) { - enc.Uint64NullEmpty(uint64(v)) -} - -// Uint32 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Uint32(v uint32) { - enc.Uint64(uint64(v)) -} - -// Uint32OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Uint32OmitEmpty(v uint32) { - enc.Uint64OmitEmpty(uint64(v)) -} - -// Uint32NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Uint32NullEmpty(v uint32) { - enc.Uint64NullEmpty(uint64(v)) -} - -// AddUint32Key adds an int to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddUint32Key(key string, v uint32) { - enc.Uint64Key(key, uint64(v)) -} - -// AddUint32KeyOmitEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddUint32KeyOmitEmpty(key string, v uint32) { - enc.Uint64KeyOmitEmpty(key, uint64(v)) -} - -// AddUint32KeyNullEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddUint32KeyNullEmpty(key string, v uint32) { - enc.Uint64KeyNullEmpty(key, uint64(v)) -} - -// Uint32Key adds an int to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) Uint32Key(key string, v uint32) { - enc.Uint64Key(key, uint64(v)) -} - -// Uint32KeyOmitEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Uint32KeyOmitEmpty(key string, v uint32) { - enc.Uint64KeyOmitEmpty(key, uint64(v)) -} - -// Uint32KeyNullEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Uint32KeyNullEmpty(key string, v uint32) { - enc.Uint64KeyNullEmpty(key, uint64(v)) -} - -// AddUint16 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddUint16(v uint16) { - enc.Uint64(uint64(v)) -} - -// AddUint16OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddUint16OmitEmpty(v uint16) { - enc.Uint64OmitEmpty(uint64(v)) -} - -// AddUint16NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddUint16NullEmpty(v uint16) { - enc.Uint64NullEmpty(uint64(v)) -} - -// Uint16 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Uint16(v uint16) { - enc.Uint64(uint64(v)) -} - -// Uint16OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Uint16OmitEmpty(v uint16) { - enc.Uint64OmitEmpty(uint64(v)) -} - -// Uint16NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Uint16NullEmpty(v uint16) { - enc.Uint64NullEmpty(uint64(v)) -} - -// AddUint16Key adds an int to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddUint16Key(key string, v uint16) { - enc.Uint64Key(key, uint64(v)) -} - -// AddUint16KeyOmitEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddUint16KeyOmitEmpty(key string, v uint16) { - enc.Uint64KeyOmitEmpty(key, uint64(v)) -} - -// AddUint16KeyNullEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddUint16KeyNullEmpty(key string, v uint16) { - enc.Uint64KeyNullEmpty(key, uint64(v)) -} - -// Uint16Key adds an int to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) Uint16Key(key string, v uint16) { - enc.Uint64Key(key, uint64(v)) -} - -// Uint16KeyOmitEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Uint16KeyOmitEmpty(key string, v uint16) { - enc.Uint64KeyOmitEmpty(key, uint64(v)) -} - -// Uint16KeyNullEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Uint16KeyNullEmpty(key string, v uint16) { - enc.Uint64KeyNullEmpty(key, uint64(v)) -} - -// AddUint8 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddUint8(v uint8) { - enc.Uint64(uint64(v)) -} - -// AddUint8OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddUint8OmitEmpty(v uint8) { - enc.Uint64OmitEmpty(uint64(v)) -} - -// AddUint8NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) AddUint8NullEmpty(v uint8) { - enc.Uint64NullEmpty(uint64(v)) -} - -// Uint8 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Uint8(v uint8) { - enc.Uint64(uint64(v)) -} - -// Uint8OmitEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Uint8OmitEmpty(v uint8) { - enc.Uint64OmitEmpty(uint64(v)) -} - -// Uint8NullEmpty adds an int to be encoded and skips it if its value is 0, -// must be used inside a slice or array encoding (does not encode a key). -func (enc *Encoder) Uint8NullEmpty(v uint8) { - enc.Uint64NullEmpty(uint64(v)) -} - -// AddUint8Key adds an int to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddUint8Key(key string, v uint8) { - enc.Uint64Key(key, uint64(v)) -} - -// AddUint8KeyOmitEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddUint8KeyOmitEmpty(key string, v uint8) { - enc.Uint64KeyOmitEmpty(key, uint64(v)) -} - -// AddUint8KeyNullEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) AddUint8KeyNullEmpty(key string, v uint8) { - enc.Uint64KeyNullEmpty(key, uint64(v)) -} - -// Uint8Key adds an int to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) Uint8Key(key string, v uint8) { - enc.Uint64Key(key, uint64(v)) -} - -// Uint8KeyOmitEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Uint8KeyOmitEmpty(key string, v uint8) { - enc.Uint64KeyOmitEmpty(key, uint64(v)) -} - -// Uint8KeyNullEmpty adds an int to be encoded and skips it if its value is 0. -// Must be used inside an object as it will encode a key. -func (enc *Encoder) Uint8KeyNullEmpty(key string, v uint8) { - enc.Uint64KeyNullEmpty(key, uint64(v)) -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_object.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_object.go deleted file mode 100644 index 5f2c8cf3f..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_object.go +++ /dev/null @@ -1,400 +0,0 @@ -package gojay - -var objKeyStr = []byte(`":"`) -var objKeyObj = []byte(`":{`) -var objKeyArr = []byte(`":[`) -var objKey = []byte(`":`) - -// EncodeObject encodes an object to JSON -func (enc *Encoder) EncodeObject(v MarshalerJSONObject) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, err := enc.encodeObject(v) - if err != nil { - enc.err = err - return err - } - _, err = enc.Write() - if err != nil { - enc.err = err - return err - } - return nil -} - -// EncodeObjectKeys encodes an object to JSON -func (enc *Encoder) EncodeObjectKeys(v MarshalerJSONObject, keys []string) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - enc.hasKeys = true - enc.keys = keys - _, err := enc.encodeObject(v) - if err != nil { - enc.err = err - return err - } - _, err = enc.Write() - if err != nil { - enc.err = err - return err - } - return nil -} - -func (enc *Encoder) encodeObject(v MarshalerJSONObject) ([]byte, error) { - enc.grow(512) - enc.writeByte('{') - if !v.IsNil() { - v.MarshalJSONObject(enc) - } - if enc.hasKeys { - enc.hasKeys = false - enc.keys = nil - } - enc.writeByte('}') - return enc.buf, enc.err -} - -// AddObject adds an object to be encoded, must be used inside a slice or array encoding (does not encode a key) -// value must implement MarshalerJSONObject -func (enc *Encoder) AddObject(v MarshalerJSONObject) { - enc.Object(v) -} - -// AddObjectOmitEmpty adds an object to be encoded or skips it if IsNil returns true. -// Must be used inside a slice or array encoding (does not encode a key) -// value must implement MarshalerJSONObject -func (enc *Encoder) AddObjectOmitEmpty(v MarshalerJSONObject) { - enc.ObjectOmitEmpty(v) -} - -// AddObjectNullEmpty adds an object to be encoded or skips it if IsNil returns true. -// Must be used inside a slice or array encoding (does not encode a key) -// value must implement MarshalerJSONObject -func (enc *Encoder) AddObjectNullEmpty(v MarshalerJSONObject) { - enc.ObjectNullEmpty(v) -} - -// AddObjectKey adds a struct to be encoded, must be used inside an object as it will encode a key -// value must implement MarshalerJSONObject -func (enc *Encoder) AddObjectKey(key string, v MarshalerJSONObject) { - enc.ObjectKey(key, v) -} - -// AddObjectKeyOmitEmpty adds an object to be encoded or skips it if IsNil returns true. -// Must be used inside a slice or array encoding (does not encode a key) -// value must implement MarshalerJSONObject -func (enc *Encoder) AddObjectKeyOmitEmpty(key string, v MarshalerJSONObject) { - enc.ObjectKeyOmitEmpty(key, v) -} - -// AddObjectKeyNullEmpty adds an object to be encoded or skips it if IsNil returns true. -// Must be used inside a slice or array encoding (does not encode a key) -// value must implement MarshalerJSONObject -func (enc *Encoder) AddObjectKeyNullEmpty(key string, v MarshalerJSONObject) { - enc.ObjectKeyNullEmpty(key, v) -} - -// Object adds an object to be encoded, must be used inside a slice or array encoding (does not encode a key) -// value must implement MarshalerJSONObject -func (enc *Encoder) Object(v MarshalerJSONObject) { - if v.IsNil() { - enc.grow(2) - r := enc.getPreviousRune() - if r != '{' && r != '[' { - enc.writeByte(',') - } - enc.writeByte('{') - enc.writeByte('}') - return - } - enc.grow(4) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.writeByte('{') - - var origHasKeys = enc.hasKeys - var origKeys = enc.keys - enc.hasKeys = false - enc.keys = nil - - v.MarshalJSONObject(enc) - - enc.hasKeys = origHasKeys - enc.keys = origKeys - - enc.writeByte('}') -} - -// ObjectWithKeys adds an object to be encoded, must be used inside a slice or array encoding (does not encode a key) -// value must implement MarshalerJSONObject. It will only encode the keys in keys. -func (enc *Encoder) ObjectWithKeys(v MarshalerJSONObject, keys []string) { - if v.IsNil() { - enc.grow(2) - r := enc.getPreviousRune() - if r != '{' && r != '[' { - enc.writeByte(',') - } - enc.writeByte('{') - enc.writeByte('}') - return - } - enc.grow(4) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.writeByte('{') - - var origKeys = enc.keys - var origHasKeys = enc.hasKeys - enc.hasKeys = true - enc.keys = keys - - v.MarshalJSONObject(enc) - - enc.hasKeys = origHasKeys - enc.keys = origKeys - - enc.writeByte('}') -} - -// ObjectOmitEmpty adds an object to be encoded or skips it if IsNil returns true. -// Must be used inside a slice or array encoding (does not encode a key) -// value must implement MarshalerJSONObject -func (enc *Encoder) ObjectOmitEmpty(v MarshalerJSONObject) { - if v.IsNil() { - return - } - enc.grow(2) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.writeByte('{') - - var origHasKeys = enc.hasKeys - var origKeys = enc.keys - enc.hasKeys = false - enc.keys = nil - - v.MarshalJSONObject(enc) - - enc.hasKeys = origHasKeys - enc.keys = origKeys - - enc.writeByte('}') -} - -// ObjectNullEmpty adds an object to be encoded or skips it if IsNil returns true. -// Must be used inside a slice or array encoding (does not encode a key) -// value must implement MarshalerJSONObject -func (enc *Encoder) ObjectNullEmpty(v MarshalerJSONObject) { - enc.grow(2) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - if v.IsNil() { - enc.writeBytes(nullBytes) - return - } - enc.writeByte('{') - - var origHasKeys = enc.hasKeys - var origKeys = enc.keys - enc.hasKeys = false - enc.keys = nil - - v.MarshalJSONObject(enc) - - enc.hasKeys = origHasKeys - enc.keys = origKeys - - enc.writeByte('}') -} - -// ObjectKey adds a struct to be encoded, must be used inside an object as it will encode a key -// value must implement MarshalerJSONObject -func (enc *Encoder) ObjectKey(key string, v MarshalerJSONObject) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - if v.IsNil() { - enc.grow(2 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKeyObj) - enc.writeByte('}') - return - } - enc.grow(5 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKeyObj) - - var origHasKeys = enc.hasKeys - var origKeys = enc.keys - enc.hasKeys = false - enc.keys = nil - - v.MarshalJSONObject(enc) - - enc.hasKeys = origHasKeys - enc.keys = origKeys - - enc.writeByte('}') -} - -// ObjectKeyWithKeys adds a struct to be encoded, must be used inside an object as it will encode a key. -// Value must implement MarshalerJSONObject. It will only encode the keys in keys. -func (enc *Encoder) ObjectKeyWithKeys(key string, value MarshalerJSONObject, keys []string) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - if value.IsNil() { - enc.grow(2 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKeyObj) - enc.writeByte('}') - return - } - enc.grow(5 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKeyObj) - var origKeys = enc.keys - var origHasKeys = enc.hasKeys - enc.hasKeys = true - enc.keys = keys - value.MarshalJSONObject(enc) - enc.hasKeys = origHasKeys - enc.keys = origKeys - enc.writeByte('}') -} - -// ObjectKeyOmitEmpty adds an object to be encoded or skips it if IsNil returns true. -// Must be used inside a slice or array encoding (does not encode a key) -// value must implement MarshalerJSONObject -func (enc *Encoder) ObjectKeyOmitEmpty(key string, v MarshalerJSONObject) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - if v.IsNil() { - return - } - enc.grow(5 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKeyObj) - - var origHasKeys = enc.hasKeys - var origKeys = enc.keys - enc.hasKeys = false - enc.keys = nil - - v.MarshalJSONObject(enc) - - enc.hasKeys = origHasKeys - enc.keys = origKeys - - enc.writeByte('}') -} - -// ObjectKeyNullEmpty adds an object to be encoded or skips it if IsNil returns true. -// Must be used inside a slice or array encoding (does not encode a key) -// value must implement MarshalerJSONObject -func (enc *Encoder) ObjectKeyNullEmpty(key string, v MarshalerJSONObject) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(5 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.writeStringEscape(key) - enc.writeBytes(objKey) - if v.IsNil() { - enc.writeBytes(nullBytes) - return - } - enc.writeByte('{') - - var origHasKeys = enc.hasKeys - var origKeys = enc.keys - enc.hasKeys = false - enc.keys = nil - - v.MarshalJSONObject(enc) - - enc.hasKeys = origHasKeys - enc.keys = origKeys - - enc.writeByte('}') -} - -// EncodeObjectFunc is a custom func type implementing MarshaleObject. -// Use it to cast a func(*Encoder) to Marshal an object. -// -// enc := gojay.NewEncoder(io.Writer) -// enc.EncodeObject(gojay.EncodeObjectFunc(func(enc *gojay.Encoder) { -// enc.AddStringKey("hello", "world") -// })) -type EncodeObjectFunc func(*Encoder) - -// MarshalJSONObject implements MarshalerJSONObject. -func (f EncodeObjectFunc) MarshalJSONObject(enc *Encoder) { - f(enc) -} - -// IsNil implements MarshalerJSONObject. -func (f EncodeObjectFunc) IsNil() bool { - return f == nil -} - -func (enc *Encoder) keyExists(k string) bool { - if enc.keys == nil { - return false - } - for _, key := range enc.keys { - if key == k { - return true - } - } - return false -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_pool.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_pool.go deleted file mode 100644 index 3b2632253..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_pool.go +++ /dev/null @@ -1,50 +0,0 @@ -package gojay - -import ( - "io" - "sync" -) - -var encPool = sync.Pool{ - New: func() interface{} { - return NewEncoder(nil) - }, -} - -var streamEncPool = sync.Pool{ - New: func() interface{} { - return Stream.NewEncoder(nil) - }, -} - -func init() { - for i := 0; i < 32; i++ { - encPool.Put(NewEncoder(nil)) - } - for i := 0; i < 32; i++ { - streamEncPool.Put(Stream.NewEncoder(nil)) - } -} - -// NewEncoder returns a new encoder or borrows one from the pool -func NewEncoder(w io.Writer) *Encoder { - return &Encoder{w: w} -} - -// BorrowEncoder borrows an Encoder from the pool. -func BorrowEncoder(w io.Writer) *Encoder { - enc := encPool.Get().(*Encoder) - enc.w = w - enc.buf = enc.buf[:0] - enc.isPooled = 0 - enc.err = nil - enc.hasKeys = false - enc.keys = nil - return enc -} - -// Release sends back a Encoder to the pool. -func (enc *Encoder) Release() { - enc.isPooled = 1 - encPool.Put(enc) -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_slice.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_slice.go deleted file mode 100644 index 7d964df97..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_slice.go +++ /dev/null @@ -1,113 +0,0 @@ -package gojay - -// AddSliceString marshals the given []string s -func (enc *Encoder) AddSliceString(s []string) { - enc.SliceString(s) -} - -// SliceString marshals the given []string s -func (enc *Encoder) SliceString(s []string) { - enc.Array(EncodeArrayFunc(func(enc *Encoder) { - for _, str := range s { - enc.String(str) - } - })) -} - -// AddSliceStringKey marshals the given []string s -func (enc *Encoder) AddSliceStringKey(k string, s []string) { - enc.SliceStringKey(k, s) -} - -// SliceStringKey marshals the given []string s -func (enc *Encoder) SliceStringKey(k string, s []string) { - enc.ArrayKey(k, EncodeArrayFunc(func(enc *Encoder) { - for _, str := range s { - enc.String(str) - } - })) -} - -// AddSliceInt marshals the given []int s -func (enc *Encoder) AddSliceInt(s []int) { - enc.SliceInt(s) -} - -// SliceInt marshals the given []int s -func (enc *Encoder) SliceInt(s []int) { - enc.Array(EncodeArrayFunc(func(enc *Encoder) { - for _, i := range s { - enc.Int(i) - } - })) -} - -// AddSliceIntKey marshals the given []int s -func (enc *Encoder) AddSliceIntKey(k string, s []int) { - enc.SliceIntKey(k, s) -} - -// SliceIntKey marshals the given []int s -func (enc *Encoder) SliceIntKey(k string, s []int) { - enc.ArrayKey(k, EncodeArrayFunc(func(enc *Encoder) { - for _, i := range s { - enc.Int(i) - } - })) -} - -// AddSliceFloat64 marshals the given []float64 s -func (enc *Encoder) AddSliceFloat64(s []float64) { - enc.SliceFloat64(s) -} - -// SliceFloat64 marshals the given []float64 s -func (enc *Encoder) SliceFloat64(s []float64) { - enc.Array(EncodeArrayFunc(func(enc *Encoder) { - for _, i := range s { - enc.Float64(i) - } - })) -} - -// AddSliceFloat64Key marshals the given []float64 s -func (enc *Encoder) AddSliceFloat64Key(k string, s []float64) { - enc.SliceFloat64Key(k, s) -} - -// SliceFloat64Key marshals the given []float64 s -func (enc *Encoder) SliceFloat64Key(k string, s []float64) { - enc.ArrayKey(k, EncodeArrayFunc(func(enc *Encoder) { - for _, i := range s { - enc.Float64(i) - } - })) -} - -// AddSliceBool marshals the given []bool s -func (enc *Encoder) AddSliceBool(s []bool) { - enc.SliceBool(s) -} - -// SliceBool marshals the given []bool s -func (enc *Encoder) SliceBool(s []bool) { - enc.Array(EncodeArrayFunc(func(enc *Encoder) { - for _, i := range s { - enc.Bool(i) - } - })) -} - -// AddSliceBoolKey marshals the given []bool s -func (enc *Encoder) AddSliceBoolKey(k string, s []bool) { - enc.SliceBoolKey(k, s) -} - -// SliceBoolKey marshals the given []bool s -func (enc *Encoder) SliceBoolKey(k string, s []bool) { - enc.ArrayKey(k, EncodeArrayFunc(func(enc *Encoder) { - for _, i := range s { - enc.Bool(i) - } - })) -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_sqlnull.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_sqlnull.go deleted file mode 100644 index 04ff5962a..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_sqlnull.go +++ /dev/null @@ -1,377 +0,0 @@ -package gojay - -import "database/sql" - -// EncodeSQLNullString encodes a string to -func (enc *Encoder) EncodeSQLNullString(v *sql.NullString) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeString(v.String) - _, err := enc.Write() - if err != nil { - enc.err = err - return err - } - return nil -} - -// AddSQLNullString adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddSQLNullString(v *sql.NullString) { - enc.String(v.String) -} - -// AddSQLNullStringOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddSQLNullStringOmitEmpty(v *sql.NullString) { - if v != nil && v.Valid && v.String != "" { - enc.StringOmitEmpty(v.String) - } -} - -// AddSQLNullStringNullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddSQLNullStringNullEmpty(v *sql.NullString) { - if v != nil && v.Valid { - enc.StringNullEmpty(v.String) - } -} - -// AddSQLNullStringKey adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddSQLNullStringKey(key string, v *sql.NullString) { - enc.StringKey(key, v.String) -} - -// AddSQLNullStringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddSQLNullStringKeyOmitEmpty(key string, v *sql.NullString) { - if v != nil && v.Valid && v.String != "" { - enc.StringKeyOmitEmpty(key, v.String) - } -} - -// SQLNullString adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullString(v *sql.NullString) { - enc.String(v.String) -} - -// SQLNullStringOmitEmpty adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullStringOmitEmpty(v *sql.NullString) { - if v != nil && v.Valid && v.String != "" { - enc.String(v.String) - } -} - -// SQLNullStringNullEmpty adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullStringNullEmpty(v *sql.NullString) { - if v != nil && v.Valid { - enc.StringNullEmpty(v.String) - } -} - -// SQLNullStringKey adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullStringKey(key string, v *sql.NullString) { - enc.StringKey(key, v.String) -} - -// SQLNullStringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullStringKeyOmitEmpty(key string, v *sql.NullString) { - if v != nil && v.Valid && v.String != "" { - enc.StringKeyOmitEmpty(key, v.String) - } -} - -// SQLNullStringKeyNullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullStringKeyNullEmpty(key string, v *sql.NullString) { - if v != nil && v.Valid { - enc.StringKeyNullEmpty(key, v.String) - } -} - -// NullInt64 - -// EncodeSQLNullInt64 encodes a string to -func (enc *Encoder) EncodeSQLNullInt64(v *sql.NullInt64) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeInt64(v.Int64) - _, err := enc.Write() - if err != nil { - enc.err = err - return err - } - return nil -} - -// AddSQLNullInt64 adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddSQLNullInt64(v *sql.NullInt64) { - enc.Int64(v.Int64) -} - -// AddSQLNullInt64OmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddSQLNullInt64OmitEmpty(v *sql.NullInt64) { - if v != nil && v.Valid && v.Int64 != 0 { - enc.Int64OmitEmpty(v.Int64) - } -} - -// AddSQLNullInt64NullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddSQLNullInt64NullEmpty(v *sql.NullInt64) { - if v != nil && v.Valid { - enc.Int64NullEmpty(v.Int64) - } -} - -// AddSQLNullInt64Key adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddSQLNullInt64Key(key string, v *sql.NullInt64) { - enc.Int64Key(key, v.Int64) -} - -// AddSQLNullInt64KeyOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddSQLNullInt64KeyOmitEmpty(key string, v *sql.NullInt64) { - if v != nil && v.Valid && v.Int64 != 0 { - enc.Int64KeyOmitEmpty(key, v.Int64) - } -} - -// AddSQLNullInt64KeyNullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddSQLNullInt64KeyNullEmpty(key string, v *sql.NullInt64) { - if v != nil && v.Valid { - enc.Int64KeyNullEmpty(key, v.Int64) - } -} - -// SQLNullInt64 adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullInt64(v *sql.NullInt64) { - enc.Int64(v.Int64) -} - -// SQLNullInt64OmitEmpty adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullInt64OmitEmpty(v *sql.NullInt64) { - if v != nil && v.Valid && v.Int64 != 0 { - enc.Int64(v.Int64) - } -} - -// SQLNullInt64NullEmpty adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullInt64NullEmpty(v *sql.NullInt64) { - if v != nil && v.Valid { - enc.Int64NullEmpty(v.Int64) - } -} - -// SQLNullInt64Key adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullInt64Key(key string, v *sql.NullInt64) { - enc.Int64Key(key, v.Int64) -} - -// SQLNullInt64KeyOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullInt64KeyOmitEmpty(key string, v *sql.NullInt64) { - if v != nil && v.Valid && v.Int64 != 0 { - enc.Int64KeyOmitEmpty(key, v.Int64) - } -} - -// SQLNullInt64KeyNullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullInt64KeyNullEmpty(key string, v *sql.NullInt64) { - if v != nil && v.Valid { - enc.Int64KeyNullEmpty(key, v.Int64) - } -} - -// NullFloat64 - -// EncodeSQLNullFloat64 encodes a string to -func (enc *Encoder) EncodeSQLNullFloat64(v *sql.NullFloat64) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeFloat(v.Float64) - _, err := enc.Write() - if err != nil { - enc.err = err - return err - } - return nil -} - -// AddSQLNullFloat64 adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddSQLNullFloat64(v *sql.NullFloat64) { - enc.Float64(v.Float64) -} - -// AddSQLNullFloat64OmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddSQLNullFloat64OmitEmpty(v *sql.NullFloat64) { - if v != nil && v.Valid && v.Float64 != 0 { - enc.Float64OmitEmpty(v.Float64) - } -} - -// AddSQLNullFloat64NullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddSQLNullFloat64NullEmpty(v *sql.NullFloat64) { - if v != nil && v.Valid { - enc.Float64NullEmpty(v.Float64) - } -} - -// AddSQLNullFloat64Key adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddSQLNullFloat64Key(key string, v *sql.NullFloat64) { - enc.Float64Key(key, v.Float64) -} - -// AddSQLNullFloat64KeyOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddSQLNullFloat64KeyOmitEmpty(key string, v *sql.NullFloat64) { - if v != nil && v.Valid && v.Float64 != 0 { - enc.Float64KeyOmitEmpty(key, v.Float64) - } -} - -// AddSQLNullFloat64KeyNullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddSQLNullFloat64KeyNullEmpty(key string, v *sql.NullFloat64) { - if v != nil && v.Valid { - enc.Float64KeyNullEmpty(key, v.Float64) - } -} - -// SQLNullFloat64 adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullFloat64(v *sql.NullFloat64) { - enc.Float64(v.Float64) -} - -// SQLNullFloat64OmitEmpty adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullFloat64OmitEmpty(v *sql.NullFloat64) { - if v != nil && v.Valid && v.Float64 != 0 { - enc.Float64(v.Float64) - } -} - -// SQLNullFloat64NullEmpty adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullFloat64NullEmpty(v *sql.NullFloat64) { - if v != nil && v.Valid { - enc.Float64NullEmpty(v.Float64) - } -} - -// SQLNullFloat64Key adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullFloat64Key(key string, v *sql.NullFloat64) { - enc.Float64Key(key, v.Float64) -} - -// SQLNullFloat64KeyOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullFloat64KeyOmitEmpty(key string, v *sql.NullFloat64) { - if v != nil && v.Valid && v.Float64 != 0 { - enc.Float64KeyOmitEmpty(key, v.Float64) - } -} - -// SQLNullFloat64KeyNullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullFloat64KeyNullEmpty(key string, v *sql.NullFloat64) { - if v != nil && v.Valid { - enc.Float64KeyNullEmpty(key, v.Float64) - } -} - -// NullBool - -// EncodeSQLNullBool encodes a string to -func (enc *Encoder) EncodeSQLNullBool(v *sql.NullBool) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeBool(v.Bool) - _, err := enc.Write() - if err != nil { - enc.err = err - return err - } - return nil -} - -// AddSQLNullBool adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddSQLNullBool(v *sql.NullBool) { - enc.Bool(v.Bool) -} - -// AddSQLNullBoolOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddSQLNullBoolOmitEmpty(v *sql.NullBool) { - if v != nil && v.Valid && v.Bool != false { - enc.BoolOmitEmpty(v.Bool) - } -} - -// AddSQLNullBoolKey adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddSQLNullBoolKey(key string, v *sql.NullBool) { - enc.BoolKey(key, v.Bool) -} - -// AddSQLNullBoolKeyOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddSQLNullBoolKeyOmitEmpty(key string, v *sql.NullBool) { - if v != nil && v.Valid && v.Bool != false { - enc.BoolKeyOmitEmpty(key, v.Bool) - } -} - -// AddSQLNullBoolKeyNullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddSQLNullBoolKeyNullEmpty(key string, v *sql.NullBool) { - if v != nil && v.Valid { - enc.BoolKeyNullEmpty(key, v.Bool) - } -} - -// SQLNullBool adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullBool(v *sql.NullBool) { - enc.Bool(v.Bool) -} - -// SQLNullBoolOmitEmpty adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullBoolOmitEmpty(v *sql.NullBool) { - if v != nil && v.Valid && v.Bool != false { - enc.Bool(v.Bool) - } -} - -// SQLNullBoolNullEmpty adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullBoolNullEmpty(v *sql.NullBool) { - if v != nil && v.Valid { - enc.BoolNullEmpty(v.Bool) - } -} - -// SQLNullBoolKey adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullBoolKey(key string, v *sql.NullBool) { - enc.BoolKey(key, v.Bool) -} - -// SQLNullBoolKeyOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullBoolKeyOmitEmpty(key string, v *sql.NullBool) { - if v != nil && v.Valid && v.Bool != false { - enc.BoolKeyOmitEmpty(key, v.Bool) - } -} - -// SQLNullBoolKeyNullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) SQLNullBoolKeyNullEmpty(key string, v *sql.NullBool) { - if v != nil && v.Valid { - enc.BoolKeyNullEmpty(key, v.Bool) - } -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_stream.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_stream.go deleted file mode 100644 index fae8a17cf..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_stream.go +++ /dev/null @@ -1,205 +0,0 @@ -package gojay - -import ( - "strconv" - "sync" - "time" -) - -// MarshalerStream is the interface to implement -// to continuously encode of stream of data. -type MarshalerStream interface { - MarshalStream(enc *StreamEncoder) -} - -// A StreamEncoder reads and encodes values to JSON from an input stream. -// -// It implements conext.Context and provide a channel to notify interruption. -type StreamEncoder struct { - mux *sync.RWMutex - *Encoder - nConsumer int - delimiter byte - deadline *time.Time - done chan struct{} -} - -// EncodeStream spins up a defined number of non blocking consumers of the MarshalerStream m. -// -// m must implement MarshalerStream. Ideally m is a channel. See example for implementation. -// -// See the documentation for Marshal for details about the conversion of Go value to JSON. -func (s *StreamEncoder) EncodeStream(m MarshalerStream) { - // if a single consumer, just use this encoder - if s.nConsumer == 1 { - go consume(s, s, m) - return - } - // else use this Encoder only for first consumer - // and use new encoders for other consumers - // this is to avoid concurrent writing to same buffer - // resulting in a weird JSON - go consume(s, s, m) - for i := 1; i < s.nConsumer; i++ { - s.mux.RLock() - select { - case <-s.done: - default: - ss := Stream.borrowEncoder(s.w) - ss.mux.Lock() - ss.done = s.done - ss.buf = make([]byte, 0, 512) - ss.delimiter = s.delimiter - go consume(s, ss, m) - ss.mux.Unlock() - } - s.mux.RUnlock() - } - return -} - -// LineDelimited sets the delimiter to a new line character. -// -// It will add a new line after each JSON marshaled by the MarshalerStream -func (s *StreamEncoder) LineDelimited() *StreamEncoder { - s.delimiter = '\n' - return s -} - -// CommaDelimited sets the delimiter to a comma. -// -// It will add a new line after each JSON marshaled by the MarshalerStream -func (s *StreamEncoder) CommaDelimited() *StreamEncoder { - s.delimiter = ',' - return s -} - -// NConsumer sets the number of non blocking go routine to consume the stream. -func (s *StreamEncoder) NConsumer(n int) *StreamEncoder { - s.nConsumer = n - return s -} - -// Release sends back a Decoder to the pool. -// If a decoder is used after calling Release -// a panic will be raised with an InvalidUsagePooledDecoderError error. -func (s *StreamEncoder) Release() { - s.isPooled = 1 - streamEncPool.Put(s) -} - -// Done returns a channel that's closed when work is done. -// It implements context.Context -func (s *StreamEncoder) Done() <-chan struct{} { - return s.done -} - -// Err returns nil if Done is not yet closed. -// If Done is closed, Err returns a non-nil error explaining why. -// It implements context.Context -func (s *StreamEncoder) Err() error { - return s.err -} - -// Deadline returns the time when work done on behalf of this context -// should be canceled. Deadline returns ok==false when no deadline is -// set. Successive calls to Deadline return the same results. -func (s *StreamEncoder) Deadline() (time.Time, bool) { - if s.deadline != nil { - return *s.deadline, true - } - return time.Time{}, false -} - -// SetDeadline sets the deadline -func (s *StreamEncoder) SetDeadline(t time.Time) { - s.deadline = &t -} - -// Value implements context.Context -func (s *StreamEncoder) Value(key interface{}) interface{} { - return nil -} - -// Cancel cancels the consumers of the stream, interrupting the stream encoding. -// -// After calling cancel, Done() will return a closed channel. -func (s *StreamEncoder) Cancel(err error) { - s.mux.Lock() - defer s.mux.Unlock() - - select { - case <-s.done: - default: - s.err = err - close(s.done) - } -} - -// AddObject adds an object to be encoded. -// value must implement MarshalerJSONObject. -func (s *StreamEncoder) AddObject(v MarshalerJSONObject) { - if v.IsNil() { - return - } - s.Encoder.writeByte('{') - v.MarshalJSONObject(s.Encoder) - s.Encoder.writeByte('}') - s.Encoder.writeByte(s.delimiter) -} - -// AddString adds a string to be encoded. -func (s *StreamEncoder) AddString(v string) { - s.Encoder.writeByte('"') - s.Encoder.writeString(v) - s.Encoder.writeByte('"') - s.Encoder.writeByte(s.delimiter) -} - -// AddArray adds an implementation of MarshalerJSONArray to be encoded. -func (s *StreamEncoder) AddArray(v MarshalerJSONArray) { - s.Encoder.writeByte('[') - v.MarshalJSONArray(s.Encoder) - s.Encoder.writeByte(']') - s.Encoder.writeByte(s.delimiter) -} - -// AddInt adds an int to be encoded. -func (s *StreamEncoder) AddInt(value int) { - s.buf = strconv.AppendInt(s.buf, int64(value), 10) - s.Encoder.writeByte(s.delimiter) -} - -// AddFloat64 adds a float64 to be encoded. -func (s *StreamEncoder) AddFloat64(value float64) { - s.buf = strconv.AppendFloat(s.buf, value, 'f', -1, 64) - s.Encoder.writeByte(s.delimiter) -} - -// AddFloat adds a float64 to be encoded. -func (s *StreamEncoder) AddFloat(value float64) { - s.AddFloat64(value) -} - -// Non exposed - -func consume(init *StreamEncoder, s *StreamEncoder, m MarshalerStream) { - defer s.Release() - for { - select { - case <-init.Done(): - return - default: - m.MarshalStream(s) - if s.Encoder.err != nil { - init.Cancel(s.Encoder.err) - return - } - i, err := s.Encoder.Write() - if err != nil || i == 0 { - init.Cancel(err) - return - } - } - } -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_stream_pool.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_stream_pool.go deleted file mode 100644 index 3bb8b1af0..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_stream_pool.go +++ /dev/null @@ -1,38 +0,0 @@ -package gojay - -import ( - "io" - "sync" -) - -// NewEncoder returns a new StreamEncoder. -// It takes an io.Writer implementation to output data. -// It initiates the done channel returned by Done(). -func (s stream) NewEncoder(w io.Writer) *StreamEncoder { - enc := BorrowEncoder(w) - return &StreamEncoder{Encoder: enc, nConsumer: 1, done: make(chan struct{}, 1), mux: &sync.RWMutex{}} -} - -// BorrowEncoder borrows a StreamEncoder from the pool. -// It takes an io.Writer implementation to output data. -// It initiates the done channel returned by Done(). -// -// If no StreamEncoder is available in the pool, it returns a fresh one -func (s stream) BorrowEncoder(w io.Writer) *StreamEncoder { - streamEnc := streamEncPool.Get().(*StreamEncoder) - streamEnc.w = w - streamEnc.Encoder.err = nil - streamEnc.done = make(chan struct{}, 1) - streamEnc.Encoder.buf = streamEnc.buf[:0] - streamEnc.nConsumer = 1 - streamEnc.isPooled = 0 - return streamEnc -} - -func (s stream) borrowEncoder(w io.Writer) *StreamEncoder { - streamEnc := streamEncPool.Get().(*StreamEncoder) - streamEnc.isPooled = 0 - streamEnc.w = w - streamEnc.Encoder.err = nil - return streamEnc -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_string.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_string.go deleted file mode 100644 index 438c773fc..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_string.go +++ /dev/null @@ -1,186 +0,0 @@ -package gojay - -// EncodeString encodes a string to -func (enc *Encoder) EncodeString(s string) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeString(s) - _, err := enc.Write() - if err != nil { - enc.err = err - return err - } - return nil -} - -// encodeString encodes a string to -func (enc *Encoder) encodeString(v string) ([]byte, error) { - enc.writeByte('"') - enc.writeStringEscape(v) - enc.writeByte('"') - return enc.buf, nil -} - -// AppendString appends a string to the buffer -func (enc *Encoder) AppendString(v string) { - enc.grow(len(v) + 2) - enc.writeByte('"') - enc.writeStringEscape(v) - enc.writeByte('"') -} - -// AddString adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddString(v string) { - enc.String(v) -} - -// AddStringOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddStringOmitEmpty(v string) { - enc.StringOmitEmpty(v) -} - -// AddStringNullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddStringNullEmpty(v string) { - enc.StringNullEmpty(v) -} - -// AddStringKey adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) AddStringKey(key, v string) { - enc.StringKey(key, v) -} - -// AddStringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddStringKeyOmitEmpty(key, v string) { - enc.StringKeyOmitEmpty(key, v) -} - -// AddStringKeyNullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) AddStringKeyNullEmpty(key, v string) { - enc.StringKeyNullEmpty(key, v) -} - -// String adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) String(v string) { - enc.grow(len(v) + 4) - r := enc.getPreviousRune() - if r != '[' { - enc.writeTwoBytes(',', '"') - } else { - enc.writeByte('"') - } - enc.writeStringEscape(v) - enc.writeByte('"') -} - -// StringOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) StringOmitEmpty(v string) { - if v == "" { - return - } - r := enc.getPreviousRune() - if r != '[' { - enc.writeTwoBytes(',', '"') - } else { - enc.writeByte('"') - } - enc.writeStringEscape(v) - enc.writeByte('"') -} - -// StringNullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) StringNullEmpty(v string) { - r := enc.getPreviousRune() - if v == "" { - if r != '[' { - enc.writeByte(',') - enc.writeBytes(nullBytes) - } else { - enc.writeBytes(nullBytes) - } - return - } - if r != '[' { - enc.writeTwoBytes(',', '"') - } else { - enc.writeByte('"') - } - enc.writeStringEscape(v) - enc.writeByte('"') -} - -// StringKey adds a string to be encoded, must be used inside an object as it will encode a key -func (enc *Encoder) StringKey(key, v string) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(len(key) + len(v) + 5) - r := enc.getPreviousRune() - if r != '{' { - enc.writeTwoBytes(',', '"') - } else { - enc.writeByte('"') - } - enc.writeStringEscape(key) - enc.writeBytes(objKeyStr) - enc.writeStringEscape(v) - enc.writeByte('"') -} - -// StringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) StringKeyOmitEmpty(key, v string) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - if v == "" { - return - } - enc.grow(len(key) + len(v) + 5) - r := enc.getPreviousRune() - if r != '{' { - enc.writeTwoBytes(',', '"') - } else { - enc.writeByte('"') - } - enc.writeStringEscape(key) - enc.writeBytes(objKeyStr) - enc.writeStringEscape(v) - enc.writeByte('"') -} - -// StringKeyNullEmpty adds a string to be encoded or skips it if it is zero value. -// Must be used inside an object as it will encode a key -func (enc *Encoder) StringKeyNullEmpty(key, v string) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(len(key) + len(v) + 5) - r := enc.getPreviousRune() - if r != '{' { - enc.writeTwoBytes(',', '"') - } else { - enc.writeByte('"') - } - enc.writeStringEscape(key) - enc.writeBytes(objKey) - if v == "" { - enc.writeBytes(nullBytes) - return - } - enc.writeByte('"') - enc.writeStringEscape(v) - enc.writeByte('"') -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_time.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_time.go deleted file mode 100644 index 6f99e3426..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/encode_time.go +++ /dev/null @@ -1,68 +0,0 @@ -package gojay - -import ( - "time" -) - -// EncodeTime encodes a *time.Time to JSON with the given format -func (enc *Encoder) EncodeTime(t *time.Time, format string) error { - if enc.isPooled == 1 { - panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder")) - } - _, _ = enc.encodeTime(t, format) - _, err := enc.Write() - if err != nil { - return err - } - return nil -} - -// encodeInt encodes an int to JSON -func (enc *Encoder) encodeTime(t *time.Time, format string) ([]byte, error) { - enc.writeByte('"') - enc.buf = t.AppendFormat(enc.buf, format) - enc.writeByte('"') - return enc.buf, nil -} - -// AddTimeKey adds an *time.Time to be encoded with the given format, must be used inside an object as it will encode a key -func (enc *Encoder) AddTimeKey(key string, t *time.Time, format string) { - enc.TimeKey(key, t, format) -} - -// TimeKey adds an *time.Time to be encoded with the given format, must be used inside an object as it will encode a key -func (enc *Encoder) TimeKey(key string, t *time.Time, format string) { - if enc.hasKeys { - if !enc.keyExists(key) { - return - } - } - enc.grow(10 + len(key)) - r := enc.getPreviousRune() - if r != '{' { - enc.writeTwoBytes(',', '"') - } else { - enc.writeByte('"') - } - enc.writeStringEscape(key) - enc.writeBytes(objKeyStr) - enc.buf = t.AppendFormat(enc.buf, format) - enc.writeByte('"') -} - -// AddTime adds an *time.Time to be encoded with the given format, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) AddTime(t *time.Time, format string) { - enc.Time(t, format) -} - -// Time adds an *time.Time to be encoded with the given format, must be used inside a slice or array encoding (does not encode a key) -func (enc *Encoder) Time(t *time.Time, format string) { - enc.grow(10) - r := enc.getPreviousRune() - if r != '[' { - enc.writeByte(',') - } - enc.writeByte('"') - enc.buf = t.AppendFormat(enc.buf, format) - enc.writeByte('"') -} diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/errors.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/errors.go deleted file mode 100644 index 0fd52e663..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/errors.go +++ /dev/null @@ -1,88 +0,0 @@ -package gojay - -import ( - "errors" - "fmt" -) - -const invalidJSONCharErrorMsg = "Invalid JSON, wrong char '%c' found at position %d" - -// InvalidJSONError is a type representing an error returned when -// Decoding encounters invalid JSON. -type InvalidJSONError string - -func (err InvalidJSONError) Error() string { - return string(err) -} - -func (dec *Decoder) raiseInvalidJSONErr(pos int) error { - var c byte - if len(dec.data) > pos { - c = dec.data[pos] - } - dec.err = InvalidJSONError( - fmt.Sprintf( - invalidJSONCharErrorMsg, - c, - pos, - ), - ) - return dec.err -} - -const invalidUnmarshalErrorMsg = "Cannot unmarshal JSON to type '%T'" - -// InvalidUnmarshalError is a type representing an error returned when -// Decoding cannot unmarshal JSON to the receiver type for various reasons. -type InvalidUnmarshalError string - -func (err InvalidUnmarshalError) Error() string { - return string(err) -} - -func (dec *Decoder) makeInvalidUnmarshalErr(v interface{}) error { - return InvalidUnmarshalError( - fmt.Sprintf( - invalidUnmarshalErrorMsg, - v, - ), - ) -} - -const invalidMarshalErrorMsg = "Invalid type %T provided to Marshal" - -// InvalidMarshalError is a type representing an error returned when -// Encoding did not find the proper way to encode -type InvalidMarshalError string - -func (err InvalidMarshalError) Error() string { - return string(err) -} - -// NoReaderError is a type representing an error returned when -// decoding requires a reader and none was given -type NoReaderError string - -func (err NoReaderError) Error() string { - return string(err) -} - -// InvalidUsagePooledDecoderError is a type representing an error returned -// when decoding is called on a still pooled Decoder -type InvalidUsagePooledDecoderError string - -func (err InvalidUsagePooledDecoderError) Error() string { - return string(err) -} - -// InvalidUsagePooledEncoderError is a type representing an error returned -// when decoding is called on a still pooled Encoder -type InvalidUsagePooledEncoderError string - -func (err InvalidUsagePooledEncoderError) Error() string { - return string(err) -} - -// ErrUnmarshalPtrExpected is the error returned when unmarshal expects a pointer value, -// When using `dec.ObjectNull` or `dec.ArrayNull` for example. -var ErrUnmarshalPtrExpected = errors.New("Cannot unmarshal to given value, a pointer is expected") diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/gojay.go b/plugins/traefik/vendor/github.com/francoispqt/gojay/gojay.go deleted file mode 100644 index d0c542f6b..000000000 --- a/plugins/traefik/vendor/github.com/francoispqt/gojay/gojay.go +++ /dev/null @@ -1,10 +0,0 @@ -// Package gojay implements encoding and decoding of JSON as defined in RFC 7159. -// The mapping between JSON and Go values is described -// in the documentation for the Marshal and Unmarshal functions. -// -// It aims at performance and usability by relying on simple interfaces -// to decode and encode structures, slices, arrays and even channels. -// -// On top of the simple interfaces to implement, gojay provides lots of helpers to decode and encode -// multiple of different types natively such as bit.Int, sql.NullString or time.Time -package gojay diff --git a/plugins/traefik/vendor/github.com/francoispqt/gojay/gojay.png b/plugins/traefik/vendor/github.com/francoispqt/gojay/gojay.png deleted file mode 100644 index 21090bdd20877f745003b24a4e8667f57b67a1a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44163 zcmeEthd6l??>n)c?&Eu7 z!-#n95jDI@a%%7|H6hC~Q+-SO$%^j!8=_AS6xRJWt4tdT z^@(||c)umOL2(}cj;I2Wy6zVevR-n_8Z|tnxgDGl5rG|_!oDABUXu0bJ0W<*M)rTd z|8EB_cL0KJ8xDx}j4bUif5S~%2qzPil3B~e zd${#dTkH&s4GuY#4)O8wj;da{j9EoO5luv!@YNpStJf}e{G0f$w$cCDIl4yL8gtYy z9DS$EE+|Yn?K>UO1M1gLBQ5C(Dci{EiT0nAj|Dupj`9_M5Yi*-D}2@ZP5kT2J20I2 zUz>1s{cG_Wp0LLHtbnHJ>q~VHhQvM89rMYgB?bB)OS_?{S4Ro#sxLN z?%DNjO9siOIK0?z+9a6$=PQGe4y6P;4mPwf z49&7EWy;!HsUfJ!OX4O3342hr3A@B!zYZSq0i7cZQR9>D66@{nuJ+y|*)PoFIIDk2 zT3=1|fByR~0~k*Nz1*mgYgC+=Y0SWIK*gv(tbHL1JU&_dC!fmEKXVJUwYABI=WVhNZe*_?pdSR=HGD35(<(~dC?sis0~|33T>JNPmm}W za4-|K4cjxsmtu?+v_f_*d72QZ3xN)0{i{-J7&I<`tNKOicmEAojI6UZz1tBW4 zEmOpU0A5Ax#)QZuo7IP$i>IbZwyvU7tDRlrCuvg{MgOpz2*ZPVaon)`Jj!7ffBTb$;Ux(93=-i1FJ}Z?bMkzJhJs-M_SgT~8kNNjl!wXLJXh(SJTEV= zTmr}CwN?JQwr8eWw{E%kU(J*9_=zjfR|~g@&V_MH!%PH&&Gt6~BE2i~2l70?m5ZHd`&N)|pG}eZe0v zWPHWx%{AKjtZqMkJ^h6OT!F`5*w=TC>YYkKEWXFqNu%_U!K8{%D;+d?eX!GL?Iu#J zs_fM@2m}KwbRWM$#!W&1yHdkDoNy0B9Fbe2$N72e6OX=_{|F|)&nKUKXuGjuVzj#F zFT}&ghv(|x1c?C30#|-0a+!cbid8}AHSNMMxvg#9@HN}%jgnOXSXN|V`yMkfTgR;% zl`8gd9clfC&c#t(0k9j_2k*RBe|K+WKLQ-(c`q)6lzQ0cpscX)8RtWxVgGn1dJni! z770Y*QH5M+ z0(9^C;1bkK@)(JHs8*EYFvKlkzjxSG^0^2%NvvSEH1iMAg4~`71UF}(&90Gz3Tcjy zRA2Pb+9QkE*9!dD9jVu-&wUqkJ+&0~eCRfS1A9E}d7kG?Baj+zU5NJBID>L8|e%@Vd( z(~XZFJ-T08QL!D&QQu4w6?g@qohs=xQCuqGS|QpQjkM<#t(s7g#`@{9QTx)*CoBE> zl10Z+x$!%Oxp>iJ7(Kcxf(tCtT}769q0pnedFKtze-8h$p9ZCT=ENFnsHTqolP zP=F-}H9*c!LAwyYU9Rtg%*KpnyvmIjRiTJM91LzC5XG2-bVc`7FlF?ekk2m)Gsptw2 zugLt@jjx@-a0CNIB~wNRsgbC#1p=34b@EnKmWP6XoOR# z9buu|Sq;)j)^T)wW&W&$_CK50TV!lh3MylN)F8~S>LAA7Q`W_uV!c;wGbm7(%bg7_ zGVQnAWUrj6xTk^t?AW(_ELR*& zBDV8ocqH|Glx<_u+i@S@?%a%v>ZN;LH*ek~ey3Dg-=xWw69JvhfaG`0zN-l&zhEvz zh<-$-K5w4X=s~(a$ORYOxH-A(7H7PxdL;Rvf-3E4TyAdewQ$Qu4P<|9y9v$U??$X1 z)pe0_dGK}`Y&q7jT50@3f^KF?zMsT-W7lJQfka}R+EVdfI}8YOlg`X`5s!;wIoF(^0R}8st4ErGh&Js0R9#^3!-pM7`3`0dhNCLb+vMch5H@Q1kMUA*Sd5pH zlaFUTgt`t%!%n+!sj%m^i({aqlHVyvjR`aB!zuK#kgcf&+4?j5Hz~X$#i7QX!-~5vrR`IrwfNPR9bcKe*f2Sc=Ot0e6oWY< zW$pk|YU`;r!DguqRD=zu6I3uNw(>7_C1y%Oa#Ota*ij$S-Fd5>rM+AawvGZXMvTlC z>nlN$JEu0^7Kw34u@l{ih`sOaY~MBPEgK>5@UG&loaJHya+e3CZ##`aUvnd&jokC~ z9Ju9su8fq2-6g-^%;9L6xp+_33=$OjFtAwK~;y9af_PWUgqueu`H^;?pXo zzvJ-nx_CbDYf2s+6}977iWl`T=1{X-tX34~T*`nUzDJiw7fW6PZ<`gza8V&qYO@)~P|G6k@jaS;I-TA}7a6lhVcn zVqORw)jnK3tD8-t1bWumQKm zP~b~!IngISkQ$lS*yrhBwbZRgQ2qLx(*sCeWQPNCMR*L#Pn-EG{$!8%BQY}bM5j66 z>w9ii`L>0BX{|VJw%_DOzEHrMgR)3_N|aCJGIPsJOT|5}r_@F7UA``&_JFtTUdj^^fkTaC8h*FT8`Ov*8&dXg!Rt2*4f* zf-G$ZcAIV8dar>mo||Tn*Y+OVzaV89w~@QfxpEJ6!IPJNbat+td)w*GvQn}nYhjc8 z0SHXfF5CrMPSn9;t~(Gd!LyurBT3)C-*0~2J|H1{*`d8JWqTc-KF^Q)OUYIgUcPZV z=b&n|9H8Es|FZ5@IzEuNY7L0m zPL=O+y?%vaQb*dcSC&sVWghQ=CULI8XY>4_nn!shcyB(GFGot_*$}s*N!A1?VL_Fn zV^A$qwkh0&UV$CnL^zwyPW&(`RgVO>G9jYL2mpxbu(4CKT(}>~S3CjOX64ruHR7bwaHR|Cmk(V()pa-tR1kw}B3mXetSzV9UiF za71>xDFM9)60lv;Ej%b&!E|e9+I1_fKYsjJgI$HWX;6LT z6a8U|8~>dw^v5l{g5=n8?D%{9Z&k!95jEYpcwtt4;LBk|l2z)l62Kv)w4W?ttaHI< zQm%=%r$JQjY-JrVgem>tftyYv^sRXEmxsyWa5Y8L}n1a(((2ug} zJtI32xjg<*Y=P9uhn3u2<&dEfx>8FW%dI{_z;&W?}sR8 zRzhOuJZ$CCv0!)R3d#2gICx)NXgQ^?A3ryzn4qSks~OolBV>HH*nLMewQ7`3`l*e) zT}{}Q-P);roA5TowER2Z8LkJC$&Z)1^WoFsa`xIi*@2V}CMf*Ijhi+%XqRkn(E57DzExtpPuTexxr?==2dy;In;_S8ns!BustiCVl(QyFlUz9-cE2?ZIXb4?K?y!~ z;i$)ZtS#w*&N59pGgo)_g(%BfjWKZMbE##^mxQ?w2ruy zCUfU7<7B8>KU6!@scJ=LNl*ZM25#K%k6pI_R{E{3QzHYQSJI;zw)F7uFyylT8k4P}Y!l{%e9_C(V9R{OUu7MTZqcGp&iIoLaH|jr>v#Zl z$Sj!P>8tfDw{wzUI2PTY z9exh~Rxcjy_QpS=oUT9Qq1Q^e3`T1qbV3vxgWDrU7w^&E0(?&l^!0C~<{yEk!1?(n{z>{X*W^w zDAu04{91Zy=>RjbSN_ptue3TBXcN9iA1*?oAl)qh-%aKKw2p;sF#O5qw=+IgSPFqU z0zPqS_Ljep+b`=gAG^(!20ia8)4Zw;Lbk@ocjK_GdTOQjt}f8E37Z}GH`QSC{jMoW zbABuS$j89fgskk7l=+x&^GTyaiqh4#XZ<+sZ{z;TNI+>cyM%@pfFPQQ*Ll{c
  • @ zdYQ4oTFdr*Wtf>~$Xg^?y-0*Rgrfz*Eq`P4$93F`{f2b&C%dowfbain8d><~nR)J} z1^7f^|KY<>UOv9}RimnaZY>>^f@eFM81X#0ew9Q$(mttkfyYT83i=}2xvOGdtmlhL zNzhA4tErj!k2@(Aa-;c}KdTcOrWLy^_9I>zidN_KOGKB!-rC{!yPiIlxnfo>@gA+r z`Fo2SH-;2*c=TY9fDCTuQln)6(LY2M)CxL5t~_}xH#WmLmUY?ynMOvu4JmHU_C4Q- znpMUyggk!u@S%L(@Czu`YLOGh6q#bGv=Ip@e&re^JWNF2voB5ROB4UQmiROd^zKcW z*iACyVWYL7f_2A+3R;2y5Ko=B737Wm&!$to&p+_LAw+?MeSp|uM()0|F*K+qU}q&X zi1x5Oe~o7OahE^Xw0>q8QQ*|cf)sm)F8ju6&BaeDJpQlst}*|^0Zy((Qz$T;mo8Fo z+g6JiuOZO;lB|P3-cBgd+IouIe+(_an2rNflqyrOn|)wO zO7&B}IOPTQ=pjRhq~TbXdXTqt?>As2$^V0;llkiv%m_zQL9eC1SAops?P|**heDUx zEJppaYv~o&A)l47V^q6^(&ebYjuWzB(GyZpwYt!09__&pSr|i*KY)2hy>+6XgOeoB zem3OH) z%P)psCL|<$fcrE5$)KE6Kpq$;?lHAffW^`5u}Q#u+a;@#C7UEQxb19WR|wc>TIKgS z>S~Yf(?YBe?~6z+q$$wl%GT{i$j>cuGETJ z$9sACJUf_D{c!UwsVWn;L*#%}s>fHA7Qz5NWJ&9R6xUz$NekkBSsdK~&dihTyv zjBGXY;_Q&S_fTPpHsXdV^sKBi@6mniIXl#EmVXz`IjN(Un*k_KF^x!*wAxkUSpAz8 z{8ld|(7PnpSrKnq0GeqM2w#nd{TkOu&D!>FGPuw3W0G&b<-f&%@G|`FJI``~P*5{L z2dgs@jp>I?TH>oq!l)m(-dH<@zs?VXEP|$SMJk=2TA9k@Q@U_T3;o8#H3Yt9PEA=k zIXS{V9d?caBS=EOI-%{UQ41eKHu$aTrCk??eNyAHeD36oxY5>#>~sK_SpFRy7JLIm z31!7gRoyD%dI~zm9$d}0n|smdQ7D;>*00CL%zx#Ti<2BRuYB?B}Qb{H^u*ZJAms-Ar|eq4|<$nloN6MZEz5vUlm;*+{k2*(0P6 zCC}aKq*|pazakJjrfvfML|f!2V}QPeE*E03c4`VONfx*+_NGa(k%XPna?}@3oUE$Z z2D2!*@OO6X`!}iZ<(1hk#ubvwQoLp=k(n@I+6Pg6bo0rkSLb3pSLbVATkfO{&+R=~ zz~Q-)5H4@16*0Z`ws_5BxtMlYpxLJE*Zu>^3AFwTra>l9>s5U9rqbQ4ShiQq+9L8) z3cklGW_hF`4WjYnpIt;r*3W z)$9&f5@HdTJSyu&NlTdj)>!Vh`=Q6*QCUKyZVad&0MoX4Z%#A6|J+DJLqk`)*n+ZRb87ND0+K{7@HXyrSI8IjA58my+A)J+T$-f0Jy zJ-|v~0JK2_5K?TsqU6eF+jz$CxGS@QudC$=AeupS5Er#}H$Ng;0+KkBkJxRSf8_D? zBp-cW{I6ZiCnZ71r%m{L_4g~zkr(}d;HaW(AgYN-gkLnfJ+;~yO zP`q@~0@_{|5MSCI?h~fd3kt}E>H04mt5MtuxUR$ zC}DL|H*alG;H$MsK1sh(b+n^b7E~Nsn+vw2Kw#no>=jM1_|hS9q!{HBjSS|j;s8#rSOvU7YysT-QT>-D{jAf{;Oz>K1$xn` zDtR4+3Bj1P!_m)?(xfWVn&75V347f4KDiQZ2|!o$_pE8L-no1ST3DA`dmtUk7{CxJ z8WFnHwgIoyjNZHa=M->F<*qL#+|Z_9({#b(8s8g=>XieOZN7w028VObH%{ZmwV9fN z&%*6Yo7-R(AD!{mM(Te+I2gbO-$PfIewG`pMcMXdG>eY@Oi7Sjbb>mi#($c)|F0LI z-~orfo4e}I^g)gHU&2ZSP@npb9#%V>zao=Nbr{O;H3!gvm2^vD><=Ip0UF`QV_qv; z1|J9(IFz!Iy1nvPVJzL-17uzCZ6BlTFcknDL8bTzJ+tlH6k zX8@Y23DLx`IY{I39+7@L@Ts>t&jJ(Cbpy#DP+s^cTmHME#lNoxb>7WO1kx&g05|#q z0NHC2wLg!aR-RQEJbfCBdVE(8`h-0a#aDY6Srb?AJFz1&31&M#&2{2jV{85NG0)WO zz}5PKwr@ai$RqRkXWkYID+6^pnlC|1wK1#CC`gP^FWyz5|bCv{PO;{)*5`5=(XZ;7#7~!4pNq3G%sCI z0xs|gpq}f*4RSzYAy(8<`F2wDK3=yRaOMQ>()|D;1>{G1V#QN<45}>e;_jh8R zNhgj5KEX2j5<4TIxsw@l6b&Fa3($!ETWpa|`hmX73A&N(2gMT4!`Q?`l*XKo1HqD1 z$^Pb8*lu*-fRbJN*uCH;Sv?^4h@MRUXzm4!e$(AIM^4bUSk+{7c$K#Zl{J1}!f1^G z7JonKn(d-b&GVzVW_qs}=3&RGqDMO{T2`S>Fi)2*`!#)39U=5Md1n zTScWU$xzaf%V7ZY>3G?s7$$w4-H&>1-*~3E$w#rvcGoa&c zNiyO?MuGgoO4$_>ObsL%Y6QlIR=y@-(&6Q+jO1ir2=ygx$il?LM4!m>ztLY`u#$K$ z2XM8%h0+h}xY`MxvVl_fkCAt~$^rs5)sBD3+ty5iKMyzzN2p6acBB#O_|5xs| zkwaP~;ziMDJuAu_J`uV7X>6_3gM}e{5J2}1NYGpGtT0|m8l0GAQIR6Q+pKESO#fZ} z=GI$oq9_W=wrBqVt*1NPf7kVM8c^0;NT|&Qn}tE%^WaDiH&%|7)^{>R@lv^M0z&?! zetOfwp8qCCPC&XIi1>VlshCf@6 z3M|2y%|U%$T72=kN$b;1Cw4{mszR}@3M1atN>&}4(uj+t1Cp%a8OP(k>n)P-RvV-k zyL8>I7xV94&Ga%5N>tQ?cRA{nc*F@58ao&KlzF`5A$i5k*36lxO&?Ls9Ww|4^M&FO zJ2v2grQEL4vFFNZo;$|Kn-kA+LL>+w;Qgrlt%0EP0MhEO(dPrzf^4@L5W20nWl0y$)VJhNVxyVksRKH;@u3ioCkc{ z5H65gvHWK+XlrFXr}7Q*xX61WFAo$HntspKIs)Mlv0lO$!ImQ)i^&5s$&lElcTlg`)depDjhC+I!X|M|ZO0CsOjV_-xOEU}>XLIZ;K*lQJK<6?F=}MJIgJ4ME$>D8l5S z*+bALaDGVVvh^17mUcCtF?T$wK-<%!NGkvbQscApN?GgY4ECrlMebQ8{zMPJwQ({@ zF<$SV@)N)agL%BZZ3lZz=SbTQ7){CCEc^GvGTFrFViTb_;-jOsDMYJ)7+|O+5&trt?hwgyV&SlNzXY>dqF8wZg!R7jvdz>I^?P6-j)z zR{c&^#ZV{L#`-k9L${WoEP3lofJQnpns)}v4olUFim{T!*~?GNIQ)SjBndKE{k>M8 zG#ZR|8Ca#P=u@&60b#GrnZrmuA>a`@ww4}hOMBe#grZ(|)ze^!bjQ|-jCxigETJUs*a|%6;hwLp4u-G{>q6z z{?A0W`$>#&=nHz(cE_LZX3S0ef)Y=u2ay~Tb0$)xeJr43_I>m~M@Tm#Ru})8*1kx7 z4)@l9gJJ&JD#vQ?gMoAl*0}|AGpWAX)QbPUUZTxSRdELAd0^_H#KI+DIkp zl9 z?eKT~d2r-RBYCSQgt>L_^kNMHKf-~8uOwdMvsDC?gr}DZ^$j{Hiw-oXh zE=2C;7pGuqdz*N893vo?>@;L#BNCSy>a|w@WVMfQ$I6+zbeog z{-)}@3)JJaHOWthR}|DrhyG^AB0X=SSV_vq-B9{G*$I)yG7x84HNtGasPj`+YW{fd zNOv%N4*QbNH2v&G5lakaM^N^3^xsO- z|5?iN>YNaDMv=5#=jFR-j5{?8_D{m(KD|;J19IVb?1c|-BkcK?$C+I5%Xq_+d~|S4 z$LZ`AiY3n1(9I+BRsC36HTzn5CdxcRAmHlR@%(UFYvcXRV6U!QRC+E& zF2Ch5&yyv$T!2u`W7T=b6aC8az*3AZTvY2eOPZZa4*gcr`vGOQ`%=I7SOgHRya-mx zS$oJ7Iz->aV&A7NAPeLxA`6*XwQTokbR-e3uum+l;ox9P-%myt=E+%t{&Ok$$dSXJ zLr(4-56o)X#vU2%9Tq8C=&XiwWMN_AKpu&k0IFmEdJD1R7?V|vR>5ZP=nqoAiL*S7Yp(np&8g=3O31KCIdrKK2@ve-lY2QZ1uEq zI1f6$n`fr_=+Ux{nc1{sjq~@MtcDt@pj(loF5}y6L4`(Mr3t$IQCSkq!7UfoZNhJ0 zxl+cz&J%$M?4+aCXHe+=!~H)cmr9)0VGd>`lYF+U{`{%a89BW7BX(voP`G7VrsFI69_r3b!^$s0O@QI=I1ZuvM;~Ke)-`?Kdge5~0V~f+(&O%yh zYCpJgI1_YLVE5l)G2A(%Rip8liALlWB8tu3<^Vh-dP&CM_Et4+-dcRhC|2kFLyOS*v=-*s0=m&d$YNP}zxBtEQH|H)_UROfC7G={o z=^a}tNEKA*)f;zsYxw^>grvc$ojTV@0T`b70v^vq^U&*p)-jp0*+ zo(eR&?@o?N}LROjs zfJU2VBHgjoI=gqBYQ!j$S;=wM%Fr9*L%X8CiLgBJ9 zd82uWD6FKplk8{lv7*bT_*0O#_`4wQ9ElWyEnl&agYQ-GuTl3@gyXBver`-PguFre zp9Wu?1h<4V&TPtGX&uDLz}cxn-j53S=D2~Nrd!POkyG~%4M(hh=_N*bMh(@N*rhD) zm5Q)hsSRij$q+q(k8Oc) zIx0%C!TMfQ4uS0^0i4EX{$dJ5rUKFrH;KW@U+(8~Gk?3tCo>A5+RA>#?WEtkj~9;q zfE@VXRK@&z^+pJ~9RWCCPncV>NBx(o@^{g~>ZYAKpY;JKSu`67wy>V`0QFuHwYjEH5v;>gb-i^QvgON*{p@@q1qAQll6-vi zUm>uKzC9J!kavHW8QYq@1z{@;;-@FixKJM8D2A)Ej8G(GMl$Q984{v#rGC_3-k@{e z_%#XKMaZ}(PZb&8QC6`@)8YB6?;^5*@ekFm<|m9j5#Jdn$H$!+vAWw1A}FlUTGBDs zuZYn2SM{X@CX33$nMY_$dRI<%(Y5-N=NS^Ie>%~v#N*;O+I4F z8-4>0UF8|6gu1qlM0ilOA0<4@hbKl@b7y^YyQXuvTHJPHc9ptDW%+YweQZnOBK4rw z^FmAdxe9r%H>%^|A3Ktj5_IKC_o$&dfCpTm44cKeK7D^@;xk5Dxw7Ufs}esY0tc^N ztSwbm@g*Mi)>meCMivSKTKYREHJwIkrdSYq^A)1-J#Ljkpl^%g-D zi(c~X(r{CW+^l7X6%oh&x36*{JsP}>RFO?sKS2}?Y<&Xn3hw^ZEDAVtcGX5!Jkb2T zwF0KU;*7C=QMw;nD@x{{oipEvc|Zhg<+CEV& z?s}-;e1E%iUqi+fB_X;^6$ zo?9kILBh&_*1AXe7fioaDlg%hIf#@!W zDuB`B0HTwbKT06XXDdsIpmeMxP;S_fo-sCtGY{7` zW5mbGr&FZH^S>?ps~j?lklr>2`B(U1?(nD^q4navj#{|sP?ozkV0jwn(a%*NCG1hG zTz-fI3a}vEb44#~!FB15iE9M{s{sIMb;)S=etf?aq!6pS8lts4(uO?>hDd=)!}OYk z6Bq*sn45{!oE#5DD@##y2jT+lKnL#wIuFwFDS8iSX^^Y?pe-&`4DQqiUoG$Y_iuak z-*Q;%(oRzsj%LYwZFe2ekhi}*6JX0>$DP7IR)2az;G2ofJbKYxvNLfzITZ3N?``rf z%Qy)zovij4YfA60%X^3ZE={;Nl`a!O}=8g62Ya8nSNoWhI)^iq!9a-425M`x~`YW*x$)8=#^kPOS#p`y*By<59 z+rUHZJ?6hfOXM(sxiYAcOXd0v1zHpdiah!Xu`{hgu~HgecI|l+U~hepB{5SbGKOV3;%YffqOAb z+MqvZ6u#p>nC(1o3jWb#z~jY)df4}eP?n`%I@}W3QRP}fwXExKkp@+6Ah#g04u@S@%3(7 z6EViO?e?wec*WJ6rdSmeh3TIUk7?qc%AGSqm1~mgaOlF_mSM)NarYy44Zn>kh!!^vsYEo(V>N-ODw%!(bu5tun_}_FO_U0V zlUPTSV*r*iIdeh?l6kF~U7zEFZ?@(^y6ME~e{k|J224D1n=@fb zhWEM_`VQ_2YMeHeb#!!`jizjefK;x?ah&9FoKzETCM%=cpOG|uBnL@A$ySC>%PPZ< zE%EzO9Q8yBO9k3%{w2S=%u091p?lJ2y|SABqCw6HL+<8y_%n0RvvG~`?>d+DH7OCb z-=>|OsrH^cVi9<7(NqS?6>zQ=i_++2;+~4{Y6yFJ z(8F+YFnq_!g4$r7z%=gE64K(~s{xF)5%&fW--3CrQ?@OS@e)rh{5yU6eq{JHaf1`p zHxA@iMY~1&EB=bL=Fdz22-n?SafIY0ZA9~UGR1+8q?hbRi=qOMPd@jiSW2NhF&krR z$0g+9l+;Cl#Jc$H-{Wqa=DeB@7(Gb}$J21oGf06)x$sE8cSL}(5MHKzd!uMI4)|Z{ z+hylpWh6-EN3HFSJ(a7ipOVx_2NKO;zOV8)##pp+^aA$yx#6hfPXY$Io(gwh*IJNS zCg_d}GFpiMF&X%nMwXL_N2K%#dA&1!Ci_SC*_`HCHM&;(-VrtV&92`h8-V#K>v+0QK?oLNv-M|!nvY}7I4w0hm$2hf?_6}RfIkOsg&Dr zD%a#nD;Y^>zv|QV7s3}=9==v!DnYbr)Cqg!sNeKT`l^B!c)_f^AS)vMY<4Z@WC7C_y((t{aYM0qX&1c9QJEA?OsY&KLE)0p##E0jEx~i zt;*Gizh^=LiG_|qe;50Xsc29wll2~3`ZF@p^|@j~FzF&!(l`H6-&ZsFC7E;7Q<3EU z4#Af(?X=OZpt1qhN_OxG=?5$32Bm7=yf?Y}5aic)Vamv7!VT{wd3=m_ZHXi-Ae%cl zp@V#hTbp(od?fYVbHDFjeA1KG13s2xqHmGD_eYXxJUQI8JG`P=IVF&Xeu}+EP3#j6 z14bcS4+&%rod76$*2lJ#N!c_5a=j9iri!$_PD4YgdQBx3(9t0WH!*kZ8h%I_$@RCfdk_LXWZR5R zA?-m>o`Z)F=WCtWs>Puz2rIk#u34kxJgYQ21) z-nQ!dXr(m(ss&wHv|Mvh<^ce&82GjwB~+B}p!PPjOZ;|CRtWvd(u}D4WOrc-EuQU; zZrG?4)8OAvplit=JCGBiT*jxPCmc&v)XS7fL1?EP%WArRP*(SM7iiwMl69H7^D{^t zcf}t}c4-$Htz^6dPK7IQ-x9o(jNV7zA!~YNI(=u&Nl7q|kf1|ds%H{Y|5z>W&1L<8 z#Y+>GpYPRmf=w$TtMd+$p(eZWs7yH_4vGaGW0PUUJO*%(A#Jz-ik!;JfdQ{zo3A)- z=?J*-da;!lCaIyMc8F6L_pQzr%puMKc^S5J#gG^Qox$?HT6Q%q-f@Sd|&JgeX z{QO2jNpyX}`90Jf$R%O2FplZq*-X&^NJH6R-eOpt23=_2735I*>O8Vo@4f)RtLA|x zWQ2Jx60*4USkFpfweI^<2^oKMc|&+V3QRJvUO}Q-%p3GA50!%ANSJ}0Y(cHyt7l_ zP0#YXy>~76zw~bk;FMqkz;V#s{i}8JpoPjp5)qYPwu7>3_VE2WYOc;uiF%KXcpZ~q z+Ti^Vmsj~_@J$T^pe7t0pDreU;IN31S>ye+mg_IU3`AuHgQc z3-k)rg!ZBG%}F<`vaPHB8o&ZIkrJvdr*WV}yTSt3ch$#+59Ey2wmu%Yf0E@BeCF_$R|C zdV8d|LOFXrDIv~(9L1b4?g_0C?dj7s; zECXy01=Q>*RdEdju6NOVjAMExjP1DqNxUxALx;z6!6Ao^2%4Rq$mLs5@$}(fpiAV; zLdQK{66zripZnA(c&OadShK5;qk7bIb(i$0s~AAf((++J+a3h~l)&YuEx>6{JT z6#W=k1!n&g00E^W_OmQS>AMuNz5h76k%t0$4(DqcEZu2_`Y6}#qId=$sQ|t_33}wI z6_vm4h<`4V%#)X4y9l9L#`bE!O58fPyBbP^j$T%snSx>fdtEc-Iga;P0`JX$0^Wrv z-34n#@J6>$5aL49eF5Xy6#PrH07HPFDqN9f_MdU{1yxzOdQI|q)Ph1Jbea<{RRCrc zo(vzOpY=V%S4&(UWLO#o`31qDh{^cPpg*~|a}@j5aoS=nFi~&i0a6GUqmDJ>Ng_i{ zJA0LVzu!qP`GJ#-*QEhuP48Y~uO{yKQ+@qmFX5XR-tz9Q=Hw)yOAuLNQj&He!wml+ z{gd)mq6n4`TqWE&BYi8OU=$ZWS=~8s6a2;a7nuJ0bNNbE)j3P+RVYGoCcv0y1kke~ z*GC?NAgEu}l?^d+{=vLed0_K>(Fdm6pj)&3wKi`~f-UT3I#wv`^KBBa6 z(UWrp4!M|n>8i*B=+~!q*S?}nSwMWp;AF7qG9YcZ2Qp7s+^FCW z*Ax2!=|$qH>c2~m|NOW3`cfFbbG@IEBvj&qW6xKGHsRa57H3kkO0e3Qy=mFY`GpU0 zi59~5yPho3flSKlq8R0$G3xKlNqJR^#Ek>4>A2i9J+rt*)XI@lPqaeTPqwaJsO^9& z^b5CSa;5+7obMnAti&}ADHe-4z}8=y@9;D^|ESa<<%`Bp<6|SEDWH6^5^Ui%{dU{H z@)_1^n+%#G-j=@!gJ`c0?m#XCZn?nM4jAT^XR0-hB!0#}a6%1If6yf?X+VYIwKbb< zCbD>`zbA$9WK|lGUMmN7)O428O8r!qkculEr`I_c2xhyLf3)#Iztm3`8%d}>U3Z{H z$WvvFMlHna&UHk+08o4E?ke~*ld#o|KQWyA=n7c&?Hr-Vnw1J{z;S#-o=zD%6=1$_SPM7!T`rN)z}RQ_!*y(LpMFNlO0v3-LwWL(!Nxou|qKZ zXNh}SgdL|097bXFEqK{?Xfx5PO8YHiF&H?zJZtY;H@BSN-aB7=6$j3OFWmLReu=&M zYVq`TMgS1rr&W;#t>Sxv#nVm^4k=652bBcbYeRr5_MuMkvRaH!WdFq%pFeY&H`h+i zxSab`lj8r@3q8JJlFb%HVWacnfsRQquL~LRr2T^|Vw18$gFJz(>REyt9XAhd>b!uF z^F|GT`HJj^O?MC8C=A_M%Iywpkr$17hW}aVkXpSIlp)itscche^lk@B#(1S0 z%KlJ>-H*kZV@emQD<-z)f)b`+Oqdomb_ud#-pWAekJlb9`KVvuzFg*JA%n8K7U`!C z4?d7y>kM_2PWS-(AS~gKvTp-MGu}L*So^QM7t;F7uOmS4Bf9_y);<+vve6ccouP6V zr;lrLaflNS2t)b=g}oNhwmLZa>esJdz~eWbwOzFznKpj$yzEpXC0P!ICH$GE?CH5X z6!Ri|_we1)thv}ul1?5;oNMfh5?-IVSdtoAg>*96o9+embMU)ykB%~W@ z1Qmp#B&E?0AuS_azsql}@1L@k@ZP)kp0m$B`|K<0;9_Vg$LlwckiD4f#J^O%y1F`N z9ACkx1x67Zp*Q;7K|l;!?y~&qx?s@pDffwOCr6fC*B`TcNE1H#W8d-TpDK}_cFQBs zjTHu=QXeBK*Qj6E#G;F_n-_t$mBkhqdquX6ESS)Tgfjrfu`UC<{_sHB^J`zZ;+rH- zt$5|!Dc0UTBJ2Dl)O-i#$uE~NM!zd)_BJF0`A<(zRVpu<;=Es)uX6FKN{i#>g9|wc z9XUp28?6Ky<=&ZY@dF8y&|3vM3N)m|?%G^mx?V3}m1q{s;4IWP$U6{^1^qIhhqrh} zUWq!MI70d((~0bc-S~szf#LbcnMA)r$qv;pvpO{gq_@6LbcVFf2zzD=vw)-#j zG4t3Hp4eBf0&h|d&Z}Gl&6L*$8Ipaf6&%ECt$tbyTEm^O>xR>&1g~))cvnQ6s$WQZ zoZGR6(=z>9Xghqr;d`QxT2Oa%#H%whM@q|vyRixOB1J0Vf%8X0VeVY?rx>nqva}bE zB1gtT0#6JGm6=eAeVe{vYRCqdDa-Qo5G>_!#i0t3{1&y(2DD+gJ>U{bjl*vj587Qh zwy+y*25r*|lCfsJmVY%HzClVc$u4!n!fX%aYj#YguNKGY>Wsh@XWX>7y_qBbUO{h< zK5i~EZ^)Ng0-aO%i5A2S^B*&bhITi7g9h(tFPFfGD7NjF{u_uU@@Z|no0XO6b3<5A zQ}@qb9w~xJvW13z3OA)C);DFo&1W~Em-z{U;YS=dPwCP-H*=v=>xZRn)#wa;v#;6HN3u!$xJo+F=R&DsDB8^^X z=$j&3lS)?CSzzxI^z7M6OE)fWAuf#q(x4xH1HIH@B>rorV6vA%O3$ebJn#+H5j-H5gVgk(VSS1+G7XhnXU@6&%~uNT`+5i?_poi& zCwTmMHHS&R$KT@LbOMn^_gBou#EygV501`%qJ!8``i5nERNlRUr`PN#Vj7610=T|7 zGv-LWNp7Q8R(4GeRpshC}{a5*b+SY@QAofLF) zeXCMeNX$zR@^77!rE5wMU-&*#nNq3y4Gz^=>hU%-3gx%MzlGrXS1cC zOL3i`X}FafK@}xDG~>C`XZ6f0*#?r7js^L;jWr(;Z{N$UFrXAENE2&+r36G5IC~H} z)xl`IEyI+_{yONXI*a0s8u7~mufk97^REyGyi>AoOy6UChn*|mNO3057a{cL>{vgF z%$qL0vbnzC_0GqS1TwKJ8YJf;7$I7;Dtt;0mAf9Aav^Odvx<*o6pQRwuM|%c_`OIF zx1QLeN-ZcGlGtQIWg2(+tY2}JZrp#9sJ2>XSGabFJk>=rYONMHKe1c35#bNAof`d8 zFrcy3(m4NFWJsU+-`=&<0`}|d?6ZZEiEEb;T~fz<0Czwd;L^@8yfYKvHUBDHzCbrc zp1#9jZHPCV*>b-2$8W6yE&c|A)m!1rZ#|@4UeQb4jfkR>6W97>(xnupAdO>>;3#sS zGn2Hk(AEjpMLylT`7d?(OEmVRL*#;mF{1oB0%cnA$@P|ZGI-8h=^{h+;q>cc@5(m* z`io2IH0uViis5DipDTe~x&fi1oedF*QZO|FR&d-YzyQf@tV~6I(2`Y!A1^v3yTasy zi(nQ^p!LY93R>|4MBsFHW(EiqR#6Es5Oai}2o- zr!-qPQYB^7cqQjHvkJ!CQ_uBmw|11j|4!5ia$v(57fg&MBt43F@gkwk zPZB0o({r_*k$23jEq#yevGeW8>-HrB@#(`!x~rbev+D~q?kpXpqvY??geH~2Ch$Pu zf0CuDIxbV=PGbw4OC)t%>8jE|tfFb2J%5+*OcKpubmbub!GE|mrFXk>V(x4H5EE$t zYeUpRe3rCOj`v4eTW<6f)D{*zY@>kUBR}ga*&2!Z&ns2cG+rj`?pHnxB^omOzOPWgoP_$(8x{=Cgnr+Qm=H^e5X zT;im6IA=er06X_A^_h!*%VGV4kaXpHgUQHUK38S)U48Df^3yn_b7q%egR)ApR>qm# z{lh%?#i+ zUkVt7L1)=&9hrsoqEoOAPkA@co55Sc674HdUK#c**mzwDxXs= zT)_7Nz^*%eaLo)c}!ruDK>e+mJJ}WGicn5}PCtCO?iNdunGLaO=CCjmO zG#m7C?DRoWI@{)$W?;CY23eI2UWlyPdlL-Z)s!LbD4@Mp<)9Fl2Ct}rvL_8Y@QBt4PPV8d-bS@BdkLyBaL=AqsG|j(5ZR0O`MM}DhB)BYo%W( zR#~M9xXZi<6H9Kb_oeB0(-DI`xWcus#jh3JqlUbNm`?f0AMVtR(>2=Bg*@SiEVOD* zlsMi5`Og-t;E~WGS0UI8>>Y-8tsNX2)5F$|9i=Uk>4*7HZItJ&yC7d>T0DAkQI|8J zJ3b5a7eY|W7XIb%WW*T2o%pr%8my z#qiz8S_x1p#0f1O>4II5f>nxCB9VfEpQJ96>5L2*+-V^>SF_lLnWlS4ch+M>9{Cl* z{2!7Hhkz>KLZbWZffiqDG&YMj_cboqux+u(r|wueswx3nLAc|c)E8imu@9w3mlcmR z*tGGNy&i2b)OP96+;LigR#Rs750?qae z4Iq+8r!P<+P(w~*WjH$=FT)@ts@!U(javmlKj;dVF-cE4Ce#5HSKu53AqfxZmB(o~ z;#@1Vd%CPuo9?9ZpPu}6lw`sZDuYu;0oLs+u7#-M)>4Q_vE~LL`!|17CTxKPm6>Uo zs>kU(x8NLoZO3)oB#Iqs8av3GdE%$<=C&~ms6#4vv0o(*d}&LXHb21m{G;I4ohSUKr$zOzFtEEJQE`w|Vd971C6EpR( zgW30xsVY&lhC&%TrCCeS5qBreefqLss{OZum3_SX5m|dBERk@Q%H}#EtoB>1^TVT` z_Ols;3)OXWo;6pvs+#)r0FDzU?Aq|L?T@Y& zAA2Xxx~Pj7YIHx zgc-l928z89oVZJW=-)_PP{??r|^{Rm(mcV%6* z_&WsuROfq9%HJ}mHo4W3&!B2+tL$}(xq%Jx^&4g;(?@o9wk?R;zjeMLwsu<6`S&A=(#ltK zuRu{jn0ojeeLElN{oSQu&c2D@r7aEyZ4r37Mh(C#$|f^0&y2X2$r;^biP{J}%Z;9y zQw|X8VK2qa4zEe+QwIw&-oi_Mfv70)-!tbsj4@+Rp@ie|}@~H^HL# zM%?LZhiKWK0>-W8;T-qDH&lbO#JyDI)gb3m)X~a#_T0#goA4vUt@%FO;I9RN6$OLd z93WRsOBLt*-V}5lJsEYuoWNHh zf-_Kk2_iusjbFqtPRo+M@Ta_w6LS&cnfs;YkS@CaFEr-;m1tWTbh$#xdSWq zzA#FNVF!stk(x5{nt6BKzn+7rAapH+0(tcZLC0{KZz=Ik3=44$?Pq|gf5Rq26zA8I zBvp2Y4$Q(iupiE45Ltv5R_@RZRAy3=?AO!>E*ur7wE!?H5q!G2x=yo8rLpbVQy2LH zX7<$w+JfiS{&d*9(~#&0V9qm6y0ecXH}WZED8=Yn$rf@!_m;cVfPI+AhXL);?f$cF zxLQ4<*C+e^NtD_u-Icg*d@HRjgdnY0Xq5nOk_3X~gN9d6-^U;Ms9=I2UXqYA@3uv! zXRYYx)OI)Mgl^^HaPJP)+?TG~OIyB=<}(%ZJelnLwXLe7p?O4r<^!{auZ^m?$K@Un zi7FEdRC|)iPoIR_dFrL(c89pHKWPYR=>C0O8Tq+uQvu_I2SCyILxH-w*;+ya#>rXl zzea#R0i=H7y4FJJ&Ah_z@VN#2y+7_fh;|ZX-;Myo?Y${2#rn#_Ao!FGRkMchhlB~j zxBB|}BBtX-3~x@}i$)w?t`!Y1tQd)Q5`-F#gc1V3)2n5IB>KM_^dc}$s+9=d@JV@4KdryNRlwXKkG zJ{{0BNYqxguB&H98i!O|5F?uW#%wW+PIWmMw)!1c1JV&YF8zbzIrDdW5PN)H&OT`X z!#~Zi)w}b_qWE-BOL5j}KUDZ(P?+9>J18bL_?*!_i%XxHT-0^#l-b|4Qo-c!R3v}8 z)wdK&M)S;N=K1-Zw9SWVrHY3yd1N()yX?Dxf__dQ22)cW?8O8kURb(FvS0dnHNa=(mDeXR}t(N8a zrS;%`9y**naqKuB258BM{3$5dLbly!IFZIAOy+ZIXNg8 ztkuUT76=!a(V0e}&tN^=x#_&mP)rSK)0c#|vZl=S4vYYY459yf%ny_1JycbHHZxwD ze`y2?MBv?j=96zr6qbF6^V4x%F)Nc*;1tE<@rpj5-o0~HOQi0(fodb^pn@!L!6pDM zr*Q=?2S5bJYk+>K1BW5YM5bFWBZ?P1IjHLZ(#6AOZsl+M{_B6oTF7djiQbR|M@zs+~c?Y_IZ{lYi9qko9{1Z+FF)sgkF;rf!72kW3JyA8QU2LPWrVp zXLOK3AQ@jb9vS{OB;gK#3()hjRtMz>!A1C=a-p9B`y=ODkf@-FM=R!s&l&0xWrn+i z&QsgygH|LS)Mjo*PtyQJy>%C92Q2Px=%?5O>mm_p;-k)zR!3M|dKZp;k<-?S5oSO4 z5~E1EqaO0bYoIEbmz;}{5aY0XyIPB(*vKm_N$(igq7q&tM8#pZzYFW67^!A%866+3 z%D4m{DEjHlGY$kJ;v=Mevv{45A6geE}` z;)~xsAr%@1P^UorOA?25JtZ~k2grZ2h<3mUI%;UObOR9aK0o1t^y2OD)3NklB$c$v zPe3NAKTCaSr=S65@gISSFN7m1`4;laapWaGv3nG}4z&RGr$EAUbkPCDF@Vdf(PEe* z3vTyF*2a$Ixe=ik(P6Ji5%UJ-hZ7(^s6t)P2H3l6Q}?KTGeNr3!1pW)G%!2d= z*J^@c3Qz$b0PgRU2Tg-L>I%SfPG9|gkl)!$ZCG*2qI(;)%yTDA$ipaNp8{RG+_V1n zQ!h7|sv$HVN!$3J7GQ^TCSVLzlfhhm?bjl(y)-AV@lyTH27xMn9WZeqHabU+B*rg2 zL+NPoDF6-z@~nm9sdg%UDUCKo)WFc#2?D39Kp-d=?c`Ocn_&yUElX^{Q*m{eDZzqp z3~t>B6?O6Fh`tV!ZJ87`=Z_ioIdeg^UGK1g>RAS+32ms*bq2k4APv;F$sjV4WS4-e zv4&c%9L0I!#8^%OcK(`*eDhRU*!avhV*)V-=<4nGl*IUl%mq9NZyc6+!)bXdiibj} zO_~U6U!lF%<90kWxS@Bz1V}Kt{X*~J0XQqKF>QuX4TV>)N~XRrwKDj%31t$zeZs6> zKZcax0A#^+6-*tZsLRjSG*f-AwRim)#6-v^sZ+xM#i^|_0+TR5Q_!<9g35_Svl*X7 z2}sN%@a?c*3Y**L3_u)*vJS}We8QK9B1etLo(dqc3VO0BT$oq|cynn!Bvjm);Mgs` zH$M9whJ$XvaJ|oDIAgwugA95`ddVvPE*G5-lY$3kVVg@TLV0u7L8@CH{cgbiS`E69 zug%inV3JpSLwN1y5)Zs72{Yi+JX=yWp7RtGXVlPeL+N}|AF6?-TF^j5g=XW_A6T{C z7NnW&oTugFoc{1NX((O(3UvA-^aW~j5}^RxNtqgi_0AzPDDQ!!Z?nSh8ffp8}3sNX&)4z6%! z>A;aU6=0{A#9C3`sNDMR&WMD0_`461QFCATgoI`(7Kry=y?XOzi$7dC20M5&7omT` zwmggr1|BCT*T@LBkzt!@#BCL?Qrk?5h<4b~6_`~pMr zXaISUDw)OMJ1Ebte1}fKCO+V$sCsJ}pcUr~#N7i{YAyFXfwKD$LvC4RGfmn>^gDjK_Ov#bdSoeuXV~T>A zNBx&Ie={gFxxrVY(K_~)>s;SE*N|!PNGk|%(E8rIl%v6+37p2Lve!;?Ek|kxR4{K0 zdjH>Bbqe9dc3M?>L8D9$F{;Re%ML<~=Y~LH4~5I#$e-c7c5TnPj<2LS(30(ABs1W! zf#)y*A4w%38^NPdz-pPr+nZIt(&1X7u>W1bS9-7zX^5fcZ<}O1l-=(}=;9<_8(O za_F#8$yU%_HpHw3B^tjk{`4B4G%NsNV9;#LCnV=F^Y7AP>oBKOUrD;wD;IF-7#u4E zyd=asUb{@(i+QfLDn!aLBGE8mkTVZeQbAxzv&K`zutIz4mkk2CVRqz0vV{vY!DWA@w_M1SE)dkN{haB`cC072jfjy{ivseTh^H{;(nPrr!snqYgs+zl{$^ zjR9zEKzKcOne=dXKH^*zm8J1!rr}xNQc%GFe=SucFRC#;dBW$b@68t&`vp5yH|~53 z@^;&648t#tB4N#Z9`Fxj&MFw?(YoHJ=Dw0K9Gxlsa)n~}7+f$QeMZVs*;s6CZ3jqp zsL`_^-kUsPbY^DUU!7q+kJp9#uL;?dqykiS6?ygTm^K?I1!`&GoQb8)N{-8L6o(3O z1VoQ%!2S6-Bz@U-`!jeGwDGT?^AiS+Ps7m0Pp=@t%I-D4!+MBQ{?0Per6}5uK(69~ ztB)s3eK|n-LQ-9o#Cq`?36k0jy`H0 zoRLAGV6Or~#Hv?OzE@9Url9su+I(aimh5RyZOjZ2`rJ{v|Ig>L2nnN-2?gU|EH>8OCeKIk!^D@tu&?#w06qMx9n4X1v;a>2K zeU&F%IuZy=&6L&^i4@lDV|;yK2R0NUvFJm-}xNef?5}|6t6!?MZK=C znch609qxi=9tjt6ho4eLh4nD1V7$~lrs(vkCObJY25D7Vie)87D7*YygeLx^q@;L# zNYH|L-^`uvcAIM?V(h%E*Sw*hz5FbI{h6yHn^pNhd&~|kcU9c*t)}hV#2=yPhp8Z6 zQG6eu8~2K@2(`oJ4x(|v0%#7TH#NEj)6x)no#pwSXEGJk&xafdQ?7K} z>clSNT2+XYA&7q=7QN4L@AOhOI<7LBk#D2lsyfTh%So7Xr>(b z9X3d9f{y@_=e*jl5Wwq)V6cS{glNy{Y!0P!kp-L|*gScQac><-MYrSUf1erDoMsQ^y@ZB#vLS3?;yt#fbHX56A(&jxva`r!2R5}xOyTy3=SQW?* zIs~+$t?#2|AF2&+ZxkpjBVqnASSh;UvmK2$C*Rli-s}Nmz*v=n^*~3|T)wQxM7X#b zAkcPs=rX8m900em!1$le?3D$5o`BQCxz-?>xR@B$F|*#Pu0`grxVX;t=EXl^X`yWD zo#Q`U23SZzff`4cLImvLzKF&q3LS-(8f}#^DZ-lw&jS|UgLeE;*`9hKPeP^^@(4;t zdOvPkyhlNbB}7~1-93ur)**|hRKCKc*yq_K?0zp5)W6N(P-sQaIwES~FdPQWDDE*j@Yn=u_}KNpOcrY%KG*x0SzQsKluf;@9VdbvpW1qA zrs8Y@c@P{XVvfsv*R$??^D#DZvi|8-ABwEK)=>gPJ5+PJlIzMd6UcuwhZEdr%q`#( z-AVh7jIY&*PpwJM^Clog&PRS^9??1evlas(l@X;2&s~BF0$b-mVD+-IwSD7y{~&ig zu(*6(2?4yp^Krp@AY%_QH#kfLmJqvI6t$kpLL!IM#E#BOK;lZ{nmW$Z;R#O# zKu!VFPLX9h#l%j9bi>02y>{WW)X+O@*sWYn&RM30dy_?8+{V2V(U|DfA7f8ii^SX; zt7qDR?pZ9w1N{U8UF-G8fgVC=%jBR6^v@hsw13%;(H&BsM+EzHwpof3D`z%sWhR-` zcQZ0F2|Or4ARds2>S_iQman@;uLd+spK0G*21xIZ)_-+ZvOEDtE&le0QB0ub6!LJ72zeYg04n$2pmM*sf|5Fwqfm5M zegH&@-@di9buF$EED%5|2>gx1h6jPL;4iqrI3dB%vbsAGfDB;o!o?)wJHDoSCN99+9XRmvD!pv9H{MU?64p^m;a>V5s>j`l)XilT|%$ zoMLB_O9^;Q`%4Qb6Z9TEI`V+784XmaX=r5KMfwTcWu@vk1!x_6S)#B8BEZQhq#tgN z=3@voYAV=MNdb-2zJi9^tfJsBrP5wBBYgsukBACmnGpiB zisV8{L9oyHa4=%Hko@e9?2!*!)Qbmg@Gs;)d}#nh@I!IBHoM1xP)jr9EDV`DVCjA(=`iXXidCD)cL=CPeJAD27p*R5ZHh#B=2$ zUMN~~JPt4?XfH?dpv@OeMrr{B>Qi%e{$m9l!2Iux)Z(LyvJ$Fe%!Z7~7aaMQs*v6a zFA5y4E-+6M6xsJD@l2+h8;p`Xh>0Tl?gU% z11W&?L*Ak*;Cj6FNg62FHg!3JikWLQza`sR#nPKOeI>2^bib|s;XZ(7M^azg0s6ir z@Hl^KXV60q)AJqocg>5*0k}g8K&QR9C-7pu>GOKnWI5v>AN`8Q?w_J%#8$m#epy+1 zTxI}#f5t}u?f4-Au>mi6j=_eq{vF1g26un$kyF}pNMP*oivs5mY@-O>9^nwv`B(L@ z-C|iq&3HGXUq#WezrlK3#*a7_WhY^{ii3kg(2b_=R8pYOz6Z4v7x1qsFL%LO@~PXU zbZYL#SBKNy?`<=O*qCxR*`7OIV`q>nE;G3dA&if7?)vYzZ8N+f-0@1>9p7L%jS2Jx zL=nN~+g-pkXgn7Kvlwz@rDI@$at>t^;;J)Hw3TVbj6fS>OIh^?G zpP#^A>|PD_!n8Wj@Q1-pnUq_X%Qt;bd?76un^_5Ez0QD!8w*A?Ra*$vZ)Pc`QzK%HC)Lxc z`Wk0ctXtZ@f}fqV2)O)hg<)C19$l8 zmKMIgAtOMTR|5spEacx6TmGvPe^7`zY@*!1`e)$Z|K+oYP(Ujv zI(gXw$S4~Scus)P;`W@p<%%v&N`E+UrSAl`ex3$S9DE&Ovss%VD$fj;9iCQ{MCzy;% zT!7?}FW_v-j*h}=00v>AE0G4JTU_Cn$zd)28e3r)_1D$fAvigd|8Mbeah}g4OhR9g}aJ>dn`Jf+dq;K?em$E0faV zp*Cv2P{4~QU{)2N3@8@&OlH2~InHY#&W`Hvt8cln9C@d6GXc02_MaXQRD}4{4j&2F zuirP4CH1>ZHD3hc-D$u9Xr%7&Cy1usKJR;%YK`}ULcGWSbai{Q23+=Cs$eRg(4?F@5h;A`F&`wp5I9(F~ z@y0P&pK;bEWcfufhwNhTK|k^#)Lv}54Yq5LWcbfVnnwb3#62xn&t=ZPG5?Z#6#th? z;a^Czy(VgKmm=lp!I2Jpst1<=c{8e5IA8l(Pn;icafeRGXo>G|#S6nHDZ)Qo_99tc z0bumE-aFU;1vCZWnA~ci6TgEC!`pz$xh{bbiIJ(^nmT!JivB0uEcQ~&JFa_ULz$q z!^X;KA^{@~lxKdI$}^T{VSwW-Ma#}DM8DbU;&?S@Jkoesh3se;QLOe~=psiB%BRKYD#$s5|_2KVV~=uj`sf@h>R=1FMAH0sGn3G|adtK3N6h0i}Bd148Q=YCv8Zzl>*8zkb96nVN*?r;GjXe^D%f@14mw0#xI;>E0!r`W$aUuo4 zO0wvOHtAb-TVr8*6^pmY2`PyNdI?X9-bc`S01@}Xf?hM_?&xn|Cd~PSGKfE8U$S_v zF+U->fk(XIa{V`R+DUDs5n%wQdivT~*n#R-NMOrbX;eqwT?$QwtUVnLd5Ul`J4^y{ z1rfS_vRg>FK$3y3Lgmxptg0V!83EJ!2EEfM0g<~!0v{4yCJu!34Ecn7G#lMl2l_G} zD*HCJj<0Jw?U4HReC3V^{*e9nb=X_%1v$h|oTO()^zH}_<-tl}J0yrOUz^{#vJsqH zLmt77{0^YA$%)z`TmU8^q=0~KC0M8pWQYuFT0RDK(PmW7MKdH^(P%AjatX0iKW#X$ zOnzr5tmob1NSGJa?Y&g3)2ZJ4aj8*EEiU+d#W3icX&w z^~O*Y55!LA8c1_TpvI;-6`Ru-9lFarh&!MgZZAIl_qA=0A`~%;oB56{3!nzomiY z^Y=Gl|A3fR=;)RQgG%hJPabD4EREV-Cmc7Z;bx>A!*5SNQga=uoh4NnYd~J{81Sf_oJM zeZ0A6NbkR#>zPN#w3#FQI5skactA+qQ_Z>rsi35rAC-)*W#&wSrEX9^_`BC(f0FgPdsHUW7bd*3GvNjIu2Rl@YKOe-M*7T!Jz;L3^ zwA-DDvOZgS2GYs%>Q^(ay8<a$fAfpiu&**^JJ?3LYt zWZ0*0?1gmYQ~mC#AAA*}No;b`o8mmDkEt3olA^41k;z-;?F%vAn$(*W?Xuj7Ece9u z9iHh-PciOoh#UB@xfah;E?kNnyHzX4-WL-RLCxW`gi|l*(*YVayOQ2ieqg_x2?dJd z{~*2TUFN1|O?Mzrw4{}53)C7@*TU}|l zSa$~*Z{%)x8&l!%@KJf%Cco%Ua?{HFO~BWbOL$A;E9x=+vs}jI$~cF z9#}&6PFRzlPqQ=v4YVZ$qz%@g{5yju99l>Xar`huT~YR2ny6*RLw`EQYMz2?JZ`QwZ>qAABFKB|cDO0& zMbmo+@TXfov>l9sT#4R^oRH|3)d~8!xer8#a?o3Y{Zz~GCtkEU7x#Z4C0yr^iAP+W zaMti#*3kehP^1K8774jKBSMhWv+?^}f$PSOHM3P2!E1A)(q}qzv1eF3>q&1PU%{euvnE zT_-MNCLHk1tM2>`*TEcpZaRh%QUWi+ee-KQh-7VmQWT(R>prKVXc(6o0kK~x8LMRS zB^4OQajj_kSaJ^HD4<%hz&CQkLOi5<*dXvMdIXRT-OkA4GPH{S+9>{( ztX8W@vx0E5#NsrdWTLSZBs(1F;*yX9FwMn?)sSejT~_CmkvU)04Zxk6a`Vi4=?@A| zu&v#cln9eSPpKE`zB4Ev0OFU25x6Kb`zLfw5#uy+2h)-OEbxx`ES6u=(>S^p|eOfUI&y*L!40aw*E-xsRF9)N*L#Na#9iyImZJI)B#I8qrV<{n1pp4SJ{AQx$}diWo4U^ zjm!i=G1JSHzri|c8p8fY!kQ)c+f;VoJI-4)%kaIb>^Cc<_R4<7vvy$^5;@xSVAq{} zIg0q`OBoKyLIA&muc5^@c+Gh+JWhR0FqUj7IBizZ34|dWsIYy(b*_u^5eDv#ped_A zv6r7(;8Uad`toi02{I)R7f*|v^tf&eIrW6BGf7OYZ%p$ z*YLc+9l*ysIo!z2Tx-1%>+Ea5c|m4a_}h5Qw5lIfQX;AomY6Kd&@{NhN>?*{=XxU$_9ow;{pXk}olhjUr{-hD=JHHx zNGVPJ_Hmz(*79{bSS=_{UqmF)P=#Ixguzt?;mNU}0Ol6FT}nW%tOY2uX&Ra4o-|}# zscW~;yxuF(nZI^c2(WyJ-L*JIwKYH3WQ;(LKPz@rgrpK~@rO>oS#Mw--`|wuA{kVD zTr3Kbo<&@D4X|;SDR9m#>iw4n&5U^`oQUI9bVl}_Qui~#Q#_n?He_?W+{vGpQ+?&p zPDYJ>5w|V*^R+@^sZ`A#Ko~=+Ih?GK9v1<{2LV8aQmE10rd2(0FY&IG7sZd^f(=gE zey3`u`dvgusKNv(4O>5YeW~FIX<}~_boh^r&7$9mnVmi4?xROPFJ8Qt(DA}Lrd133@IrL0G4jlhb?fO*h%Aa;YfES7@h7ew-5R*SN`EFWvj zz8zQUy&W4E<+}->?-gp7qA(|B^^E-R>#CQNl~C4oris5 z>=@b)=?)nR|DXt3IBI)d6FH;Z*6Yu#z!LdYOq@ubevXG07)B&WA9CS~`M`CsT2x)1 zzKO;HusdKJb7Bm68p%wM+uWdg4bR0Q|K*miKX?@W1i)2Q&47n*O-@{y-=Dv~7snx; zWA)!;&ivtL-026G)qNm2;5t>PtaJ|{yJ*yF?JNE1uaA1t{Mh0 zmrMNab6LH)?Of*Y4em`*_El9$7Bh1YHEehc(?sV{8zhFQc3$T{!yZ{4t{j3JfWX(X zWbL)o3mV7DT)mq{VH9d&%9H0{2U13sIQ}K*`CWwvmZ`S?{hfvxHQAi6tVE!Hl7&Yz@5m@{9)I*%ccfO1&?f=2CK0A6 zlv8^%dwq1r#Z&3g|F0S-~7rpgR>Hv0o*^hiauDh&e`J5ttxPi zlXu1X~vL_B0I{A=b9^FH@ApJ1#d5W6V80cuJ#ZSZXgKj6Syu!0oJ_{ioDN%G5GuMC`JA5>W~ee;Kiu zj^}HD@?S7F6VhdrwX8zeAdJ(;gz9#n+BdQm_mgIGB;NX1{;mQc+sMc#?g+1bQB^B1 z9!ApP3=AIYRl%T4LUQu<9ZEYv1TX9`8mj~X&}j+#$$X$T!u~=P)z%n!lKMfmK_3!` zUVRNz-JE5-03i@lNOCn*i6|p!I+QF{d2)ea6*_Et{RCnZ$AjA@R(!ie%S%d2E#}|4 z0>RSrwY=c}4i5jx8lkv^O^#+H05xS>a<7(8e2~yH;W4wS+a2>2y>r*p<%Y<|7DNjM zs4brS(;RTD7*fSAaHj(3yMiIj#WNH3P~2xFmJNc+SnMD^ur&gxncNztgG?XHUmnWy z@d63duS>X_fvwPwiUF5KO-l6tEpVom)baY{ocbF8@;+QTQ^7!&-rnDNeHN->yF6J+ z=tDx1Z%`i|7YA*{J?lOyfqEH7 zyy(VPxC2f8sEzqb&o2Pp(tyfdKb6vYdUM~k)WGKQ8|kR8?vP?=pKPhv?SiZ)gCu##+HACioQPf-Ph^ zQ{sAyPN69D_%)UkV6g*7?dR`2cH4e7gnssc#4)S+7arSlzw`J870?%%KkXgwEWU#@ zU={bFb>eprxs||L&X`NdSf-g-N$$<(#wGQIM$;T3V^iZ=t)tT)-+ETn+q#Y!$JN(c z?L;cyT+FT0B&f?RyFz{w{HC7=GGQCdmEWMdcT)P#+p-=gB7)NT73JjGLmVCFq}Zs# z;#~;|Gl~WYL#zV6e}?b+1pO_4^X84;@ovPY@*r_&u)Zlsj^u<=&eBee`Wqt>6WujyM>m!SH5DtuZ1ib~uEBS8pa!avbRQi~(qk`ZAMq`C-fFJ2xVvtA zqI~AhakJZi5j4(hx7LBEU|vO50!#JbNP(ZS?NThS+gh2dv~~~hVRMxMJHj+innP8B zVDx#~KFk08H`8sDb5SBBbgYOjYuhf|qsUze$YO{mg+`CslqjIw;Z-(>sc3DiOTaN> z!ldHkpNa+@;XBzTgRU9P)-G{p*)qCFjgiR&GR+fEY<29Svz?v~g zBEI=v@!Hz#Zz@&kf`~G(qbcaoLGdLE0$XxV?Ev5z6`}M902vLG3lZ4}GKfU&wx*H@(nf6ixPhwn? z#>CT$lKe^uJBQUsi`!qkOB>Rdtg&}BuRB@QN#b^y@EoVN>>K&WPca*+!-!Ft0(T=? z_roHlCGpc+{^uB#?&m%1&^kjTcJVVqnKysGY6wR7`T1=N_s#Mfu6?u^+h56aB0(`E z+PMQSl~@8#!2a_j7ow_oi^9Rw}dusjZcCm>O(PM6YQCZSo@XRH zl-asx)fiq>RCM8VT(-8z@nL%=*^fpRx$wa7!1nF64zGAu@!$K?H~2jusE3Cne6mxz zMfq{l`M8{;f+{=kcjXq^F6P;wY_OhSd9S?9w#!5zy!A$EdM!cGE zUp@xy?&nh}-s>6i&L>tHF*W1Au8iy%V7UgPL-HLQi+i$6VO$y(+L1 zsXGpc&ULBf9b-*ucC*}&{UGauVdKKp47$M{%er7~TCHPSk`(N(%0X;vijkUGBKGLW zBU7gRzR&nbcg4%Jh#@71-O`R>l$4U@+Eu{|vdc+u3*t^<%fR}1)MoD=qB{H6sJ38+ z7x_KE{~#*kX=iP^?9XTX2tf`e=QAUTgBmyVSc2@Xe36C%Yr9-%&HE=Ku`0y=#Wk3( z>PYn?Ch^r{Sld@)ZC(fkk{xBszhU)N4qUn^bvk_1Vxnf@ZoOa3Y>hFWO*(QZonYwg z=~-8ovmXJzif*fg%$Uy_TUF!$!ZH7a)+e+i!nqmooF z;)DI2g|~9OIkiOrx=Q;qJ3BkKT2icprCR()c?{~qB#VtG=M244>Zur9?0+E>wdsAC z!7wZr-Db7AvZ7M|cH1xA=lP6ZzUCA!%6=^zxqA{mu{QLKYo7jsS38~mAI#jhI zfW7U-_Diu+Ul3%sw1}EwepM|l-jd`DgrYY9xXuDn=OS66rHRDw?AY|Sy{p4z6>x<=#%>8SkvQ}MrX4G%Moi|>GaRo#;}*loHp?hMrX-bgyZ8o}meQFWZ`8$gi;zU*$lvVH*7 zvt`2O>C!EA@8HCBY6y=_9C4`Eu+t}CB4w!8^DI6Zk#;x6&lH!6wdKTHK|B}HtB4P< zf6?OhjqFK9r;J5e^h)8Bm!hI#Ba`b6KsmwLTpEaJ48k{Va&C#XA#~_lR9haTVj)?* z^&VVs%6V^bY4W8vB$9F`$oH=1fAR?WQjC6wTSNDEPXiN0&qp17iNInDVN4ubHZ8D}vX@UCya! zs2tesVgp4$A#915_$zcsV7_^k8{w;lYejw#Jqy1!Z$+Y?^gt{W(Z)-dKqAYGoqPU%CxU^5#g+dty1t92fRYY{r0Ry#?% zcb;OW&W_VU$UYgN`lh2gJ{Iy0=Jm!##dm0v4Za+*%WGc0Y!*-nEG6})QViWtLuK=O zk=^$GUqn+7OW_0=9vgu|%jyOBK)t-8f(nSPjE{%J(jfc_h*>F-G6&W{q=hyb$R{VBI zbrD7jcMif&Du}MznjZ1YLVWTX(}xt%?qh(k=+@SzgI;vQkqH*GI~w0t`yl|Du*dCI z5ay6-n(s7m@``b*A2&t6H8lA=^FQ>r6(O_P5Yi`5+0}!iJcYO3QWIw@gA`39?dN{` zD(`V|a$wtI?N*cjC&5UV_0v*3x^ ztRRe9Q3iK1lY)(n2NcoIkr1qO?pL<27*_y0IV_L`6p$HD3ZZbafNP~ZKn0q7Qbzy$ zXtGiAMP(`>46F_KiE)9$Gq+DAv{j>5_#izyIT<2l*L#F6f>6gn|M7xR8Yp+I%14s4 zg!R;s>duyXM^M$hdr9@?083D04M-xbYR>D+?)q?l*5UQzih~WTBA=I)J$WCBdlK3t zlO8ih!7bCZkfWyst>OEqs;X*;YR_sq!u14x9Ke+zA9F4#(A_H7_#K;eM%Bn zVpN;%wqJDy<^G#vYoc(?RV;)T_vC#B8yD3U6&3i3;a#HJ&cI3?;qEN>bGWqzAdWVo zt|VHM=$sR}xE)_s27D=46Dv1t%BXa7DrqbA@*Rsq)-}7cu~UCu+`!k4Fdf+o*GIxn zogZ9r_&IBe$~qamNp#GKFXaVK?p0mFbThSYZoX)_Zlg(1=~#D7u|e+MC^!VBHsew) zr+unV3B<2{mCZ^wpUJ2og^Yh3{MDp(ZmY@sck1owO^nj5p6ua2(qaq;_gD4e5_5`B zYjXzc(krL+KB}FgCcC@4S2ENPj+daZf^x-mwio6^Qj2C)TB9U;Be&jz2@?%!8qzpN zeFf{6llX>*hvmx92aLfik;|`z(Qi#zv*PLfpAvtyIUIa_9s9k4bjtK-R(zleD~VM6 zKPkS``HkoUDqFc|zPWr;W=5r3A+)$LYpLEy6&QkkE^qKA9n74@&40IBENqwYVn+^? ze|83g!K9j^!0r2%nI~tQFtb~Q;sa%9EQsI|;u@m7#xpjJ^OwAoLvEeyQ24_QyRI;==%zpl8Hz(*wfUjvrnl$UL99l={4dw>1ZB z&L2Gg^Liza2JMh@#1q`pqT~I#lub|l<+GI$MIo>>l>%PhHexw)&zQmqB@tXm9!g&{XTfqGM{Gv_3%!vqK8a%=AYGp6eQQp6T z2c{P>IIaCc>E(MNI>WWXsX%smrqX|kC}oEDTkoStd{X-*8YA91=kYAj(}^vcME*{ zpBA{F**Psoj!t#@T&ly!ZHWi}bY^=--V!?!+2+7E_Zgkg7W_Zn+Z4`Fs&{K`}y%TTX$$xg$YHM#deePJ$BPyYo&Y9`x^Ig=%8Cp_- z2yM1TPk`D`N=i!KLr?1BaOZ&CA-q54^7Hox6rVqs^Sq#Uz)z>Q_rA{QPpo#p3@1p- zW=A0OC$)3Bfm}&vW+s;v%>Vq8jrl3ph_#@Rxmi;fUSyWI-A^t4yQ0it{3aD?B|zf7)uw?y=_RjxJ%kSElNuvL7GV^gjJKZ2+mW&P&rYdQvt9 zVCEu%9m2yaWCg&3mft7+8~4u>D&xI`(EPE_fbi;~HIqAi-NF7prrh3|0LI|gqw~Rs z@EZS94VbpyMh(%EBU>lWkiSjg81ClB^!(Tnc3)g&xkfC#|Vz?EA{ znp5hvi2S>XA|rX!N8am_(A|FwNMUUgh(x)NpDAI0IV$9ub{4}2Hn(m5pV~GW8hOZO zkT9;$PE#cHgw0<1%KhZfZlEC%7-pI4x|S4Hw)1((uA>?KkDRG!{p2VU85%4uDoB}m zXYdVncHFY)Xb$_Ir+|r^Ahh>gS8u??t+M)MB_^o4QyS{eG z@dNRX(SMxOi6JND!^z+a3q*Ur;;ed6vmhm{Ez@ib@22}we zZm07629IAGV4YxvZc_B9F7F`rvJEx?x$0OMmwTza$WTnS!FvwM;Z3=TxyS_Xi$IM%JU0= zC#*Zq53d7cfB2@n9~`jxJ$&n^6W?C@%^bw_>w%Z&HfP|DgOESUa|^dyNfcZrpEroN zx%yDZTypan$>8Fp-V?vENNq8$Z6sbBQp0u^ii+;hGhYC>T5gTFkz8`@uP82ZTuK^WCF>-L+ zvJ3gF2L`~+7tm+aSA^9l}m=Le!cCnIr%%G7}Y5RgH@Z-JTFp z=ZNjHP`<`17}S=lXm=Ti$0nH0`aC4?w;ebvYv04ano#mc^dyLm1sj~ml`*@Vo~myH zD)bY=IAUDW(npYWc{d&lec)6(3BYRzRP@HA3ooyNS|b>;cFb~f-s1zC#=0+XCuII` z-Hv6Dn%x5@ea-*UgLzX!K9=1Kkq7Z)6C>3_*T&##(795beAY#@AlL7R zS}?-jNDP8lrmtev4cY1U+jUDpx)T5S!_}7&U$MUO-`pZ`3j^wC&|Gv%k$)dv?R5@+ z?9-1WdZTFIx3UMxJF4xf4*zC4aw2r|SSx>L$ITE~m!E?;NEf1yn@k(qT~GSuu}?p7 z6jhC<+ymjlIZjJO@H0)Egf?4J&dqj2-LSo%+n5JBiL&@FkQy#u?qdCe_P7P+2{9Wx3)f5GA zi6+1Dy~*Dv(DC1YM1JO{dj;_4XFT3(f8iFp_1Nnfo+;x;g{oP0(*bJ_7O7I8iz7}a z`Hi;QULXW&LDL)(iS(VvgAN}ulC)*xb-#H>{JBcIWQg*au9@|-T?jSYOg{B=&nl}O zCn!NW%z*X{&@0@Ii>GQU;nM2YiJA59E6X3&5q22K8&f#YZd~}LWMXn_RR#YjOz6W4 z&igDx5z*#*r30FvcR4VJqX66Lab4rZyryK<_g>g9B8XMp{r(=7Kq}bzB)^6CljnGo z03w)n(ssSn+4&Dopdj{yw*X;azh7r&N|nB97p|P5c0^?$U8Ny5G85YUwip+NLG4{h zR<^S|_ogxKmkU54G+i%f2Y?f)qnhv+PZ@ftgE%q(^4XXQ=q3Y7@&p|uKCfNUoBzRc zFcC&RbmO1Nhq^)YK(QjHmD}j+9V3%lq_b;Es5~Y~Mm2d$-a+MjBP%$rtD`lU}+pj=}h>&TX>TERGmGICsu1*_qzmd>_vv9acG*pw7YpM z`3q>!#X{i+^po7dd)C*Soi8>9UIOPudWG@Qf5g__aze7B5@rvm0Yqtd#+fyCWX0uc zB4;B50M)m16gEtp$3u2{A7t-BeCfbIyz=y8W1o^iLFC5Ws#!UuIFf{Dx~cC=OrPcR zrN`B? zsd3|j4A-{dno8iSc?Xs%xlIoNTR#A-t2)G(=D?~thgY?5ySnW3FZ@qTL%kQ!(%7lW z9|m@Uy`Sf!4cDUESzul+RK}u)UHjd`g!Lj&Yci4*(`PL5;BllRk}L#$G4wLCFm+=B z2OjPS;u{TR<%;i9%CcpH3#6t+q3mcKhglPZ@S_+R@2JG?VgCwKQOqpOmI>F z^;q1bBZk)!8=glU3DmyC;!}MrXl3Pc&-QaTJ+>*-Bh$I6@f125x5j`AD)RqTLlGMy z-vYgFO(=uGRjJZP_vLYhC9u>f%N1Rp9-iX?z<~~Rf&wi1;JGm?(Ga(wpnnBm4v$iv zL)4_g4F+{dezllIb|jIY5)N8LeV~#Mh4dL*#W=JjLpH96mR-de3zg1RAk=I?*SEOL z|J7a4EHQ*Kq*?;Cuoss5F2A>c_Aa2K1II(?$10KjzJ)~*1zZUf>7>1R z?M&AVg{0*dB-fP>2^JO>iRjyTumQyXw5dmQtQk>v$oiH7|DJ`p`3O@`{X9*1(E(R~ zoE-n`x5STtmJ|svWtYKA`%KdO0MOlX0q?>s$4x5d!!)GtZESWf^*By^*88i+jXis0 zFvy6UcpNCA3-98#-~9?IfrFXJzNowsL~t+bLJ?%iuv8AKoQ!VfLOvWD+4nfjp?FCk ze%y|Byd2qvEIEDX@g&64kPl*7SGs34&X{rz3akQ4N43uf*fK6{LpELXIO2qYejcn3 zNwQ*8CuA8XaH!2xDZAK7g~fa-33M4<%KGb>7dUX2ui@B`uDO#65hFr^b1_C`ClKJeTkSfwPu(qt? zappuAY)Kq}R5(HouJw%)!8d{mPj1Nyx#S=xa9;(BX z3UuO;mG1*QNdNeRyQp=o4As|dMjc1GK9!o@_^y}O$^VMLMFv;~`!puuZ(`rWVB*Vkzuj5rPg!Z{bb z3;GD{-j#jdqrd;YBj_U9K&)(!-+T=($D$LEhF%3@^Jzym-6~~gvzO0!Me2;Of;W>C z2iIJ_2JDQ1(geB=y++97IgnsEFK=%-Z z3^g9x+rF}}LCHvGTC!%RujN-b3mPWlCSr1+m1#lfVZp^~Jfb zCtXAhWx<6y{OS!ud-a9zzB~Vn6K=N(ZkVrGXk7o4cMl7kl6q^p|U3W%^PI4{Da!W9GW2sRvr9a4xh7#uMwm&(3^m5bJ~ zjKNd<^07OCVwRI6R1g+Yo$L$nV>aux58yg~qE#mVRQ%f{x0nJ}_ zYFG?mB{!^-D=jz@QV3la3vxGgXz8g*|Cx%RiwSMAqgw2syYO()q5Z%AE~Cf@u#hX^ zJio-f@V6VRCq_0+NMu|9RaHYo?G6W-r)M?0tQ`9)v@!G8QL!r)13^4wosrG1E#jCT zXwftA+E{WWGy~$BW>hCY=_I^0Vj||P(y80T1-P+D4HHs0L5_xN%7I)SnA+8r_q4kE zF^bo5H$drDT|V-k9(IaF>^$ngZBD4O)61gW8SoLzq7KgA|H$KwsZ_)r#tC>|ftq^C zz}bw&y6KI2*!tb8k-!=L9$pS=TCM}ys1;1QhU-IkObFn|EBkz#%;a?Ef|7m@~{au1Xu$Dnepw|z$oPNPt_ zR8f)Gbq@>LMX+E0fR`0O$ziah;MocX$Zmq>+IE7@)V-e71s@CJ%RRN>iKjY_D0dJ= zI;Uo4;$vDTx$~$)5Gyt-`fHWuI}2PZU7L26;9v8gaWGX2$DKL=R@J1`R7{^+nl2PU ww}d@?P9R=lS$Pq~YNUbv|DXSt24wKNsu%-8D+%F1g}~>krarbv!}{_60UN9I^Z)<= diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/.gitignore b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/.gitignore new file mode 100644 index 000000000..eb29ebaef --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/.gitignore @@ -0,0 +1,2 @@ +jose-util/jose-util +jose-util.t.err \ No newline at end of file diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/.golangci.yml b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/.golangci.yml new file mode 100644 index 000000000..2a577a8f9 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/.golangci.yml @@ -0,0 +1,53 @@ +# https://github.com/golangci/golangci-lint + +run: + skip-files: + - doc_test.go + modules-download-mode: readonly + +linters: + enable-all: true + disable: + - gochecknoglobals + - goconst + - lll + - maligned + - nakedret + - scopelint + - unparam + - funlen # added in 1.18 (requires go-jose changes before it can be enabled) + +linters-settings: + gocyclo: + min-complexity: 35 + +issues: + exclude-rules: + - text: "don't use ALL_CAPS in Go names" + linters: + - golint + - text: "hardcoded credentials" + linters: + - gosec + - text: "weak cryptographic primitive" + linters: + - gosec + - path: json/ + linters: + - dupl + - errcheck + - gocritic + - gocyclo + - golint + - govet + - ineffassign + - staticcheck + - structcheck + - stylecheck + - unused + - path: _test\.go + linters: + - scopelint + - path: jwk.go + linters: + - gocyclo diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/.travis.yml b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/.travis.yml new file mode 100644 index 000000000..48de631b0 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/.travis.yml @@ -0,0 +1,33 @@ +language: go + +matrix: + fast_finish: true + allow_failures: + - go: tip + +go: + - "1.13.x" + - "1.14.x" + - tip + +before_script: + - export PATH=$HOME/.local/bin:$PATH + +before_install: + - go get -u github.com/mattn/goveralls github.com/wadey/gocovmerge + - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.18.0 + - pip install cram --user + +script: + - go test -v -covermode=count -coverprofile=profile.cov . + - go test -v -covermode=count -coverprofile=cryptosigner/profile.cov ./cryptosigner + - go test -v -covermode=count -coverprofile=cipher/profile.cov ./cipher + - go test -v -covermode=count -coverprofile=jwt/profile.cov ./jwt + - go test -v ./json # no coverage for forked encoding/json package + - golangci-lint run + - cd jose-util && go build && PATH=$PWD:$PATH cram -v jose-util.t # cram tests jose-util + - cd .. + +after_success: + - gocovmerge *.cov */*.cov > merged.coverprofile + - goveralls -coverprofile merged.coverprofile -service=travis-ci diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md new file mode 100644 index 000000000..4b4805add --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md @@ -0,0 +1,9 @@ +# Contributing + +If you would like to contribute code to go-jose you can do so through GitHub by +forking the repository and sending a pull request. + +When submitting code, please make every effort to follow existing conventions +and style in order to keep the code as readable as possible. Please also make +sure all tests pass by running `go test`, and format your code with `go fmt`. +We also recommend using `golint` and `errcheck`. diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/LICENSE b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/README.md b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/README.md new file mode 100644 index 000000000..55c550917 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/README.md @@ -0,0 +1,108 @@ +# Go JOSE + +[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4) +[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt) +[![license](https://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/go-jose/go-jose/master/LICENSE) + +Package jose aims to provide an implementation of the Javascript Object Signing +and Encryption set of standards. This includes support for JSON Web Encryption, +JSON Web Signature, and JSON Web Token standards. + +## Overview + +The implementation follows the +[JSON Web Encryption](https://dx.doi.org/10.17487/RFC7516) (RFC 7516), +[JSON Web Signature](https://dx.doi.org/10.17487/RFC7515) (RFC 7515), and +[JSON Web Token](https://dx.doi.org/10.17487/RFC7519) (RFC 7519) specifications. +Tables of supported algorithms are shown below. The library supports both +the compact and JWS/JWE JSON Serialization formats, and has optional support for +multiple recipients. It also comes with a small command-line utility +([`jose-util`](https://pkg.go.dev/github.com/go-jose/go-jose/jose-util)) +for dealing with JOSE messages in a shell. + +**Note**: We use a forked version of the `encoding/json` package from the Go +standard library which uses case-sensitive matching for member names (instead +of [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html)). +This is to avoid differences in interpretation of messages between go-jose and +libraries in other languages. + +### Versions + +The forthcoming Version 5 will be released with several breaking API changes, +and will require Golang's `encoding/json/v2`, which is currently requires +Go 1.25 built with GOEXPERIMENT=jsonv2. + +Version 4 is the current stable version: + + import "github.com/go-jose/go-jose/v4" + +It supports at least the current and previous Golang release. Currently it +requires Golang 1.24. + +Version 3 is only receiving critical security updates. Migration to Version 4 is recommended. + +Versions 1 and 2 are obsolete, but can be found in the old repository, [square/go-jose](https://github.com/square/go-jose). + +### Supported algorithms + +See below for a table of supported algorithms. Algorithm identifiers match +the names in the [JSON Web Algorithms](https://dx.doi.org/10.17487/RFC7518) +standard where possible. The Godoc reference has a list of constants. + +| Key encryption | Algorithm identifier(s) | +|:-----------------------|:-----------------------------------------------| +| RSA-PKCS#1v1.5 | RSA1_5 | +| RSA-OAEP | RSA-OAEP, RSA-OAEP-256 | +| AES key wrap | A128KW, A192KW, A256KW | +| AES-GCM key wrap | A128GCMKW, A192GCMKW, A256GCMKW | +| ECDH-ES + AES key wrap | ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW | +| ECDH-ES (direct) | ECDH-ES1 | +| Direct encryption | dir1 | + +1. Not supported in multi-recipient mode + +| Signing / MAC | Algorithm identifier(s) | +|:------------------|:------------------------| +| RSASSA-PKCS#1v1.5 | RS256, RS384, RS512 | +| RSASSA-PSS | PS256, PS384, PS512 | +| HMAC | HS256, HS384, HS512 | +| ECDSA | ES256, ES384, ES512 | +| Ed25519 | EdDSA2 | + +2. Only available in version 2 of the package + +| Content encryption | Algorithm identifier(s) | +|:-------------------|:--------------------------------------------| +| AES-CBC+HMAC | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512 | +| AES-GCM | A128GCM, A192GCM, A256GCM | + +| Compression | Algorithm identifiers(s) | +|:-------------------|--------------------------| +| DEFLATE (RFC 1951) | DEF | + +### Supported key types + +See below for a table of supported key types. These are understood by the +library, and can be passed to corresponding functions such as `NewEncrypter` or +`NewSigner`. Each of these keys can also be wrapped in a JWK if desired, which +allows attaching a key id. + +| Algorithm(s) | Corresponding types | +|:------------------|--------------------------------------------------------------------------------------------------------------------------------------| +| RSA | *[rsa.PublicKey](https://pkg.go.dev/crypto/rsa/#PublicKey), *[rsa.PrivateKey](https://pkg.go.dev/crypto/rsa/#PrivateKey) | +| ECDH, ECDSA | *[ecdsa.PublicKey](https://pkg.go.dev/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](https://pkg.go.dev/crypto/ecdsa/#PrivateKey) | +| EdDSA1 | [ed25519.PublicKey](https://pkg.go.dev/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://pkg.go.dev/crypto/ed25519#PrivateKey) | +| AES, HMAC | []byte | + +1. Only available in version 2 or later of the package + +## Examples + +[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4) +[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt) + +Examples can be found in the Godoc +reference for this package. The +[`jose-util`](https://github.com/go-jose/go-jose/tree/main/jose-util) +subdirectory also contains a small command-line utility which might be useful +as an example as well. diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/SECURITY.md b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/SECURITY.md new file mode 100644 index 000000000..2f18a75a8 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/SECURITY.md @@ -0,0 +1,13 @@ +# Security Policy +This document explains how to contact the Let's Encrypt security team to report security vulnerabilities. + +## Supported Versions +| Version | Supported | +| ------- | ----------| +| >= v3 | ✓ | +| v2 | ✗ | +| v1 | ✗ | + +## Reporting a vulnerability + +Please see [https://letsencrypt.org/contact/#security](https://letsencrypt.org/contact/#security) for the email address to report a vulnerability. Ensure that the subject line for your report contains the word `vulnerability` and is descriptive. Your email should be acknowledged within 24 hours. If you do not receive a response within 24 hours, please follow-up again with another email. diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/asymmetric.go b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/asymmetric.go new file mode 100644 index 000000000..7784cd458 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/asymmetric.go @@ -0,0 +1,603 @@ +/*- + * Copyright 2014 Square Inc. + * + * 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 jose + +import ( + "crypto" + "crypto/aes" + "crypto/ecdsa" + "crypto/ed25519" + "crypto/rand" + "crypto/rsa" + "crypto/sha1" + "crypto/sha256" + "errors" + "fmt" + "math/big" + + josecipher "github.com/go-jose/go-jose/v4/cipher" + "github.com/go-jose/go-jose/v4/json" +) + +// A generic RSA-based encrypter/verifier +type rsaEncrypterVerifier struct { + publicKey *rsa.PublicKey +} + +// A generic RSA-based decrypter/signer +type rsaDecrypterSigner struct { + privateKey *rsa.PrivateKey +} + +// A generic EC-based encrypter/verifier +type ecEncrypterVerifier struct { + publicKey *ecdsa.PublicKey +} + +type edEncrypterVerifier struct { + publicKey ed25519.PublicKey +} + +// A key generator for ECDH-ES +type ecKeyGenerator struct { + size int + algID string + publicKey *ecdsa.PublicKey +} + +// A generic EC-based decrypter/signer +type ecDecrypterSigner struct { + privateKey *ecdsa.PrivateKey +} + +type edDecrypterSigner struct { + privateKey ed25519.PrivateKey +} + +// newRSARecipient creates recipientKeyInfo based on the given key. +func newRSARecipient(keyAlg KeyAlgorithm, publicKey *rsa.PublicKey) (recipientKeyInfo, error) { + // Verify that key management algorithm is supported by this encrypter + switch keyAlg { + case RSA1_5, RSA_OAEP, RSA_OAEP_256: + default: + return recipientKeyInfo{}, ErrUnsupportedAlgorithm + } + + if publicKey == nil { + return recipientKeyInfo{}, errors.New("invalid public key") + } + + return recipientKeyInfo{ + keyAlg: keyAlg, + keyEncrypter: &rsaEncrypterVerifier{ + publicKey: publicKey, + }, + }, nil +} + +// newRSASigner creates a recipientSigInfo based on the given key. +func newRSASigner(sigAlg SignatureAlgorithm, privateKey *rsa.PrivateKey) (recipientSigInfo, error) { + // Verify that key management algorithm is supported by this encrypter + switch sigAlg { + case RS256, RS384, RS512, PS256, PS384, PS512: + default: + return recipientSigInfo{}, ErrUnsupportedAlgorithm + } + + if privateKey == nil { + return recipientSigInfo{}, errors.New("invalid private key") + } + + return recipientSigInfo{ + sigAlg: sigAlg, + publicKey: staticPublicKey(&JSONWebKey{ + Key: privateKey.Public(), + }), + signer: &rsaDecrypterSigner{ + privateKey: privateKey, + }, + }, nil +} + +func newEd25519Signer(sigAlg SignatureAlgorithm, privateKey ed25519.PrivateKey) (recipientSigInfo, error) { + if sigAlg != EdDSA { + return recipientSigInfo{}, ErrUnsupportedAlgorithm + } + + if privateKey == nil { + return recipientSigInfo{}, errors.New("invalid private key") + } + return recipientSigInfo{ + sigAlg: sigAlg, + publicKey: staticPublicKey(&JSONWebKey{ + Key: privateKey.Public(), + }), + signer: &edDecrypterSigner{ + privateKey: privateKey, + }, + }, nil +} + +// newECDHRecipient creates recipientKeyInfo based on the given key. +func newECDHRecipient(keyAlg KeyAlgorithm, publicKey *ecdsa.PublicKey) (recipientKeyInfo, error) { + // Verify that key management algorithm is supported by this encrypter + switch keyAlg { + case ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW: + default: + return recipientKeyInfo{}, ErrUnsupportedAlgorithm + } + + if publicKey == nil || !publicKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) { + return recipientKeyInfo{}, errors.New("invalid public key") + } + + return recipientKeyInfo{ + keyAlg: keyAlg, + keyEncrypter: &ecEncrypterVerifier{ + publicKey: publicKey, + }, + }, nil +} + +// newECDSASigner creates a recipientSigInfo based on the given key. +func newECDSASigner(sigAlg SignatureAlgorithm, privateKey *ecdsa.PrivateKey) (recipientSigInfo, error) { + // Verify that key management algorithm is supported by this encrypter + switch sigAlg { + case ES256, ES384, ES512: + default: + return recipientSigInfo{}, ErrUnsupportedAlgorithm + } + + if privateKey == nil { + return recipientSigInfo{}, errors.New("invalid private key") + } + + return recipientSigInfo{ + sigAlg: sigAlg, + publicKey: staticPublicKey(&JSONWebKey{ + Key: privateKey.Public(), + }), + signer: &ecDecrypterSigner{ + privateKey: privateKey, + }, + }, nil +} + +// Encrypt the given payload and update the object. +func (ctx rsaEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) { + encryptedKey, err := ctx.encrypt(cek, alg) + if err != nil { + return recipientInfo{}, err + } + + return recipientInfo{ + encryptedKey: encryptedKey, + header: &rawHeader{}, + }, nil +} + +// Encrypt the given payload. Based on the key encryption algorithm, +// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256). +func (ctx rsaEncrypterVerifier) encrypt(cek []byte, alg KeyAlgorithm) ([]byte, error) { + switch alg { + case RSA1_5: + return rsa.EncryptPKCS1v15(RandReader, ctx.publicKey, cek) + case RSA_OAEP: + return rsa.EncryptOAEP(sha1.New(), RandReader, ctx.publicKey, cek, []byte{}) + case RSA_OAEP_256: + return rsa.EncryptOAEP(sha256.New(), RandReader, ctx.publicKey, cek, []byte{}) + } + + return nil, ErrUnsupportedAlgorithm +} + +// Decrypt the given payload and return the content encryption key. +func (ctx rsaDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) { + return ctx.decrypt(recipient.encryptedKey, headers.getAlgorithm(), generator) +} + +// Decrypt the given payload. Based on the key encryption algorithm, +// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256). +func (ctx rsaDecrypterSigner) decrypt(jek []byte, alg KeyAlgorithm, generator keyGenerator) ([]byte, error) { + // Note: The random reader on decrypt operations is only used for blinding, + // so stubbing is meanlingless (hence the direct use of rand.Reader). + switch alg { + case RSA1_5: + defer func() { + // DecryptPKCS1v15SessionKey sometimes panics on an invalid payload + // because of an index out of bounds error, which we want to ignore. + // This has been fixed in Go 1.3.1 (released 2014/08/13), the recover() + // only exists for preventing crashes with unpatched versions. + // See: https://groups.google.com/forum/#!topic/golang-dev/7ihX6Y6kx9k + // See: https://code.google.com/p/go/source/detail?r=58ee390ff31602edb66af41ed10901ec95904d33 + _ = recover() + }() + + // Perform some input validation. + keyBytes := ctx.privateKey.PublicKey.N.BitLen() / 8 + if keyBytes != len(jek) { + // Input size is incorrect, the encrypted payload should always match + // the size of the public modulus (e.g. using a 2048 bit key will + // produce 256 bytes of output). Reject this since it's invalid input. + return nil, ErrCryptoFailure + } + + cek, _, err := generator.genKey() + if err != nil { + return nil, ErrCryptoFailure + } + + // When decrypting an RSA-PKCS1v1.5 payload, we must take precautions to + // prevent chosen-ciphertext attacks as described in RFC 3218, "Preventing + // the Million Message Attack on Cryptographic Message Syntax". We are + // therefore deliberately ignoring errors here. + _ = rsa.DecryptPKCS1v15SessionKey(rand.Reader, ctx.privateKey, jek, cek) + + return cek, nil + case RSA_OAEP: + // Use rand.Reader for RSA blinding + return rsa.DecryptOAEP(sha1.New(), rand.Reader, ctx.privateKey, jek, []byte{}) + case RSA_OAEP_256: + // Use rand.Reader for RSA blinding + return rsa.DecryptOAEP(sha256.New(), rand.Reader, ctx.privateKey, jek, []byte{}) + } + + return nil, ErrUnsupportedAlgorithm +} + +// Sign the given payload +func (ctx rsaDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) { + var hash crypto.Hash + + switch alg { + case RS256, PS256: + hash = crypto.SHA256 + case RS384, PS384: + hash = crypto.SHA384 + case RS512, PS512: + hash = crypto.SHA512 + default: + return Signature{}, ErrUnsupportedAlgorithm + } + + hasher := hash.New() + + // According to documentation, Write() on hash never fails + _, _ = hasher.Write(payload) + hashed := hasher.Sum(nil) + + var out []byte + var err error + + switch alg { + case RS256, RS384, RS512: + // TODO(https://github.com/go-jose/go-jose/issues/40): As of go1.20, the + // random parameter is legacy and ignored, and it can be nil. + // https://cs.opensource.google/go/go/+/refs/tags/go1.20:src/crypto/rsa/pkcs1v15.go;l=263;bpv=0;bpt=1 + out, err = rsa.SignPKCS1v15(RandReader, ctx.privateKey, hash, hashed) + case PS256, PS384, PS512: + out, err = rsa.SignPSS(RandReader, ctx.privateKey, hash, hashed, &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthEqualsHash, + }) + } + + if err != nil { + return Signature{}, err + } + + return Signature{ + Signature: out, + protected: &rawHeader{}, + }, nil +} + +// Verify the given payload +func (ctx rsaEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error { + var hash crypto.Hash + + switch alg { + case RS256, PS256: + hash = crypto.SHA256 + case RS384, PS384: + hash = crypto.SHA384 + case RS512, PS512: + hash = crypto.SHA512 + default: + return ErrUnsupportedAlgorithm + } + + hasher := hash.New() + + // According to documentation, Write() on hash never fails + _, _ = hasher.Write(payload) + hashed := hasher.Sum(nil) + + switch alg { + case RS256, RS384, RS512: + return rsa.VerifyPKCS1v15(ctx.publicKey, hash, hashed, signature) + case PS256, PS384, PS512: + return rsa.VerifyPSS(ctx.publicKey, hash, hashed, signature, nil) + } + + return ErrUnsupportedAlgorithm +} + +// Encrypt the given payload and update the object. +func (ctx ecEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) { + switch alg { + case ECDH_ES: + // ECDH-ES mode doesn't wrap a key, the shared secret is used directly as the key. + return recipientInfo{ + header: &rawHeader{}, + }, nil + case ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW: + default: + return recipientInfo{}, ErrUnsupportedAlgorithm + } + + generator := ecKeyGenerator{ + algID: string(alg), + publicKey: ctx.publicKey, + } + + switch alg { + case ECDH_ES_A128KW: + generator.size = 16 + case ECDH_ES_A192KW: + generator.size = 24 + case ECDH_ES_A256KW: + generator.size = 32 + } + + kek, header, err := generator.genKey() + if err != nil { + return recipientInfo{}, err + } + + block, err := aes.NewCipher(kek) + if err != nil { + return recipientInfo{}, err + } + + jek, err := josecipher.KeyWrap(block, cek) + if err != nil { + return recipientInfo{}, err + } + + return recipientInfo{ + encryptedKey: jek, + header: &header, + }, nil +} + +// Get key size for EC key generator +func (ctx ecKeyGenerator) keySize() int { + return ctx.size +} + +// Get a content encryption key for ECDH-ES +func (ctx ecKeyGenerator) genKey() ([]byte, rawHeader, error) { + priv, err := ecdsa.GenerateKey(ctx.publicKey.Curve, RandReader) + if err != nil { + return nil, rawHeader{}, err + } + + out := josecipher.DeriveECDHES(ctx.algID, []byte{}, []byte{}, priv, ctx.publicKey, ctx.size) + + b, err := json.Marshal(&JSONWebKey{ + Key: &priv.PublicKey, + }) + if err != nil { + return nil, nil, err + } + + headers := rawHeader{ + headerEPK: makeRawMessage(b), + } + + return out, headers, nil +} + +// Decrypt the given payload and return the content encryption key. +func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) { + if recipient == nil { + return nil, errors.New("go-jose/go-jose: missing recipient") + } + epk, err := headers.getEPK() + if err != nil { + return nil, errors.New("go-jose/go-jose: invalid epk header") + } + if epk == nil { + return nil, errors.New("go-jose/go-jose: missing epk header") + } + + publicKey, ok := epk.Key.(*ecdsa.PublicKey) + if publicKey == nil || !ok { + return nil, errors.New("go-jose/go-jose: invalid epk header") + } + + if !ctx.privateKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) { + return nil, errors.New("go-jose/go-jose: invalid public key in epk header") + } + + apuData, err := headers.getAPU() + if err != nil { + return nil, errors.New("go-jose/go-jose: invalid apu header") + } + apvData, err := headers.getAPV() + if err != nil { + return nil, errors.New("go-jose/go-jose: invalid apv header") + } + + deriveKey := func(algID string, size int) []byte { + return josecipher.DeriveECDHES(algID, apuData.bytes(), apvData.bytes(), ctx.privateKey, publicKey, size) + } + + var keySize int + + algorithm := headers.getAlgorithm() + switch algorithm { + case ECDH_ES: + // ECDH-ES uses direct key agreement, no key unwrapping necessary. + return deriveKey(string(headers.getEncryption()), generator.keySize()), nil + case ECDH_ES_A128KW: + keySize = 16 + case ECDH_ES_A192KW: + keySize = 24 + case ECDH_ES_A256KW: + keySize = 32 + default: + return nil, ErrUnsupportedAlgorithm + } + + encryptedKey := recipient.encryptedKey + if len(encryptedKey) == 0 { + return nil, errors.New("go-jose/go-jose: missing JWE Encrypted Key") + } + + key := deriveKey(string(algorithm), keySize) + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + return josecipher.KeyUnwrap(block, encryptedKey) +} + +func (ctx edDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) { + if alg != EdDSA { + return Signature{}, ErrUnsupportedAlgorithm + } + + sig, err := ctx.privateKey.Sign(RandReader, payload, crypto.Hash(0)) + if err != nil { + return Signature{}, err + } + + return Signature{ + Signature: sig, + protected: &rawHeader{}, + }, nil +} + +func (ctx edEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error { + if alg != EdDSA { + return ErrUnsupportedAlgorithm + } + ok := ed25519.Verify(ctx.publicKey, payload, signature) + if !ok { + return errors.New("go-jose/go-jose: ed25519 signature failed to verify") + } + return nil +} + +// Sign the given payload +func (ctx ecDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) { + var expectedBitSize int + var hash crypto.Hash + + switch alg { + case ES256: + expectedBitSize = 256 + hash = crypto.SHA256 + case ES384: + expectedBitSize = 384 + hash = crypto.SHA384 + case ES512: + expectedBitSize = 521 + hash = crypto.SHA512 + } + + curveBits := ctx.privateKey.Curve.Params().BitSize + if expectedBitSize != curveBits { + return Signature{}, fmt.Errorf("go-jose/go-jose: expected %d bit key, got %d bits instead", expectedBitSize, curveBits) + } + + hasher := hash.New() + + // According to documentation, Write() on hash never fails + _, _ = hasher.Write(payload) + hashed := hasher.Sum(nil) + + r, s, err := ecdsa.Sign(RandReader, ctx.privateKey, hashed) + if err != nil { + return Signature{}, err + } + + keyBytes := curveBits / 8 + if curveBits%8 > 0 { + keyBytes++ + } + + // We serialize the outputs (r and s) into big-endian byte arrays and pad + // them with zeros on the left to make sure the sizes work out. Both arrays + // must be keyBytes long, and the output must be 2*keyBytes long. + rBytes := r.Bytes() + rBytesPadded := make([]byte, keyBytes) + copy(rBytesPadded[keyBytes-len(rBytes):], rBytes) + + sBytes := s.Bytes() + sBytesPadded := make([]byte, keyBytes) + copy(sBytesPadded[keyBytes-len(sBytes):], sBytes) + + out := append(rBytesPadded, sBytesPadded...) + + return Signature{ + Signature: out, + protected: &rawHeader{}, + }, nil +} + +// Verify the given payload +func (ctx ecEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error { + var keySize int + var hash crypto.Hash + + switch alg { + case ES256: + keySize = 32 + hash = crypto.SHA256 + case ES384: + keySize = 48 + hash = crypto.SHA384 + case ES512: + keySize = 66 + hash = crypto.SHA512 + default: + return ErrUnsupportedAlgorithm + } + + if len(signature) != 2*keySize { + return fmt.Errorf("go-jose/go-jose: invalid signature size, have %d bytes, wanted %d", len(signature), 2*keySize) + } + + hasher := hash.New() + + // According to documentation, Write() on hash never fails + _, _ = hasher.Write(payload) + hashed := hasher.Sum(nil) + + r := big.NewInt(0).SetBytes(signature[:keySize]) + s := big.NewInt(0).SetBytes(signature[keySize:]) + + match := ecdsa.Verify(ctx.publicKey, hashed, r, s) + if !match { + return errors.New("go-jose/go-jose: ecdsa signature failed to verify") + } + + return nil +} diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/cbc_hmac.go b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/cbc_hmac.go new file mode 100644 index 000000000..af029cec0 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/cbc_hmac.go @@ -0,0 +1,196 @@ +/*- + * Copyright 2014 Square Inc. + * + * 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 josecipher + +import ( + "bytes" + "crypto/cipher" + "crypto/hmac" + "crypto/sha256" + "crypto/sha512" + "crypto/subtle" + "encoding/binary" + "errors" + "hash" +) + +const ( + nonceBytes = 16 +) + +// NewCBCHMAC instantiates a new AEAD based on CBC+HMAC. +func NewCBCHMAC(key []byte, newBlockCipher func([]byte) (cipher.Block, error)) (cipher.AEAD, error) { + keySize := len(key) / 2 + integrityKey := key[:keySize] + encryptionKey := key[keySize:] + + blockCipher, err := newBlockCipher(encryptionKey) + if err != nil { + return nil, err + } + + var hash func() hash.Hash + switch keySize { + case 16: + hash = sha256.New + case 24: + hash = sha512.New384 + case 32: + hash = sha512.New + } + + return &cbcAEAD{ + hash: hash, + blockCipher: blockCipher, + authtagBytes: keySize, + integrityKey: integrityKey, + }, nil +} + +// An AEAD based on CBC+HMAC +type cbcAEAD struct { + hash func() hash.Hash + authtagBytes int + integrityKey []byte + blockCipher cipher.Block +} + +func (ctx *cbcAEAD) NonceSize() int { + return nonceBytes +} + +func (ctx *cbcAEAD) Overhead() int { + // Maximum overhead is block size (for padding) plus auth tag length, where + // the length of the auth tag is equivalent to the key size. + return ctx.blockCipher.BlockSize() + ctx.authtagBytes +} + +// Seal encrypts and authenticates the plaintext. +func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte { + // Output buffer -- must take care not to mangle plaintext input. + ciphertext := make([]byte, uint64(len(plaintext))+uint64(ctx.Overhead()))[:len(plaintext)] + copy(ciphertext, plaintext) + ciphertext = padBuffer(ciphertext, ctx.blockCipher.BlockSize()) + + cbc := cipher.NewCBCEncrypter(ctx.blockCipher, nonce) + + cbc.CryptBlocks(ciphertext, ciphertext) + authtag := ctx.computeAuthTag(data, nonce, ciphertext) + + ret, out := resize(dst, uint64(len(dst))+uint64(len(ciphertext))+uint64(len(authtag))) + copy(out, ciphertext) + copy(out[len(ciphertext):], authtag) + + return ret +} + +// Open decrypts and authenticates the ciphertext. +func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { + if len(ciphertext) < ctx.authtagBytes { + return nil, errors.New("go-jose/go-jose: invalid ciphertext (too short)") + } + + offset := len(ciphertext) - ctx.authtagBytes + expectedTag := ctx.computeAuthTag(data, nonce, ciphertext[:offset]) + match := subtle.ConstantTimeCompare(expectedTag, ciphertext[offset:]) + if match != 1 { + return nil, errors.New("go-jose/go-jose: invalid ciphertext (auth tag mismatch)") + } + + cbc := cipher.NewCBCDecrypter(ctx.blockCipher, nonce) + + // Make copy of ciphertext buffer, don't want to modify in place + buffer := append([]byte{}, ciphertext[:offset]...) + + if len(buffer)%ctx.blockCipher.BlockSize() > 0 { + return nil, errors.New("go-jose/go-jose: invalid ciphertext (invalid length)") + } + + cbc.CryptBlocks(buffer, buffer) + + // Remove padding + plaintext, err := unpadBuffer(buffer, ctx.blockCipher.BlockSize()) + if err != nil { + return nil, err + } + + ret, out := resize(dst, uint64(len(dst))+uint64(len(plaintext))) + copy(out, plaintext) + + return ret, nil +} + +// Compute an authentication tag +func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte { + buffer := make([]byte, uint64(len(aad))+uint64(len(nonce))+uint64(len(ciphertext))+8) + n := 0 + n += copy(buffer, aad) + n += copy(buffer[n:], nonce) + n += copy(buffer[n:], ciphertext) + binary.BigEndian.PutUint64(buffer[n:], uint64(len(aad))*8) + + // According to documentation, Write() on hash.Hash never fails. + hmac := hmac.New(ctx.hash, ctx.integrityKey) + _, _ = hmac.Write(buffer) + + return hmac.Sum(nil)[:ctx.authtagBytes] +} + +// resize ensures that the given slice has a capacity of at least n bytes. +// If the capacity of the slice is less than n, a new slice is allocated +// and the existing data will be copied. +func resize(in []byte, n uint64) (head, tail []byte) { + if uint64(cap(in)) >= n { + head = in[:n] + } else { + head = make([]byte, n) + copy(head, in) + } + + tail = head[len(in):] + return +} + +// Apply padding +func padBuffer(buffer []byte, blockSize int) []byte { + missing := blockSize - (len(buffer) % blockSize) + ret, out := resize(buffer, uint64(len(buffer))+uint64(missing)) + padding := bytes.Repeat([]byte{byte(missing)}, missing) + copy(out, padding) + return ret +} + +// Remove padding +func unpadBuffer(buffer []byte, blockSize int) ([]byte, error) { + if len(buffer)%blockSize != 0 { + return nil, errors.New("go-jose/go-jose: invalid padding") + } + + last := buffer[len(buffer)-1] + count := int(last) + + if count == 0 || count > blockSize || count > len(buffer) { + return nil, errors.New("go-jose/go-jose: invalid padding") + } + + padding := bytes.Repeat([]byte{last}, count) + if !bytes.HasSuffix(buffer, padding) { + return nil, errors.New("go-jose/go-jose: invalid padding") + } + + return buffer[:len(buffer)-count], nil +} diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/concat_kdf.go b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/concat_kdf.go new file mode 100644 index 000000000..f62c3bdba --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/concat_kdf.go @@ -0,0 +1,75 @@ +/*- + * Copyright 2014 Square Inc. + * + * 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 josecipher + +import ( + "crypto" + "encoding/binary" + "hash" + "io" +) + +type concatKDF struct { + z, info []byte + i uint32 + cache []byte + hasher hash.Hash +} + +// NewConcatKDF builds a KDF reader based on the given inputs. +func NewConcatKDF(hash crypto.Hash, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo []byte) io.Reader { + buffer := make([]byte, uint64(len(algID))+uint64(len(ptyUInfo))+uint64(len(ptyVInfo))+uint64(len(supPubInfo))+uint64(len(supPrivInfo))) + n := 0 + n += copy(buffer, algID) + n += copy(buffer[n:], ptyUInfo) + n += copy(buffer[n:], ptyVInfo) + n += copy(buffer[n:], supPubInfo) + copy(buffer[n:], supPrivInfo) + + hasher := hash.New() + + return &concatKDF{ + z: z, + info: buffer, + hasher: hasher, + cache: []byte{}, + i: 1, + } +} + +func (ctx *concatKDF) Read(out []byte) (int, error) { + copied := copy(out, ctx.cache) + ctx.cache = ctx.cache[copied:] + + for copied < len(out) { + ctx.hasher.Reset() + + // Write on a hash.Hash never fails + _ = binary.Write(ctx.hasher, binary.BigEndian, ctx.i) + _, _ = ctx.hasher.Write(ctx.z) + _, _ = ctx.hasher.Write(ctx.info) + + hash := ctx.hasher.Sum(nil) + chunkCopied := copy(out[copied:], hash) + copied += chunkCopied + ctx.cache = hash[chunkCopied:] + + ctx.i++ + } + + return copied, nil +} diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/ecdh_es.go b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/ecdh_es.go new file mode 100644 index 000000000..093c64674 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/ecdh_es.go @@ -0,0 +1,86 @@ +/*- + * Copyright 2014 Square Inc. + * + * 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 josecipher + +import ( + "bytes" + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "encoding/binary" +) + +// DeriveECDHES derives a shared encryption key using ECDH/ConcatKDF as described in JWE/JWA. +// It is an error to call this function with a private/public key that are not on the same +// curve. Callers must ensure that the keys are valid before calling this function. Output +// size may be at most 1<<16 bytes (64 KiB). +func DeriveECDHES(alg string, apuData, apvData []byte, priv *ecdsa.PrivateKey, pub *ecdsa.PublicKey, size int) []byte { + if size > 1<<16 { + panic("ECDH-ES output size too large, must be less than or equal to 1<<16") + } + + // algId, partyUInfo, partyVInfo inputs must be prefixed with the length + algID := lengthPrefixed([]byte(alg)) + ptyUInfo := lengthPrefixed(apuData) + ptyVInfo := lengthPrefixed(apvData) + + // suppPubInfo is the encoded length of the output size in bits + supPubInfo := make([]byte, 4) + binary.BigEndian.PutUint32(supPubInfo, uint32(size)*8) + + if !priv.PublicKey.Curve.IsOnCurve(pub.X, pub.Y) { + panic("public key not on same curve as private key") + } + + z, _ := priv.Curve.ScalarMult(pub.X, pub.Y, priv.D.Bytes()) + zBytes := z.Bytes() + + // Note that calling z.Bytes() on a big.Int may strip leading zero bytes from + // the returned byte array. This can lead to a problem where zBytes will be + // shorter than expected which breaks the key derivation. Therefore we must pad + // to the full length of the expected coordinate here before calling the KDF. + octSize := dSize(priv.Curve) + if len(zBytes) != octSize { + zBytes = append(bytes.Repeat([]byte{0}, octSize-len(zBytes)), zBytes...) + } + + reader := NewConcatKDF(crypto.SHA256, zBytes, algID, ptyUInfo, ptyVInfo, supPubInfo, []byte{}) + key := make([]byte, size) + + // Read on the KDF will never fail + _, _ = reader.Read(key) + + return key +} + +// dSize returns the size in octets for a coordinate on a elliptic curve. +func dSize(curve elliptic.Curve) int { + order := curve.Params().P + bitLen := order.BitLen() + size := bitLen / 8 + if bitLen%8 != 0 { + size++ + } + return size +} + +func lengthPrefixed(data []byte) []byte { + out := make([]byte, len(data)+4) + binary.BigEndian.PutUint32(out, uint32(len(data))) + copy(out[4:], data) + return out +} diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/key_wrap.go b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/key_wrap.go new file mode 100644 index 000000000..a2f86e3db --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/cipher/key_wrap.go @@ -0,0 +1,117 @@ +/*- + * Copyright 2014 Square Inc. + * + * 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 josecipher + +import ( + "crypto/cipher" + "crypto/subtle" + "encoding/binary" + "errors" +) + +var defaultIV = []byte{0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6} + +// KeyWrap implements NIST key wrapping; it wraps a content encryption key (cek) with the given block cipher. +func KeyWrap(block cipher.Block, cek []byte) ([]byte, error) { + if len(cek)%8 != 0 { + return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks") + } + + n := len(cek) / 8 + r := make([][]byte, n) + + for i := range r { + r[i] = make([]byte, 8) + copy(r[i], cek[i*8:]) + } + + buffer := make([]byte, 16) + tBytes := make([]byte, 8) + copy(buffer, defaultIV) + + for t := 0; t < 6*n; t++ { + copy(buffer[8:], r[t%n]) + + block.Encrypt(buffer, buffer) + + binary.BigEndian.PutUint64(tBytes, uint64(t+1)) + + for i := 0; i < 8; i++ { + buffer[i] ^= tBytes[i] + } + copy(r[t%n], buffer[8:]) + } + + out := make([]byte, (n+1)*8) + copy(out, buffer[:8]) + for i := range r { + copy(out[(i+1)*8:], r[i]) + } + + return out, nil +} + +// KeyUnwrap implements NIST key unwrapping; it unwraps a content encryption key (cek) with the given block cipher. +// +// https://datatracker.ietf.org/doc/html/rfc7518#section-4.4 +// https://datatracker.ietf.org/doc/html/rfc7518#section-4.6 +// https://datatracker.ietf.org/doc/html/rfc7518#section-4.8 +func KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) { + n := (len(ciphertext) / 8) - 1 + if n <= 0 { + return nil, errors.New("go-jose/go-jose: JWE Encrypted Key too short") + } + + if len(ciphertext)%8 != 0 { + return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks") + } + + r := make([][]byte, n) + + for i := range r { + r[i] = make([]byte, 8) + copy(r[i], ciphertext[(i+1)*8:]) + } + + buffer := make([]byte, 16) + tBytes := make([]byte, 8) + copy(buffer[:8], ciphertext[:8]) + + for t := 6*n - 1; t >= 0; t-- { + binary.BigEndian.PutUint64(tBytes, uint64(t+1)) + + for i := 0; i < 8; i++ { + buffer[i] ^= tBytes[i] + } + copy(buffer[8:], r[t%n]) + + block.Decrypt(buffer, buffer) + + copy(r[t%n], buffer[8:]) + } + + if subtle.ConstantTimeCompare(buffer[:8], defaultIV) == 0 { + return nil, errors.New("go-jose/go-jose: failed to unwrap key") + } + + out := make([]byte, n*8) + for i := range r { + copy(out[i*8:], r[i]) + } + + return out, nil +} diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/crypter.go b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/crypter.go new file mode 100644 index 000000000..31290fc87 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/crypter.go @@ -0,0 +1,595 @@ +/*- + * Copyright 2014 Square Inc. + * + * 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 jose + +import ( + "crypto/ecdsa" + "crypto/rsa" + "errors" + "fmt" + + "github.com/go-jose/go-jose/v4/json" +) + +// Encrypter represents an encrypter which produces an encrypted JWE object. +type Encrypter interface { + Encrypt(plaintext []byte) (*JSONWebEncryption, error) + EncryptWithAuthData(plaintext []byte, aad []byte) (*JSONWebEncryption, error) + Options() EncrypterOptions +} + +// A generic content cipher +type contentCipher interface { + keySize() int + encrypt(cek []byte, aad, plaintext []byte) (*aeadParts, error) + decrypt(cek []byte, aad []byte, parts *aeadParts) ([]byte, error) +} + +// A key generator (for generating/getting a CEK) +type keyGenerator interface { + keySize() int + genKey() ([]byte, rawHeader, error) +} + +// A generic key encrypter +type keyEncrypter interface { + encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) // Encrypt a key +} + +// A generic key decrypter +type keyDecrypter interface { + decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) // Decrypt a key +} + +// A generic encrypter based on the given key encrypter and content cipher. +type genericEncrypter struct { + contentAlg ContentEncryption + compressionAlg CompressionAlgorithm + cipher contentCipher + recipients []recipientKeyInfo + keyGenerator keyGenerator + extraHeaders map[HeaderKey]interface{} +} + +type recipientKeyInfo struct { + keyID string + keyAlg KeyAlgorithm + keyEncrypter keyEncrypter +} + +// EncrypterOptions represents options that can be set on new encrypters. +type EncrypterOptions struct { + Compression CompressionAlgorithm + + // Optional map of name/value pairs to be inserted into the protected + // header of a JWS object. Some specifications which make use of + // JWS require additional values here. + // + // Values will be serialized by [json.Marshal] and must be valid inputs to + // that function. + // + // [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal + ExtraHeaders map[HeaderKey]interface{} +} + +// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it +// if necessary, and returns the updated EncrypterOptions. +// +// The v parameter will be serialized by [json.Marshal] and must be a valid +// input to that function. +// +// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal +func (eo *EncrypterOptions) WithHeader(k HeaderKey, v interface{}) *EncrypterOptions { + if eo.ExtraHeaders == nil { + eo.ExtraHeaders = map[HeaderKey]interface{}{} + } + eo.ExtraHeaders[k] = v + return eo +} + +// WithContentType adds a content type ("cty") header and returns the updated +// EncrypterOptions. +func (eo *EncrypterOptions) WithContentType(contentType ContentType) *EncrypterOptions { + return eo.WithHeader(HeaderContentType, contentType) +} + +// WithType adds a type ("typ") header and returns the updated EncrypterOptions. +func (eo *EncrypterOptions) WithType(typ ContentType) *EncrypterOptions { + return eo.WithHeader(HeaderType, typ) +} + +// Recipient represents an algorithm/key to encrypt messages to. +// +// PBES2Count and PBES2Salt correspond with the "p2c" and "p2s" headers used +// on the password-based encryption algorithms PBES2-HS256+A128KW, +// PBES2-HS384+A192KW, and PBES2-HS512+A256KW. If they are not provided a safe +// default of 100000 will be used for the count and a 128-bit random salt will +// be generated. +type Recipient struct { + Algorithm KeyAlgorithm + // Key must have one of these types: + // - ed25519.PublicKey + // - *ecdsa.PublicKey + // - *rsa.PublicKey + // - *JSONWebKey + // - JSONWebKey + // - []byte (a symmetric key) + // - Any type that satisfies the OpaqueKeyEncrypter interface + // + // The type of Key must match the value of Algorithm. + Key interface{} + KeyID string + PBES2Count int + PBES2Salt []byte +} + +// NewEncrypter creates an appropriate encrypter based on the key type +func NewEncrypter(enc ContentEncryption, rcpt Recipient, opts *EncrypterOptions) (Encrypter, error) { + encrypter := &genericEncrypter{ + contentAlg: enc, + recipients: []recipientKeyInfo{}, + cipher: getContentCipher(enc), + } + if opts != nil { + encrypter.compressionAlg = opts.Compression + encrypter.extraHeaders = opts.ExtraHeaders + } + + if encrypter.cipher == nil { + return nil, ErrUnsupportedAlgorithm + } + + var keyID string + var rawKey interface{} + switch encryptionKey := rcpt.Key.(type) { + case JSONWebKey: + keyID, rawKey = encryptionKey.KeyID, encryptionKey.Key + case *JSONWebKey: + keyID, rawKey = encryptionKey.KeyID, encryptionKey.Key + case OpaqueKeyEncrypter: + keyID, rawKey = encryptionKey.KeyID(), encryptionKey + default: + rawKey = encryptionKey + } + + switch rcpt.Algorithm { + case DIRECT: + // Direct encryption mode must be treated differently + keyBytes, ok := rawKey.([]byte) + if !ok { + return nil, ErrUnsupportedKeyType + } + if encrypter.cipher.keySize() != len(keyBytes) { + return nil, ErrInvalidKeySize + } + encrypter.keyGenerator = staticKeyGenerator{ + key: keyBytes, + } + recipientInfo, _ := newSymmetricRecipient(rcpt.Algorithm, keyBytes) + recipientInfo.keyID = keyID + if rcpt.KeyID != "" { + recipientInfo.keyID = rcpt.KeyID + } + encrypter.recipients = []recipientKeyInfo{recipientInfo} + return encrypter, nil + case ECDH_ES: + // ECDH-ES (w/o key wrapping) is similar to DIRECT mode + keyDSA, ok := rawKey.(*ecdsa.PublicKey) + if !ok { + return nil, ErrUnsupportedKeyType + } + encrypter.keyGenerator = ecKeyGenerator{ + size: encrypter.cipher.keySize(), + algID: string(enc), + publicKey: keyDSA, + } + recipientInfo, _ := newECDHRecipient(rcpt.Algorithm, keyDSA) + recipientInfo.keyID = keyID + if rcpt.KeyID != "" { + recipientInfo.keyID = rcpt.KeyID + } + encrypter.recipients = []recipientKeyInfo{recipientInfo} + return encrypter, nil + default: + // Can just add a standard recipient + encrypter.keyGenerator = randomKeyGenerator{ + size: encrypter.cipher.keySize(), + } + err := encrypter.addRecipient(rcpt) + return encrypter, err + } +} + +// NewMultiEncrypter creates a multi-encrypter based on the given parameters +func NewMultiEncrypter(enc ContentEncryption, rcpts []Recipient, opts *EncrypterOptions) (Encrypter, error) { + cipher := getContentCipher(enc) + + if cipher == nil { + return nil, ErrUnsupportedAlgorithm + } + if len(rcpts) == 0 { + return nil, fmt.Errorf("go-jose/go-jose: recipients is nil or empty") + } + + encrypter := &genericEncrypter{ + contentAlg: enc, + recipients: []recipientKeyInfo{}, + cipher: cipher, + keyGenerator: randomKeyGenerator{ + size: cipher.keySize(), + }, + } + + if opts != nil { + encrypter.compressionAlg = opts.Compression + encrypter.extraHeaders = opts.ExtraHeaders + } + + for _, recipient := range rcpts { + err := encrypter.addRecipient(recipient) + if err != nil { + return nil, err + } + } + + return encrypter, nil +} + +func (ctx *genericEncrypter) addRecipient(recipient Recipient) (err error) { + var recipientInfo recipientKeyInfo + + switch recipient.Algorithm { + case DIRECT, ECDH_ES: + return fmt.Errorf("go-jose/go-jose: key algorithm '%s' not supported in multi-recipient mode", recipient.Algorithm) + } + + recipientInfo, err = makeJWERecipient(recipient.Algorithm, recipient.Key) + if recipient.KeyID != "" { + recipientInfo.keyID = recipient.KeyID + } + + switch recipient.Algorithm { + case PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW: + if sr, ok := recipientInfo.keyEncrypter.(*symmetricKeyCipher); ok { + sr.p2c = recipient.PBES2Count + sr.p2s = recipient.PBES2Salt + } + } + + if err == nil { + ctx.recipients = append(ctx.recipients, recipientInfo) + } + return err +} + +func makeJWERecipient(alg KeyAlgorithm, encryptionKey interface{}) (recipientKeyInfo, error) { + switch encryptionKey := encryptionKey.(type) { + case *rsa.PublicKey: + return newRSARecipient(alg, encryptionKey) + case *ecdsa.PublicKey: + return newECDHRecipient(alg, encryptionKey) + case []byte: + return newSymmetricRecipient(alg, encryptionKey) + case string: + return newSymmetricRecipient(alg, []byte(encryptionKey)) + case JSONWebKey: + recipient, err := makeJWERecipient(alg, encryptionKey.Key) + recipient.keyID = encryptionKey.KeyID + return recipient, err + case *JSONWebKey: + recipient, err := makeJWERecipient(alg, encryptionKey.Key) + recipient.keyID = encryptionKey.KeyID + return recipient, err + case OpaqueKeyEncrypter: + return newOpaqueKeyEncrypter(alg, encryptionKey) + } + return recipientKeyInfo{}, ErrUnsupportedKeyType +} + +// newDecrypter creates an appropriate decrypter based on the key type +func newDecrypter(decryptionKey interface{}) (keyDecrypter, error) { + switch decryptionKey := decryptionKey.(type) { + case *rsa.PrivateKey: + return &rsaDecrypterSigner{ + privateKey: decryptionKey, + }, nil + case *ecdsa.PrivateKey: + return &ecDecrypterSigner{ + privateKey: decryptionKey, + }, nil + case []byte: + return &symmetricKeyCipher{ + key: decryptionKey, + }, nil + case string: + return &symmetricKeyCipher{ + key: []byte(decryptionKey), + }, nil + case JSONWebKey: + return newDecrypter(decryptionKey.Key) + case *JSONWebKey: + return newDecrypter(decryptionKey.Key) + case OpaqueKeyDecrypter: + return &opaqueKeyDecrypter{decrypter: decryptionKey}, nil + default: + return nil, ErrUnsupportedKeyType + } +} + +// Implementation of encrypt method producing a JWE object. +func (ctx *genericEncrypter) Encrypt(plaintext []byte) (*JSONWebEncryption, error) { + return ctx.EncryptWithAuthData(plaintext, nil) +} + +// Implementation of encrypt method producing a JWE object. +func (ctx *genericEncrypter) EncryptWithAuthData(plaintext, aad []byte) (*JSONWebEncryption, error) { + obj := &JSONWebEncryption{} + obj.aad = aad + + obj.protected = &rawHeader{} + err := obj.protected.set(headerEncryption, ctx.contentAlg) + if err != nil { + return nil, err + } + + obj.recipients = make([]recipientInfo, len(ctx.recipients)) + + if len(ctx.recipients) == 0 { + return nil, fmt.Errorf("go-jose/go-jose: no recipients to encrypt to") + } + + cek, headers, err := ctx.keyGenerator.genKey() + if err != nil { + return nil, err + } + + obj.protected.merge(&headers) + + for i, info := range ctx.recipients { + recipient, err := info.keyEncrypter.encryptKey(cek, info.keyAlg) + if err != nil { + return nil, err + } + + err = recipient.header.set(headerAlgorithm, info.keyAlg) + if err != nil { + return nil, err + } + + if info.keyID != "" { + err = recipient.header.set(headerKeyID, info.keyID) + if err != nil { + return nil, err + } + } + obj.recipients[i] = recipient + } + + if len(ctx.recipients) == 1 { + // Move per-recipient headers into main protected header if there's + // only a single recipient. + obj.protected.merge(obj.recipients[0].header) + obj.recipients[0].header = nil + } + + if ctx.compressionAlg != NONE { + plaintext, err = compress(ctx.compressionAlg, plaintext) + if err != nil { + return nil, err + } + + err = obj.protected.set(headerCompression, ctx.compressionAlg) + if err != nil { + return nil, err + } + } + + for k, v := range ctx.extraHeaders { + b, err := json.Marshal(v) + if err != nil { + return nil, err + } + (*obj.protected)[k] = makeRawMessage(b) + } + + authData := obj.computeAuthData() + parts, err := ctx.cipher.encrypt(cek, authData, plaintext) + if err != nil { + return nil, err + } + + obj.iv = parts.iv + obj.ciphertext = parts.ciphertext + obj.tag = parts.tag + + return obj, nil +} + +func (ctx *genericEncrypter) Options() EncrypterOptions { + return EncrypterOptions{ + Compression: ctx.compressionAlg, + ExtraHeaders: ctx.extraHeaders, + } +} + +// Decrypt and validate the object and return the plaintext. This +// function does not support multi-recipient. If you desire multi-recipient +// decryption use DecryptMulti instead. +// +// The decryptionKey argument must contain a private or symmetric key +// and must have one of these types: +// - *ecdsa.PrivateKey +// - *rsa.PrivateKey +// - *JSONWebKey +// - JSONWebKey +// - *JSONWebKeySet +// - JSONWebKeySet +// - []byte (a symmetric key) +// - string (a symmetric key) +// - Any type that satisfies the OpaqueKeyDecrypter interface. +// +// Note that ed25519 is only available for signatures, not encryption, so is +// not an option here. +// +// Automatically decompresses plaintext, but returns an error if the decompressed +// data would be >250kB or >10x the size of the compressed data, whichever is larger. +func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) { + headers := obj.mergedHeaders(nil) + + if len(obj.recipients) > 1 { + return nil, errors.New("go-jose/go-jose: too many recipients in payload; expecting only one") + } + + err := headers.checkNoCritical() + if err != nil { + return nil, err + } + + key, err := tryJWKS(decryptionKey, obj.Header) + if err != nil { + return nil, err + } + decrypter, err := newDecrypter(key) + if err != nil { + return nil, err + } + + cipher := getContentCipher(headers.getEncryption()) + if cipher == nil { + return nil, fmt.Errorf("go-jose/go-jose: unsupported enc value '%s'", string(headers.getEncryption())) + } + + generator := randomKeyGenerator{ + size: cipher.keySize(), + } + + parts := &aeadParts{ + iv: obj.iv, + ciphertext: obj.ciphertext, + tag: obj.tag, + } + + authData := obj.computeAuthData() + + var plaintext []byte + recipient := obj.recipients[0] + recipientHeaders := obj.mergedHeaders(&recipient) + + cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator) + if err == nil { + // Found a valid CEK -- let's try to decrypt. + plaintext, err = cipher.decrypt(cek, authData, parts) + } + + if plaintext == nil { + return nil, ErrCryptoFailure + } + + // The "zip" header parameter may only be present in the protected header. + if comp := obj.protected.getCompression(); comp != "" { + plaintext, err = decompress(comp, plaintext) + if err != nil { + return nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err) + } + } + + return plaintext, nil +} + +// DecryptMulti decrypts and validates the object and returns the plaintexts, +// with support for multiple recipients. It returns the index of the recipient +// for which the decryption was successful, the merged headers for that recipient, +// and the plaintext. +// +// The decryptionKey argument must have one of the types allowed for the +// decryptionKey argument of Decrypt(). +// +// Automatically decompresses plaintext, but returns an error if the decompressed +// data would be >250kB or >3x the size of the compressed data, whichever is larger. +func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) { + globalHeaders := obj.mergedHeaders(nil) + + err := globalHeaders.checkNoCritical() + if err != nil { + return -1, Header{}, nil, err + } + + key, err := tryJWKS(decryptionKey, obj.Header) + if err != nil { + return -1, Header{}, nil, err + } + decrypter, err := newDecrypter(key) + if err != nil { + return -1, Header{}, nil, err + } + + encryption := globalHeaders.getEncryption() + cipher := getContentCipher(encryption) + if cipher == nil { + return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported enc value '%s'", string(encryption)) + } + + generator := randomKeyGenerator{ + size: cipher.keySize(), + } + + parts := &aeadParts{ + iv: obj.iv, + ciphertext: obj.ciphertext, + tag: obj.tag, + } + + authData := obj.computeAuthData() + + index := -1 + var plaintext []byte + var headers rawHeader + + for i, recipient := range obj.recipients { + recipientHeaders := obj.mergedHeaders(&recipient) + + cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator) + if err == nil { + // Found a valid CEK -- let's try to decrypt. + plaintext, err = cipher.decrypt(cek, authData, parts) + if err == nil { + index = i + headers = recipientHeaders + break + } + } + } + + if plaintext == nil { + return -1, Header{}, nil, ErrCryptoFailure + } + + // The "zip" header parameter may only be present in the protected header. + if comp := obj.protected.getCompression(); comp != "" { + plaintext, err = decompress(comp, plaintext) + if err != nil { + return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err) + } + } + + sanitized, err := headers.sanitized() + if err != nil { + return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to sanitize header: %v", err) + } + + return index, sanitized, plaintext, err +} diff --git a/plugins/traefik/vendor/google.golang.org/grpc/internal/grpcsync/oncefunc.go b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/doc.go similarity index 55% rename from plugins/traefik/vendor/google.golang.org/grpc/internal/grpcsync/oncefunc.go rename to plugins/traefik/vendor/github.com/go-jose/go-jose/v4/doc.go index 6635f7bca..0ad40ca08 100644 --- a/plugins/traefik/vendor/google.golang.org/grpc/internal/grpcsync/oncefunc.go +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/doc.go @@ -1,6 +1,5 @@ -/* - * - * Copyright 2022 gRPC authors. +/*- + * Copyright 2014 Square Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,20 +12,14 @@ * 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) - } -} +/* +Package jose aims to provide an implementation of the Javascript Object Signing +and Encryption set of standards. It implements encryption and signing based on +the JSON Web Encryption and JSON Web Signature standards, with optional JSON Web +Token support available in a sub-package. The library supports both the compact +and JWS/JWE JSON Serialization formats, and has optional support for multiple +recipients. +*/ +package jose diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/encoding.go b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/encoding.go new file mode 100644 index 000000000..4f6e0d4a5 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/encoding.go @@ -0,0 +1,228 @@ +/*- + * Copyright 2014 Square Inc. + * + * 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 jose + +import ( + "bytes" + "compress/flate" + "encoding/base64" + "encoding/binary" + "fmt" + "io" + "math/big" + "strings" + "unicode" + + "github.com/go-jose/go-jose/v4/json" +) + +// Helper function to serialize known-good objects. +// Precondition: value is not a nil pointer. +func mustSerializeJSON(value interface{}) []byte { + out, err := json.Marshal(value) + if err != nil { + panic(err) + } + // We never want to serialize the top-level value "null," since it's not a + // valid JOSE message. But if a caller passes in a nil pointer to this method, + // MarshalJSON will happily serialize it as the top-level value "null". If + // that value is then embedded in another operation, for instance by being + // base64-encoded and fed as input to a signing algorithm + // (https://github.com/go-jose/go-jose/issues/22), the result will be + // incorrect. Because this method is intended for known-good objects, and a nil + // pointer is not a known-good object, we are free to panic in this case. + // Note: It's not possible to directly check whether the data pointed at by an + // interface is a nil pointer, so we do this hacky workaround. + // https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I + if string(out) == "null" { + panic("Tried to serialize a nil pointer.") + } + return out +} + +// Strip all newlines and whitespace +func stripWhitespace(data string) string { + buf := strings.Builder{} + buf.Grow(len(data)) + for _, r := range data { + if !unicode.IsSpace(r) { + buf.WriteRune(r) + } + } + return buf.String() +} + +// Perform compression based on algorithm +func compress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) { + switch algorithm { + case DEFLATE: + return deflate(input) + default: + return nil, ErrUnsupportedAlgorithm + } +} + +// Perform decompression based on algorithm +func decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) { + switch algorithm { + case DEFLATE: + return inflate(input) + default: + return nil, ErrUnsupportedAlgorithm + } +} + +// deflate compresses the input. +func deflate(input []byte) ([]byte, error) { + output := new(bytes.Buffer) + + // Writing to byte buffer, err is always nil + writer, _ := flate.NewWriter(output, 1) + _, _ = io.Copy(writer, bytes.NewBuffer(input)) + + err := writer.Close() + return output.Bytes(), err +} + +// inflate decompresses the input. +// +// Errors if the decompressed data would be >250kB or >10x the size of the +// compressed data, whichever is larger. +func inflate(input []byte) ([]byte, error) { + output := new(bytes.Buffer) + reader := flate.NewReader(bytes.NewBuffer(input)) + + maxCompressedSize := max(250_000, 10*int64(len(input))) + + limit := maxCompressedSize + 1 + n, err := io.CopyN(output, reader, limit) + if err != nil && err != io.EOF { + return nil, err + } + if n == limit { + return nil, fmt.Errorf("uncompressed data would be too large (>%d bytes)", maxCompressedSize) + } + + err = reader.Close() + return output.Bytes(), err +} + +// byteBuffer represents a slice of bytes that can be serialized to url-safe base64. +type byteBuffer struct { + data []byte +} + +func newBuffer(data []byte) *byteBuffer { + if data == nil { + return nil + } + return &byteBuffer{ + data: data, + } +} + +func newFixedSizeBuffer(data []byte, length int) *byteBuffer { + if len(data) > length { + panic("go-jose/go-jose: invalid call to newFixedSizeBuffer (len(data) > length)") + } + pad := make([]byte, length-len(data)) + return newBuffer(append(pad, data...)) +} + +func newBufferFromInt(num uint64) *byteBuffer { + data := make([]byte, 8) + binary.BigEndian.PutUint64(data, num) + return newBuffer(bytes.TrimLeft(data, "\x00")) +} + +func (b *byteBuffer) MarshalJSON() ([]byte, error) { + return json.Marshal(b.base64()) +} + +func (b *byteBuffer) UnmarshalJSON(data []byte) error { + var encoded string + err := json.Unmarshal(data, &encoded) + if err != nil { + return err + } + + if encoded == "" { + return nil + } + + decoded, err := base64.RawURLEncoding.DecodeString(encoded) + if err != nil { + return err + } + + *b = *newBuffer(decoded) + + return nil +} + +func (b *byteBuffer) base64() string { + return base64.RawURLEncoding.EncodeToString(b.data) +} + +func (b *byteBuffer) bytes() []byte { + // Handling nil here allows us to transparently handle nil slices when serializing. + if b == nil { + return nil + } + return b.data +} + +func (b byteBuffer) bigInt() *big.Int { + return new(big.Int).SetBytes(b.data) +} + +func (b byteBuffer) toInt() int { + return int(b.bigInt().Int64()) +} + +func base64EncodeLen(sl []byte) int { + return base64.RawURLEncoding.EncodedLen(len(sl)) +} + +func base64JoinWithDots(inputs ...[]byte) string { + if len(inputs) == 0 { + return "" + } + + // Count of dots. + totalCount := len(inputs) - 1 + + for _, input := range inputs { + totalCount += base64EncodeLen(input) + } + + out := make([]byte, totalCount) + startEncode := 0 + for i, input := range inputs { + base64.RawURLEncoding.Encode(out[startEncode:], input) + + if i == len(inputs)-1 { + continue + } + + startEncode += base64EncodeLen(input) + out[startEncode] = '.' + startEncode++ + } + + return string(out) +} diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/LICENSE b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/LICENSE new file mode 100644 index 000000000..744875676 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/README.md b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/README.md new file mode 100644 index 000000000..86de5e558 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/README.md @@ -0,0 +1,13 @@ +# Safe JSON + +This repository contains a fork of the `encoding/json` package from Go 1.6. + +The following changes were made: + +* Object deserialization uses case-sensitive member name matching instead of + [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html). + This is to avoid differences in the interpretation of JOSE messages between + go-jose and libraries written in other languages. +* When deserializing a JSON object, we check for duplicate keys and reject the + input whenever we detect a duplicate. Rather than trying to work with malformed + data, we prefer to reject it right away. diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/decode.go b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/decode.go new file mode 100644 index 000000000..50634dd84 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/decode.go @@ -0,0 +1,1216 @@ +// Copyright 2010 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. + +// Represents JSON data structure using native Go types: booleans, floats, +// strings, arrays, and maps. + +package json + +import ( + "bytes" + "encoding" + "encoding/base64" + "errors" + "fmt" + "math" + "reflect" + "runtime" + "strconv" + "unicode" + "unicode/utf16" + "unicode/utf8" +) + +// Unmarshal parses the JSON-encoded data and stores the result +// in the value pointed to by v. +// +// Unmarshal uses the inverse of the encodings that +// Marshal uses, allocating maps, slices, and pointers as necessary, +// with the following additional rules: +// +// To unmarshal JSON into a pointer, Unmarshal first handles the case of +// the JSON being the JSON literal null. In that case, Unmarshal sets +// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into +// the value pointed at by the pointer. If the pointer is nil, Unmarshal +// allocates a new value for it to point to. +// +// To unmarshal JSON into a struct, Unmarshal matches incoming object +// keys to the keys used by Marshal (either the struct field name or its tag), +// preferring an exact match but also accepting a case-insensitive match. +// Unmarshal will only set exported fields of the struct. +// +// To unmarshal JSON into an interface value, +// Unmarshal stores one of these in the interface value: +// +// bool, for JSON booleans +// float64, for JSON numbers +// string, for JSON strings +// []interface{}, for JSON arrays +// map[string]interface{}, for JSON objects +// nil for JSON null +// +// To unmarshal a JSON array into a slice, Unmarshal resets the slice length +// to zero and then appends each element to the slice. +// As a special case, to unmarshal an empty JSON array into a slice, +// Unmarshal replaces the slice with a new empty slice. +// +// To unmarshal a JSON array into a Go array, Unmarshal decodes +// JSON array elements into corresponding Go array elements. +// If the Go array is smaller than the JSON array, +// the additional JSON array elements are discarded. +// If the JSON array is smaller than the Go array, +// the additional Go array elements are set to zero values. +// +// To unmarshal a JSON object into a string-keyed map, Unmarshal first +// establishes a map to use, If the map is nil, Unmarshal allocates a new map. +// Otherwise Unmarshal reuses the existing map, keeping existing entries. +// Unmarshal then stores key-value pairs from the JSON object into the map. +// +// If a JSON value is not appropriate for a given target type, +// or if a JSON number overflows the target type, Unmarshal +// skips that field and completes the unmarshaling as best it can. +// If no more serious errors are encountered, Unmarshal returns +// an UnmarshalTypeError describing the earliest such error. +// +// The JSON null value unmarshals into an interface, map, pointer, or slice +// by setting that Go value to nil. Because null is often used in JSON to mean +// “not present,” unmarshaling a JSON null into any other Go type has no effect +// on the value and produces no error. +// +// When unmarshaling quoted strings, invalid UTF-8 or +// invalid UTF-16 surrogate pairs are not treated as an error. +// Instead, they are replaced by the Unicode replacement +// character U+FFFD. +func Unmarshal(data []byte, v interface{}) error { + // Check for well-formedness. + // Avoids filling out half a data structure + // before discovering a JSON syntax error. + var d decodeState + err := checkValid(data, &d.scan) + if err != nil { + return err + } + + d.init(data) + return d.unmarshal(v) +} + +// Unmarshaler is the interface implemented by objects +// that can unmarshal a JSON description of themselves. +// The input can be assumed to be a valid encoding of +// a JSON value. UnmarshalJSON must copy the JSON data +// if it wishes to retain the data after returning. +type Unmarshaler interface { + UnmarshalJSON([]byte) error +} + +// An UnmarshalTypeError describes a JSON value that was +// not appropriate for a value of a specific Go type. +type UnmarshalTypeError struct { + Value string // description of JSON value - "bool", "array", "number -5" + Type reflect.Type // type of Go value it could not be assigned to + Offset int64 // error occurred after reading Offset bytes +} + +func (e *UnmarshalTypeError) Error() string { + return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String() +} + +// An UnmarshalFieldError describes a JSON object key that +// led to an unexported (and therefore unwritable) struct field. +// (No longer used; kept for compatibility.) +type UnmarshalFieldError struct { + Key string + Type reflect.Type + Field reflect.StructField +} + +func (e *UnmarshalFieldError) Error() string { + return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String() +} + +// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. +// (The argument to Unmarshal must be a non-nil pointer.) +type InvalidUnmarshalError struct { + Type reflect.Type +} + +func (e *InvalidUnmarshalError) Error() string { + if e.Type == nil { + return "json: Unmarshal(nil)" + } + + if e.Type.Kind() != reflect.Ptr { + return "json: Unmarshal(non-pointer " + e.Type.String() + ")" + } + return "json: Unmarshal(nil " + e.Type.String() + ")" +} + +func (d *decodeState) unmarshal(v interface{}) (err error) { + defer func() { + if r := recover(); r != nil { + if _, ok := r.(runtime.Error); ok { + panic(r) + } + err = r.(error) + } + }() + + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + return &InvalidUnmarshalError{reflect.TypeOf(v)} + } + + d.scan.reset() + // We decode rv not rv.Elem because the Unmarshaler interface + // test must be applied at the top level of the value. + d.value(rv) + return d.savedError +} + +// A Number represents a JSON number literal. +type Number string + +// String returns the literal text of the number. +func (n Number) String() string { return string(n) } + +// Float64 returns the number as a float64. +func (n Number) Float64() (float64, error) { + return strconv.ParseFloat(string(n), 64) +} + +// Int64 returns the number as an int64. +func (n Number) Int64() (int64, error) { + return strconv.ParseInt(string(n), 10, 64) +} + +// isValidNumber reports whether s is a valid JSON number literal. +func isValidNumber(s string) bool { + // This function implements the JSON numbers grammar. + // See https://tools.ietf.org/html/rfc7159#section-6 + // and http://json.org/number.gif + + if s == "" { + return false + } + + // Optional - + if s[0] == '-' { + s = s[1:] + if s == "" { + return false + } + } + + // Digits + switch { + default: + return false + + case s[0] == '0': + s = s[1:] + + case '1' <= s[0] && s[0] <= '9': + s = s[1:] + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // . followed by 1 or more digits. + if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' { + s = s[2:] + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // e or E followed by an optional - or + and + // 1 or more digits. + if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') { + s = s[1:] + if s[0] == '+' || s[0] == '-' { + s = s[1:] + if s == "" { + return false + } + } + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // Make sure we are at the end. + return s == "" +} + +type NumberUnmarshalType int + +const ( + // unmarshal a JSON number into an interface{} as a float64 + UnmarshalFloat NumberUnmarshalType = iota + // unmarshal a JSON number into an interface{} as a `json.Number` + UnmarshalJSONNumber + // unmarshal a JSON number into an interface{} as a int64 + // if value is an integer otherwise float64 + UnmarshalIntOrFloat +) + +// decodeState represents the state while decoding a JSON value. +type decodeState struct { + data []byte + off int // read offset in data + scan scanner + nextscan scanner // for calls to nextValue + savedError error + numberType NumberUnmarshalType +} + +// errPhase is used for errors that should not happen unless +// there is a bug in the JSON decoder or something is editing +// the data slice while the decoder executes. +var errPhase = errors.New("JSON decoder out of sync - data changing underfoot?") + +func (d *decodeState) init(data []byte) *decodeState { + d.data = data + d.off = 0 + d.savedError = nil + return d +} + +// error aborts the decoding by panicking with err. +func (d *decodeState) error(err error) { + panic(err) +} + +// saveError saves the first err it is called with, +// for reporting at the end of the unmarshal. +func (d *decodeState) saveError(err error) { + if d.savedError == nil { + d.savedError = err + } +} + +// next cuts off and returns the next full JSON value in d.data[d.off:]. +// The next value is known to be an object or array, not a literal. +func (d *decodeState) next() []byte { + c := d.data[d.off] + item, rest, err := nextValue(d.data[d.off:], &d.nextscan) + if err != nil { + d.error(err) + } + d.off = len(d.data) - len(rest) + + // Our scanner has seen the opening brace/bracket + // and thinks we're still in the middle of the object. + // invent a closing brace/bracket to get it out. + if c == '{' { + d.scan.step(&d.scan, '}') + } else { + d.scan.step(&d.scan, ']') + } + + return item +} + +// scanWhile processes bytes in d.data[d.off:] until it +// receives a scan code not equal to op. +// It updates d.off and returns the new scan code. +func (d *decodeState) scanWhile(op int) int { + var newOp int + for { + if d.off >= len(d.data) { + newOp = d.scan.eof() + d.off = len(d.data) + 1 // mark processed EOF with len+1 + } else { + c := d.data[d.off] + d.off++ + newOp = d.scan.step(&d.scan, c) + } + if newOp != op { + break + } + } + return newOp +} + +// value decodes a JSON value from d.data[d.off:] into the value. +// it updates d.off to point past the decoded value. +func (d *decodeState) value(v reflect.Value) { + if !v.IsValid() { + _, rest, err := nextValue(d.data[d.off:], &d.nextscan) + if err != nil { + d.error(err) + } + d.off = len(d.data) - len(rest) + + // d.scan thinks we're still at the beginning of the item. + // Feed in an empty string - the shortest, simplest value - + // so that it knows we got to the end of the value. + if d.scan.redo { + // rewind. + d.scan.redo = false + d.scan.step = stateBeginValue + } + d.scan.step(&d.scan, '"') + d.scan.step(&d.scan, '"') + + n := len(d.scan.parseState) + if n > 0 && d.scan.parseState[n-1] == parseObjectKey { + // d.scan thinks we just read an object key; finish the object + d.scan.step(&d.scan, ':') + d.scan.step(&d.scan, '"') + d.scan.step(&d.scan, '"') + d.scan.step(&d.scan, '}') + } + + return + } + + switch op := d.scanWhile(scanSkipSpace); op { + default: + d.error(errPhase) + + case scanBeginArray: + d.array(v) + + case scanBeginObject: + d.object(v) + + case scanBeginLiteral: + d.literal(v) + } +} + +type unquotedValue struct{} + +// valueQuoted is like value but decodes a +// quoted string literal or literal null into an interface value. +// If it finds anything other than a quoted string literal or null, +// valueQuoted returns unquotedValue{}. +func (d *decodeState) valueQuoted() interface{} { + switch op := d.scanWhile(scanSkipSpace); op { + default: + d.error(errPhase) + + case scanBeginArray: + d.array(reflect.Value{}) + + case scanBeginObject: + d.object(reflect.Value{}) + + case scanBeginLiteral: + switch v := d.literalInterface().(type) { + case nil, string: + return v + } + } + return unquotedValue{} +} + +// indirect walks down v allocating pointers as needed, +// until it gets to a non-pointer. +// if it encounters an Unmarshaler, indirect stops and returns that. +// if decodingNull is true, indirect stops at the last pointer so it can be set to nil. +func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { + // If v is a named type and is addressable, + // start with its address, so that if the type has pointer methods, + // we find them. + if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { + v = v.Addr() + } + for { + // Load value from interface, but only if the result will be + // usefully addressable. + if v.Kind() == reflect.Interface && !v.IsNil() { + e := v.Elem() + if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { + v = e + continue + } + } + + if v.Kind() != reflect.Ptr { + break + } + + if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() { + break + } + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + if v.Type().NumMethod() > 0 { + if u, ok := v.Interface().(Unmarshaler); ok { + return u, nil, reflect.Value{} + } + if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { + return nil, u, reflect.Value{} + } + } + v = v.Elem() + } + return nil, nil, v +} + +// array consumes an array from d.data[d.off-1:], decoding into the value v. +// the first byte of the array ('[') has been read already. +func (d *decodeState) array(v reflect.Value) { + // Check for unmarshaler. + u, ut, pv := d.indirect(v, false) + if u != nil { + d.off-- + err := u.UnmarshalJSON(d.next()) + if err != nil { + d.error(err) + } + return + } + if ut != nil { + d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)}) + d.off-- + d.next() + return + } + + v = pv + + // Check type of target. + switch v.Kind() { + case reflect.Interface: + if v.NumMethod() == 0 { + // Decoding into nil interface? Switch to non-reflect code. + v.Set(reflect.ValueOf(d.arrayInterface())) + return + } + // Otherwise it's invalid. + fallthrough + default: + d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)}) + d.off-- + d.next() + return + case reflect.Array: + case reflect.Slice: + break + } + + i := 0 + for { + // Look ahead for ] - can only happen on first iteration. + op := d.scanWhile(scanSkipSpace) + if op == scanEndArray { + break + } + + // Back up so d.value can have the byte we just read. + d.off-- + d.scan.undo(op) + + // Get element of array, growing if necessary. + if v.Kind() == reflect.Slice { + // Grow slice if necessary + if i >= v.Cap() { + newcap := v.Cap() + v.Cap()/2 + if newcap < 4 { + newcap = 4 + } + newv := reflect.MakeSlice(v.Type(), v.Len(), newcap) + reflect.Copy(newv, v) + v.Set(newv) + } + if i >= v.Len() { + v.SetLen(i + 1) + } + } + + if i < v.Len() { + // Decode into element. + d.value(v.Index(i)) + } else { + // Ran out of fixed array: skip. + d.value(reflect.Value{}) + } + i++ + + // Next token must be , or ]. + op = d.scanWhile(scanSkipSpace) + if op == scanEndArray { + break + } + if op != scanArrayValue { + d.error(errPhase) + } + } + + if i < v.Len() { + if v.Kind() == reflect.Array { + // Array. Zero the rest. + z := reflect.Zero(v.Type().Elem()) + for ; i < v.Len(); i++ { + v.Index(i).Set(z) + } + } else { + v.SetLen(i) + } + } + if i == 0 && v.Kind() == reflect.Slice { + v.Set(reflect.MakeSlice(v.Type(), 0, 0)) + } +} + +var nullLiteral = []byte("null") + +// object consumes an object from d.data[d.off-1:], decoding into the value v. +// the first byte ('{') of the object has been read already. +func (d *decodeState) object(v reflect.Value) { + // Check for unmarshaler. + u, ut, pv := d.indirect(v, false) + if u != nil { + d.off-- + err := u.UnmarshalJSON(d.next()) + if err != nil { + d.error(err) + } + return + } + if ut != nil { + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + v = pv + + // Decoding into nil interface? Switch to non-reflect code. + if v.Kind() == reflect.Interface && v.NumMethod() == 0 { + v.Set(reflect.ValueOf(d.objectInterface())) + return + } + + // Check type of target: struct or map[string]T + switch v.Kind() { + case reflect.Map: + // map must have string kind + t := v.Type() + if t.Key().Kind() != reflect.String { + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + if v.IsNil() { + v.Set(reflect.MakeMap(t)) + } + case reflect.Struct: + + default: + d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) + d.off-- + d.next() // skip over { } in input + return + } + + var mapElem reflect.Value + keys := map[string]bool{} + + for { + // Read opening " of string key or closing }. + op := d.scanWhile(scanSkipSpace) + if op == scanEndObject { + // closing } - can only happen on first iteration. + break + } + if op != scanBeginLiteral { + d.error(errPhase) + } + + // Read key. + start := d.off - 1 + op = d.scanWhile(scanContinue) + item := d.data[start : d.off-1] + key, ok := unquote(item) + if !ok { + d.error(errPhase) + } + + // Check for duplicate keys. + _, ok = keys[key] + if !ok { + keys[key] = true + } else { + d.error(fmt.Errorf("json: duplicate key '%s' in object", key)) + } + + // Figure out field corresponding to key. + var subv reflect.Value + destring := false // whether the value is wrapped in a string to be decoded first + + if v.Kind() == reflect.Map { + elemType := v.Type().Elem() + if !mapElem.IsValid() { + mapElem = reflect.New(elemType).Elem() + } else { + mapElem.Set(reflect.Zero(elemType)) + } + subv = mapElem + } else { + var f *field + fields := cachedTypeFields(v.Type()) + for i := range fields { + ff := &fields[i] + if bytes.Equal(ff.nameBytes, []byte(key)) { + f = ff + break + } + } + if f != nil { + subv = v + destring = f.quoted + for _, i := range f.index { + if subv.Kind() == reflect.Ptr { + if subv.IsNil() { + subv.Set(reflect.New(subv.Type().Elem())) + } + subv = subv.Elem() + } + subv = subv.Field(i) + } + } + } + + // Read : before value. + if op == scanSkipSpace { + op = d.scanWhile(scanSkipSpace) + } + if op != scanObjectKey { + d.error(errPhase) + } + + // Read value. + if destring { + switch qv := d.valueQuoted().(type) { + case nil: + d.literalStore(nullLiteral, subv, false) + case string: + d.literalStore([]byte(qv), subv, true) + default: + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type())) + } + } else { + d.value(subv) + } + + // Write value back to map; + // if using struct, subv points into struct already. + if v.Kind() == reflect.Map { + kv := reflect.ValueOf(key).Convert(v.Type().Key()) + v.SetMapIndex(kv, subv) + } + + // Next token must be , or }. + op = d.scanWhile(scanSkipSpace) + if op == scanEndObject { + break + } + if op != scanObjectValue { + d.error(errPhase) + } + } +} + +// literal consumes a literal from d.data[d.off-1:], decoding into the value v. +// The first byte of the literal has been read already +// (that's how the caller knows it's a literal). +func (d *decodeState) literal(v reflect.Value) { + // All bytes inside literal return scanContinue op code. + start := d.off - 1 + op := d.scanWhile(scanContinue) + + // Scan read one byte too far; back up. + d.off-- + d.scan.undo(op) + + d.literalStore(d.data[start:d.off], v, false) +} + +// convertNumber converts the number literal s to a float64, int64 or a Number +// depending on d.numberDecodeType. +func (d *decodeState) convertNumber(s string) (interface{}, error) { + switch d.numberType { + + case UnmarshalJSONNumber: + return Number(s), nil + case UnmarshalIntOrFloat: + v, err := strconv.ParseInt(s, 10, 64) + if err == nil { + return v, nil + } + + // tries to parse integer number in scientific notation + f, err := strconv.ParseFloat(s, 64) + if err != nil { + return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)} + } + + // if it has no decimal value use int64 + if fi, fd := math.Modf(f); fd == 0.0 { + return int64(fi), nil + } + return f, nil + default: + f, err := strconv.ParseFloat(s, 64) + if err != nil { + return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)} + } + return f, nil + } + +} + +var numberType = reflect.TypeOf(Number("")) + +// literalStore decodes a literal stored in item into v. +// +// fromQuoted indicates whether this literal came from unwrapping a +// string from the ",string" struct tag option. this is used only to +// produce more helpful error messages. +func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) { + // Check for unmarshaler. + if len(item) == 0 { + //Empty string given + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + return + } + wantptr := item[0] == 'n' // null + u, ut, pv := d.indirect(v, wantptr) + if u != nil { + err := u.UnmarshalJSON(item) + if err != nil { + d.error(err) + } + return + } + if ut != nil { + if item[0] != '"' { + if fromQuoted { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) + } + return + } + s, ok := unquoteBytes(item) + if !ok { + if fromQuoted { + d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.error(errPhase) + } + } + err := ut.UnmarshalText(s) + if err != nil { + d.error(err) + } + return + } + + v = pv + + switch c := item[0]; c { + case 'n': // null + switch v.Kind() { + case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: + v.Set(reflect.Zero(v.Type())) + // otherwise, ignore null for primitives/string + } + case 't', 'f': // true, false + value := c == 't' + switch v.Kind() { + default: + if fromQuoted { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)}) + } + case reflect.Bool: + v.SetBool(value) + case reflect.Interface: + if v.NumMethod() == 0 { + v.Set(reflect.ValueOf(value)) + } else { + d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)}) + } + } + + case '"': // string + s, ok := unquoteBytes(item) + if !ok { + if fromQuoted { + d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.error(errPhase) + } + } + switch v.Kind() { + default: + d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) + case reflect.Slice: + if v.Type().Elem().Kind() != reflect.Uint8 { + d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) + break + } + b := make([]byte, base64.StdEncoding.DecodedLen(len(s))) + n, err := base64.StdEncoding.Decode(b, s) + if err != nil { + d.saveError(err) + break + } + v.SetBytes(b[:n]) + case reflect.String: + v.SetString(string(s)) + case reflect.Interface: + if v.NumMethod() == 0 { + v.Set(reflect.ValueOf(string(s))) + } else { + d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) + } + } + + default: // number + if c != '-' && (c < '0' || c > '9') { + if fromQuoted { + d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.error(errPhase) + } + } + s := string(item) + switch v.Kind() { + default: + if v.Kind() == reflect.String && v.Type() == numberType { + v.SetString(s) + if !isValidNumber(s) { + d.error(fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item)) + } + break + } + if fromQuoted { + d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.error(&UnmarshalTypeError{"number", v.Type(), int64(d.off)}) + } + case reflect.Interface: + n, err := d.convertNumber(s) + if err != nil { + d.saveError(err) + break + } + if v.NumMethod() != 0 { + d.saveError(&UnmarshalTypeError{"number", v.Type(), int64(d.off)}) + break + } + v.Set(reflect.ValueOf(n)) + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + n, err := strconv.ParseInt(s, 10, 64) + if err != nil || v.OverflowInt(n) { + d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)}) + break + } + v.SetInt(n) + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + n, err := strconv.ParseUint(s, 10, 64) + if err != nil || v.OverflowUint(n) { + d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)}) + break + } + v.SetUint(n) + + case reflect.Float32, reflect.Float64: + n, err := strconv.ParseFloat(s, v.Type().Bits()) + if err != nil || v.OverflowFloat(n) { + d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)}) + break + } + v.SetFloat(n) + } + } +} + +// The xxxInterface routines build up a value to be stored +// in an empty interface. They are not strictly necessary, +// but they avoid the weight of reflection in this common case. + +// valueInterface is like value but returns interface{} +func (d *decodeState) valueInterface() interface{} { + switch d.scanWhile(scanSkipSpace) { + default: + d.error(errPhase) + panic("unreachable") + case scanBeginArray: + return d.arrayInterface() + case scanBeginObject: + return d.objectInterface() + case scanBeginLiteral: + return d.literalInterface() + } +} + +// arrayInterface is like array but returns []interface{}. +func (d *decodeState) arrayInterface() []interface{} { + var v = make([]interface{}, 0) + for { + // Look ahead for ] - can only happen on first iteration. + op := d.scanWhile(scanSkipSpace) + if op == scanEndArray { + break + } + + // Back up so d.value can have the byte we just read. + d.off-- + d.scan.undo(op) + + v = append(v, d.valueInterface()) + + // Next token must be , or ]. + op = d.scanWhile(scanSkipSpace) + if op == scanEndArray { + break + } + if op != scanArrayValue { + d.error(errPhase) + } + } + return v +} + +// objectInterface is like object but returns map[string]interface{}. +func (d *decodeState) objectInterface() map[string]interface{} { + m := make(map[string]interface{}) + keys := map[string]bool{} + + for { + // Read opening " of string key or closing }. + op := d.scanWhile(scanSkipSpace) + if op == scanEndObject { + // closing } - can only happen on first iteration. + break + } + if op != scanBeginLiteral { + d.error(errPhase) + } + + // Read string key. + start := d.off - 1 + op = d.scanWhile(scanContinue) + item := d.data[start : d.off-1] + key, ok := unquote(item) + if !ok { + d.error(errPhase) + } + + // Check for duplicate keys. + _, ok = keys[key] + if !ok { + keys[key] = true + } else { + d.error(fmt.Errorf("json: duplicate key '%s' in object", key)) + } + + // Read : before value. + if op == scanSkipSpace { + op = d.scanWhile(scanSkipSpace) + } + if op != scanObjectKey { + d.error(errPhase) + } + + // Read value. + m[key] = d.valueInterface() + + // Next token must be , or }. + op = d.scanWhile(scanSkipSpace) + if op == scanEndObject { + break + } + if op != scanObjectValue { + d.error(errPhase) + } + } + return m +} + +// literalInterface is like literal but returns an interface value. +func (d *decodeState) literalInterface() interface{} { + // All bytes inside literal return scanContinue op code. + start := d.off - 1 + op := d.scanWhile(scanContinue) + + // Scan read one byte too far; back up. + d.off-- + d.scan.undo(op) + item := d.data[start:d.off] + + switch c := item[0]; c { + case 'n': // null + return nil + + case 't', 'f': // true, false + return c == 't' + + case '"': // string + s, ok := unquote(item) + if !ok { + d.error(errPhase) + } + return s + + default: // number + if c != '-' && (c < '0' || c > '9') { + d.error(errPhase) + } + n, err := d.convertNumber(string(item)) + if err != nil { + d.saveError(err) + } + return n + } +} + +// getu4 decodes \uXXXX from the beginning of s, returning the hex value, +// or it returns -1. +func getu4(s []byte) rune { + if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { + return -1 + } + r, err := strconv.ParseUint(string(s[2:6]), 16, 64) + if err != nil { + return -1 + } + return rune(r) +} + +// unquote converts a quoted JSON string literal s into an actual string t. +// The rules are different than for Go, so cannot use strconv.Unquote. +func unquote(s []byte) (t string, ok bool) { + s, ok = unquoteBytes(s) + t = string(s) + return +} + +func unquoteBytes(s []byte) (t []byte, ok bool) { + if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' { + return + } + s = s[1 : len(s)-1] + + // Check for unusual characters. If there are none, + // then no unquoting is needed, so return a slice of the + // original bytes. + r := 0 + for r < len(s) { + c := s[r] + if c == '\\' || c == '"' || c < ' ' { + break + } + if c < utf8.RuneSelf { + r++ + continue + } + rr, size := utf8.DecodeRune(s[r:]) + if rr == utf8.RuneError && size == 1 { + break + } + r += size + } + if r == len(s) { + return s, true + } + + b := make([]byte, len(s)+2*utf8.UTFMax) + w := copy(b, s[0:r]) + for r < len(s) { + // Out of room? Can only happen if s is full of + // malformed UTF-8 and we're replacing each + // byte with RuneError. + if w >= len(b)-2*utf8.UTFMax { + nb := make([]byte, (len(b)+utf8.UTFMax)*2) + copy(nb, b[0:w]) + b = nb + } + switch c := s[r]; { + case c == '\\': + r++ + if r >= len(s) { + return + } + switch s[r] { + default: + return + case '"', '\\', '/', '\'': + b[w] = s[r] + r++ + w++ + case 'b': + b[w] = '\b' + r++ + w++ + case 'f': + b[w] = '\f' + r++ + w++ + case 'n': + b[w] = '\n' + r++ + w++ + case 'r': + b[w] = '\r' + r++ + w++ + case 't': + b[w] = '\t' + r++ + w++ + case 'u': + r-- + rr := getu4(s[r:]) + if rr < 0 { + return + } + r += 6 + if utf16.IsSurrogate(rr) { + rr1 := getu4(s[r:]) + if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { + // A valid pair; consume. + r += 6 + w += utf8.EncodeRune(b[w:], dec) + break + } + // Invalid surrogate; fall back to replacement rune. + rr = unicode.ReplacementChar + } + w += utf8.EncodeRune(b[w:], rr) + } + + // Quote, control characters are invalid. + case c == '"', c < ' ': + return + + // ASCII + case c < utf8.RuneSelf: + b[w] = c + r++ + w++ + + // Coerce to well-formed UTF-8. + default: + rr, size := utf8.DecodeRune(s[r:]) + r += size + w += utf8.EncodeRune(b[w:], rr) + } + } + return b[0:w], true +} diff --git a/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/encode.go b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/encode.go new file mode 100644 index 000000000..98de68ce1 --- /dev/null +++ b/plugins/traefik/vendor/github.com/go-jose/go-jose/v4/json/encode.go @@ -0,0 +1,1197 @@ +// Copyright 2010 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 json implements encoding and decoding of JSON objects as defined in +// RFC 4627. The mapping between JSON objects and Go values is described +// in the documentation for the Marshal and Unmarshal functions. +// +// See "JSON and Go" for an introduction to this package: +// https://golang.org/doc/articles/json_and_go.html +package json + +import ( + "bytes" + "encoding" + "encoding/base64" + "fmt" + "math" + "reflect" + "runtime" + "sort" + "strconv" + "strings" + "sync" + "unicode" + "unicode/utf8" +) + +// Marshal returns the JSON encoding of v. +// +// Marshal traverses the value v recursively. +// If an encountered value implements the Marshaler interface +// and is not a nil pointer, Marshal calls its MarshalJSON method +// to produce JSON. If no MarshalJSON method is present but the +// value implements encoding.TextMarshaler instead, Marshal calls +// its MarshalText method. +// The nil pointer exception is not strictly necessary +// but mimics a similar, necessary exception in the behavior of +// UnmarshalJSON. +// +// Otherwise, Marshal uses the following type-dependent default encodings: +// +// Boolean values encode as JSON booleans. +// +// Floating point, integer, and Number values encode as JSON numbers. +// +// String values encode as JSON strings coerced to valid UTF-8, +// replacing invalid bytes with the Unicode replacement rune. +// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" +// to keep some browsers from misinterpreting JSON output as HTML. +// Ampersand "&" is also escaped to "\u0026" for the same reason. +// +// Array and slice values encode as JSON arrays, except that +// []byte encodes as a base64-encoded string, and a nil slice +// encodes as the null JSON object. +// +// Struct values encode as JSON objects. Each exported struct field +// becomes a member of the object unless +// - the field's tag is "-", or +// - the field is empty and its tag specifies the "omitempty" option. +// +// The empty values are false, 0, any +// nil pointer or interface value, and any array, slice, map, or string of +// length zero. The object's default key string is the struct field name +// but can be specified in the struct field's tag value. The "json" key in +// the struct field's tag value is the key name, followed by an optional comma +// and options. Examples: +// +// // Field is ignored by this package. +// Field int `json:"-"` +// +// // Field appears in JSON as key "myName". +// Field int `json:"myName"` +// +// // Field appears in JSON as key "myName" and +// // the field is omitted from the object if its value is empty, +// // as defined above. +// Field int `json:"myName,omitempty"` +// +// // Field appears in JSON as key "Field" (the default), but +// // the field is skipped if empty. +// // Note the leading comma. +// Field int `json:",omitempty"` +// +// The "string" option signals that a field is stored as JSON inside a +// JSON-encoded string. It applies only to fields of string, floating point, +// integer, or boolean types. This extra level of encoding is sometimes used +// when communicating with JavaScript programs: +// +// Int64String int64 `json:",string"` +// +// The key name will be used if it's a non-empty string consisting of +// only Unicode letters, digits, dollar signs, percent signs, hyphens, +// underscores and slashes. +// +// Anonymous struct fields are usually marshaled as if their inner exported fields +// were fields in the outer struct, subject to the usual Go visibility rules amended +// as described in the next paragraph. +// An anonymous struct field with a name given in its JSON tag is treated as +// having that name, rather than being anonymous. +// An anonymous struct field of interface type is treated the same as having +// that type as its name, rather than being anonymous. +// +// The Go visibility rules for struct fields are amended for JSON when +// deciding which field to marshal or unmarshal. If there are +// multiple fields at the same level, and that level is the least +// nested (and would therefore be the nesting level selected by the +// usual Go rules), the following extra rules apply: +// +// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, +// even if there are multiple untagged fields that would otherwise conflict. +// 2) If there is exactly one field (tagged or not according to the first rule), that is selected. +// 3) Otherwise there are multiple fields, and all are ignored; no error occurs. +// +// Handling of anonymous struct fields is new in Go 1.1. +// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of +// an anonymous struct field in both current and earlier versions, give the field +// a JSON tag of "-". +// +// Map values encode as JSON objects. +// The map's key type must be string; the map keys are used as JSON object +// keys, subject to the UTF-8 coercion described for string values above. +// +// Pointer values encode as the value pointed to. +// A nil pointer encodes as the null JSON object. +// +// Interface values encode as the value contained in the interface. +// A nil interface value encodes as the null JSON object. +// +// Channel, complex, and function values cannot be encoded in JSON. +// Attempting to encode such a value causes Marshal to return +// an UnsupportedTypeError. +// +// JSON cannot represent cyclic data structures and Marshal does not +// handle them. Passing cyclic structures to Marshal will result in +// an infinite recursion. +func Marshal(v interface{}) ([]byte, error) { + e := &encodeState{} + err := e.marshal(v) + if err != nil { + return nil, err + } + return e.Bytes(), nil +} + +// MarshalIndent is like Marshal but applies Indent to format the output. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + b, err := Marshal(v) + if err != nil { + return nil, err + } + var buf bytes.Buffer + err = Indent(&buf, b, prefix, indent) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 +// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 +// so that the JSON will be safe to embed inside HTML